Add method to determine if a URI is a template or not
This commit is contained in:
parent
dc77d9cf47
commit
1e040e9932
2 changed files with 41 additions and 5 deletions
|
|
@ -1,6 +1,23 @@
|
|||
import { UriTemplate } from "./uriTemplate.js";
|
||||
|
||||
describe("UriTemplate", () => {
|
||||
describe("isTemplate", () => {
|
||||
it("should return true for strings containing template expressions", () => {
|
||||
expect(UriTemplate.isTemplate("{foo}")).toBe(true);
|
||||
expect(UriTemplate.isTemplate("/users/{id}")).toBe(true);
|
||||
expect(UriTemplate.isTemplate("http://example.com/{path}/{file}")).toBe(true);
|
||||
expect(UriTemplate.isTemplate("/search{?q,limit}")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for strings without template expressions", () => {
|
||||
expect(UriTemplate.isTemplate("")).toBe(false);
|
||||
expect(UriTemplate.isTemplate("plain string")).toBe(false);
|
||||
expect(UriTemplate.isTemplate("http://example.com/foo/bar")).toBe(false);
|
||||
expect(UriTemplate.isTemplate("{}")).toBe(false); // Empty braces don't count
|
||||
expect(UriTemplate.isTemplate("{ }")).toBe(false); // Just whitespace doesn't count
|
||||
});
|
||||
});
|
||||
|
||||
describe("simple string expansion", () => {
|
||||
it("should expand simple string variables", () => {
|
||||
const template = new UriTemplate("http://example.com/users/{username}");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Claude-authored implementation of RFC 6570 URI Templates
|
||||
|
||||
type Variables = Record<string, string | string[]>;
|
||||
export type Variables = Record<string, string | string[]>;
|
||||
|
||||
const MAX_TEMPLATE_LENGTH = 1000000; // 1MB
|
||||
const MAX_VARIABLE_LENGTH = 1000000; // 1MB
|
||||
|
|
@ -8,7 +8,22 @@ const MAX_TEMPLATE_EXPRESSIONS = 10000;
|
|||
const MAX_REGEX_LENGTH = 1000000; // 1MB
|
||||
|
||||
export class UriTemplate {
|
||||
private static validateLength(str: string, max: number, context: string): void {
|
||||
/**
|
||||
* Returns true if the given string contains any URI template expressions.
|
||||
* A template expression is a sequence of characters enclosed in curly braces,
|
||||
* like {foo} or {?bar}.
|
||||
*/
|
||||
static isTemplate(str: string): boolean {
|
||||
// Look for any sequence of characters between curly braces
|
||||
// that isn't just whitespace
|
||||
return /\{[^}\s]+\}/.test(str);
|
||||
}
|
||||
|
||||
private static validateLength(
|
||||
str: string,
|
||||
max: number,
|
||||
context: string,
|
||||
): void {
|
||||
if (str.length > max) {
|
||||
throw new Error(
|
||||
`${context} exceeds maximum length of ${max} characters (got ${str.length})`,
|
||||
|
|
@ -60,7 +75,7 @@ export class UriTemplate {
|
|||
const exploded = expr.includes("*");
|
||||
const names = this.getNames(expr);
|
||||
const name = names[0];
|
||||
|
||||
|
||||
// Validate variable name length
|
||||
for (const name of names) {
|
||||
UriTemplate.validateLength(
|
||||
|
|
@ -263,7 +278,11 @@ export class UriTemplate {
|
|||
}
|
||||
|
||||
pattern += "$";
|
||||
UriTemplate.validateLength(pattern, MAX_REGEX_LENGTH, "Generated regex pattern");
|
||||
UriTemplate.validateLength(
|
||||
pattern,
|
||||
MAX_REGEX_LENGTH,
|
||||
"Generated regex pattern",
|
||||
);
|
||||
const regex = new RegExp(pattern);
|
||||
const match = uri.match(regex);
|
||||
|
||||
|
|
@ -284,4 +303,4 @@ export class UriTemplate {
|
|||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue