Skip to content

Commit

Permalink
Merge pull request #3113 from RoelVB/fix/aliased-parameters-v3-retry
Browse files Browse the repository at this point in the history
Improved aliased parameter parsing (v3)
  • Loading branch information
bcameron1231 authored Sep 16, 2024
2 parents 208cfa9 + ce0ca25 commit 0255cce
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
14 changes: 4 additions & 10 deletions packages/sp/spqueryable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,11 @@ export class _SPQueryable<GetType = any> extends Queryable<GetType> {

const aliasedParams = new URLSearchParams(this.query);

// this regex is designed to locate aliased parameters within url paths. These may have the form:
// /something(!@p1::value)
// /something(!@p1::value, param=value)
// /something(param=value,!@p1::value)
// /something(param=value,!@p1::value,param=value)
// /something(param=!@p1::value)
// there could be spaces or not around the boundaries
let url = this.toUrl().replace(/([( *| *, *| *= *])'!(@.*?)::(.*?)'([ *)| *, *])/ig, (match, frontBoundary, labelName, value, endBoundary) => {
// this regex is designed to locate aliased parameters within url paths
let url = this.toUrl().replace(/'!(@.+?)::((?:[^']|'')+)'/ig, (match, labelName, value) => {
this.log(`Rewriting aliased parameter from match ${match} to label: ${labelName} value: ${value}`, 0);
aliasedParams.set(labelName,`'${value}'`);
return `${frontBoundary}${labelName}${endBoundary}`;
aliasedParams.set(labelName, `'${value}'`);
return labelName;
});

const query = aliasedParams.toString();
Expand Down
45 changes: 45 additions & 0 deletions test/sp/alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import "@pnp/sp/files/web";
import "@pnp/sp/files/folder";
import "@pnp/sp/lists/web";
import { combine } from "@pnp/core";
import { SPQueryable } from "@pnp/sp";
import { URL } from 'url'; // To prevent typing error in the "parameter parsing" test

Check failure on line 10 in test/sp/alias.ts

View workflow job for this annotation

GitHub Actions / run_push_tests

Strings must use doublequote

describe("Alias Parameters", function () {

Expand All @@ -28,6 +30,49 @@ describe("Alias Parameters", function () {
await ler.list.rootFolder.files.addUsingPath("text.txt", "Some file content!");
});

it('Parameter parsing', function() {

Check failure on line 33 in test/sp/alias.ts

View workflow job for this annotation

GitHub Actions / run_push_tests

Strings must use doublequote
/** Values to test */
const values = [
"value",
"value's",
"value with space",
"value with space' and apostrophe",
"ending with apostrophe'",
"'staring with apostrophe",
"'staring and ending with apostrophe'",
"with,' comma",
];
/** Aliased parameters to test */
const tests = values.reduce<Record<string, Record<string, string>>>((obj, value)=>{
// Escape apostrophe in value
value = value.replace(/'/g, "''");

obj[`something('!@p1::${value}')`] = {"@p1": `'${value}'`};
obj[`something('!@p1::${value}','!@p2::${value}2')`] = {"@p1": `'${value}'`, "@p2": `'${value}2'`};
obj[`something('!@p1::${value}', param=value)`] = {"@p1": `'${value}'`};
obj[`something('!@p1::${value}', param=value, '!@p2::${value}2')`] = {"@p1": `'${value}'`, "@p2": `'${value}2'`};
obj[`something(param=value,'!@p1::${value}')`] = {"@p1": `'${value}'`};
obj[`something(param=value,'!@p1::${value}','!@p2::${value}2')`] = {"@p1": `'${value}'`, "@p2": `'${value}2'`};
obj[`something(param=value,'!@p1::${value}',param=value)`] = {"@p1": `'${value}'`};
obj[`something(param=value,'!@p1::${value}',param=value,'!@p2::${value}2')`] = {"@p1": `'${value}'`, "@p2": `'${value}2'`};
obj[`something(param='!@p1::${value}')`] = {"@p1": `'${value}'`};
obj[`something(param='!@p1::${value}',param2='!@p2::${value}2')`] = {"@p1": `'${value}'`, "@p2": `'${value}2'`};
return obj;
}, {});

// Test all aliased parameters
for(const [alias, params] of Object.entries(tests)) {
const requestUrl = SPQueryable(this.pnp.sp.web, alias).toRequestUrl();
const searchParams = Object.fromEntries(new URL(requestUrl).searchParams.entries());

// eslint-disable-next-line guard-for-in
for(const param in params) {
expect(searchParams, `Failed to parse "${alias}"`).to.have.property(param);
expect(searchParams[param], `Failed to parse "${alias}"`).to.equal(params[param]);
}
}
});

it("Folders", function () {

return expect(this.pnp.sp.web.getFolderByServerRelativePath(`!@p1::/${combine(webRelativeUrl, "AliasTestLib/MyTestFolder")}`)()).to.eventually.be.fulfilled;
Expand Down

0 comments on commit 0255cce

Please sign in to comment.