Skip to content

Commit

Permalink
fix: refactor path templates to simplify regexes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-fenster committed Aug 6, 2021
1 parent 5e92510 commit ca7a6a1
Showing 1 changed file with 44 additions and 46 deletions.
90 changes: 44 additions & 46 deletions src/pathTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,36 @@ export class PathTemplate {
);
} else {
let segment = this.segments[index];
const variable = segment.match(/(?<={)[$0-9a-zA-Z_]+(?==.*})/g) || [];
const matches = segment.match(/\{[$0-9a-zA-Z_]+=.*?\}/g);
if (!matches) {
throw new Error(
`Error processing path template segment ${segment}`
);
}
console.log(matches);
const variables = matches.map(str =>
str.replace(/^\{/, '').replace(/=.*/, '')
);
console.log(variables);
if (segment.includes('**')) {
bindings[variable[0]] = pathSegments[0] + '/' + pathSegments[1];
bindings[variables[0]] = pathSegments[0] + '/' + pathSegments[1];
pathSegments = pathSegments.slice(2);
} else {
// atomic resource
if (variable.length === 1) {
bindings[variable[0]] = pathSegments[0];
if (variables.length === 1) {
bindings[variables[0]] = pathSegments[0];
} else {
// non-slash resource
// segment: {blurb_id=*}.{legacy_user=*} to match pathSegments: ['bar.user2']
// split the match pathSegments[0] -> value: ['bar', 'user2']
// compare the length of two arrays, and compare array items
const value = pathSegments[0].split(/[-_.~]/);
if (value.length !== variable!.length) {
if (value.length !== variables.length) {
throw new Error(
`segment ${segment} does not match ${pathSegments[0]}`
);
}
for (const v of variable) {
for (const v of variables) {
bindings[v] = value[0];
segment = segment.replace(`{${v}=*}`, `${value[0]}`);
value.shift();
Expand Down Expand Up @@ -173,6 +183,7 @@ export class PathTemplate {
let index = 0;
let wildCardCount = 0;
const segments: string[] = [];
let matches: RegExpMatchArray | null;
pathSegments.forEach(segment => {
// * or ** -> segments.push('{$0=*}');
// -> bindings['$0'] = '*'
Expand All @@ -181,52 +192,39 @@ export class PathTemplate {
segments.push(`{$${index}=${segment}}`);
index = index + 1;
if (segment === '**') {
wildCardCount = wildCardCount + 1;
++wildCardCount;
}
}
// {project}~{location} -> {project=*}~{location=*}
else if (
segment.match(
/(?<={)[0-9a-zA-Z-.~_]+(?:}[-._~]?{)[0-9a-zA-Z-.~_]+(?=})/
)
) {
// [project, location]
const variable = segment.match(/(?<=\{).*?(?=(?:=.*?)?\})/g) || [];
for (const v of variable) {
this.bindings[v] = '*';
segment = segment.replace(v, v + '=*');
} else if ((matches = segment.match(/\{[0-9a-zA-Z-.~_]+(?:=.*?)?\}/g))) {
for (const subsegment of matches) {
const pairMatch = subsegment.match(
/^\{([0-9a-zA-Z-.~_]+)(?:=(.*?))?\}$/
);
if (!pairMatch) {
throw new Error(
`Cannot process path template segment ${subsegment}`
);
}
const key = pairMatch[1];
let value = pairMatch[2];
if (!value) {
value = '*';
segment = segment.replace(key, key + '=*');
this.bindings[key] = value;
} else if (value === '*') {
this.bindings[key] = value;
} else if (value === '**') {
++wildCardCount;
this.bindings[key] = value;
}
}
segments.push(segment);
}
// {project} / {project=*} -> segments.push('{project=*}');
// -> bindings['project'] = '*'
else if (segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*)?})/)) {
const variable = segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*)?})/);
this.bindings[variable![0]] = '*';
segments.push(`{${variable![0]}=*}`);
}
// {project=**} -> segments.push('{project=**}');
// -> bindings['project'] = '**'
else if (segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*\*)})/)) {
const variable = segment.match(/(?<={)[0-9a-zA-Z-.~_]+(?=(=\*\*)})/);
this.bindings[variable![0]] = '**';
segments.push(`{${variable![0]}=**}`);
wildCardCount = wildCardCount + 1;
}
// {hello=/what} -> segments.push('{hello=/what}');
// -> no binding in this case
else if (segment.match(/(?<={)[0-9a-zA-Z-.~_]+=[^*]+(?=})/)) {
segments.push(segment);
}
// helloazAZ09-.~_what -> segments.push('helloazAZ09-.~_what');
// -> no binding in this case
else if (segment.match(/[0-9a-zA-Z-.~_]+/)) {
} else if (segment.match(/[0-9a-zA-Z-.~_]+/)) {
segments.push(segment);
}
if (wildCardCount > 1) {
throw new TypeError('Can not have more than one wildcard.');
}
});
if (wildCardCount > 1) {
throw new TypeError('Can not have more than one wildcard.');
}
return segments;
}
}
Expand Down

0 comments on commit ca7a6a1

Please sign in to comment.