@b9g/match-pattern 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -41
- package/package.json +14 -14
- package/src/index.d.ts +164 -0
- package/src/index.js +2039 -0
- package/src/match-pattern.d.ts +0 -43
- package/src/match-pattern.js +0 -183
package/src/match-pattern.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
declare let URLPattern: any;
|
|
2
|
-
type URLPatternInput = URLPatternInit | string;
|
|
3
|
-
interface URLPatternComponentResult {
|
|
4
|
-
input: string;
|
|
5
|
-
groups: Record<string, string | undefined>;
|
|
6
|
-
}
|
|
7
|
-
interface URLPatternResult {
|
|
8
|
-
inputs: URLPatternInput[];
|
|
9
|
-
protocol: URLPatternComponentResult;
|
|
10
|
-
username: URLPatternComponentResult;
|
|
11
|
-
password: URLPatternComponentResult;
|
|
12
|
-
hostname: URLPatternComponentResult;
|
|
13
|
-
port: URLPatternComponentResult;
|
|
14
|
-
pathname: URLPatternComponentResult;
|
|
15
|
-
search: URLPatternComponentResult;
|
|
16
|
-
hash: URLPatternComponentResult;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Enhanced URLPattern result that includes unified params
|
|
20
|
-
*/
|
|
21
|
-
export interface MatchPatternResult extends URLPatternResult {
|
|
22
|
-
params: Record<string, string>;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* MatchPattern extends URLPattern with enhanced routing capabilities:
|
|
26
|
-
* - Order-independent search parameter matching
|
|
27
|
-
* - Non-exhaustive search matching (extra params allowed)
|
|
28
|
-
* - Unified parameter extraction (pathname + search + extras)
|
|
29
|
-
* - Enhanced string pattern parsing with & syntax
|
|
30
|
-
*/
|
|
31
|
-
export declare class MatchPattern extends URLPattern {
|
|
32
|
-
private _originalInput;
|
|
33
|
-
constructor(input: string | URLPatternInit, baseURL?: string);
|
|
34
|
-
/**
|
|
35
|
-
* Enhanced exec that returns unified params object
|
|
36
|
-
*/
|
|
37
|
-
exec(input: string | URL): MatchPatternResult | null;
|
|
38
|
-
/**
|
|
39
|
-
* Enhanced test with order-independent search parameter matching
|
|
40
|
-
*/
|
|
41
|
-
test(input: string | URL): boolean;
|
|
42
|
-
}
|
|
43
|
-
export {};
|
package/src/match-pattern.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/// <reference types="./match-pattern.d.ts" />
|
|
2
|
-
// src/match-pattern.ts
|
|
3
|
-
var URLPattern = globalThis.URLPattern;
|
|
4
|
-
if (!URLPattern) {
|
|
5
|
-
await import("urlpattern-polyfill");
|
|
6
|
-
URLPattern = globalThis.URLPattern;
|
|
7
|
-
}
|
|
8
|
-
var MatchPattern = class extends URLPattern {
|
|
9
|
-
_originalInput;
|
|
10
|
-
constructor(input, baseURL) {
|
|
11
|
-
let processedInput = input;
|
|
12
|
-
if (typeof input === "string") {
|
|
13
|
-
processedInput = parseStringPattern(input);
|
|
14
|
-
}
|
|
15
|
-
if (baseURL !== void 0) {
|
|
16
|
-
super(processedInput, baseURL);
|
|
17
|
-
} else {
|
|
18
|
-
super(processedInput);
|
|
19
|
-
}
|
|
20
|
-
this._originalInput = processedInput;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Enhanced exec that returns unified params object
|
|
24
|
-
*/
|
|
25
|
-
exec(input) {
|
|
26
|
-
if (!this.test(input)) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
const result = super.exec(input);
|
|
30
|
-
if (result) {
|
|
31
|
-
const enhancedResult = {
|
|
32
|
-
...result,
|
|
33
|
-
params: extractUnifiedParams(result, input)
|
|
34
|
-
};
|
|
35
|
-
return enhancedResult;
|
|
36
|
-
}
|
|
37
|
-
return buildCustomResult(this, input);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Enhanced test with order-independent search parameter matching
|
|
41
|
-
*/
|
|
42
|
-
test(input) {
|
|
43
|
-
const url = typeof input === "string" ? new URL(input) : input;
|
|
44
|
-
if (!this.search || this.search === "*") {
|
|
45
|
-
return super.test(input);
|
|
46
|
-
}
|
|
47
|
-
const pathPatternInit = typeof this._originalInput === "string" ? { pathname: this._originalInput } : { ...this._originalInput, search: void 0 };
|
|
48
|
-
const pathPattern = new URLPattern(pathPatternInit);
|
|
49
|
-
if (!pathPattern.test(input)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
return testSearchParameters(this.search, url.searchParams);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
function parseStringPattern(pattern) {
|
|
56
|
-
if (pattern.includes("://")) {
|
|
57
|
-
const ampIndex2 = pattern.indexOf("&");
|
|
58
|
-
if (ampIndex2 === -1) {
|
|
59
|
-
return pattern;
|
|
60
|
-
}
|
|
61
|
-
const urlPart = pattern.slice(0, ampIndex2);
|
|
62
|
-
const search2 = pattern.slice(ampIndex2 + 1);
|
|
63
|
-
try {
|
|
64
|
-
const url = new URL(urlPart.replace(/:(\w+)/g, "placeholder"));
|
|
65
|
-
return {
|
|
66
|
-
protocol: urlPart.split("://")[0],
|
|
67
|
-
hostname: url.hostname,
|
|
68
|
-
pathname: url.pathname.replace(/placeholder/g, ":$1"),
|
|
69
|
-
// Restore params
|
|
70
|
-
search: search2
|
|
71
|
-
};
|
|
72
|
-
} catch {
|
|
73
|
-
return pattern;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const ampIndex = pattern.indexOf("&");
|
|
77
|
-
if (ampIndex === -1) {
|
|
78
|
-
return { pathname: pattern };
|
|
79
|
-
}
|
|
80
|
-
if (ampIndex === 0) {
|
|
81
|
-
return { search: pattern.slice(1) };
|
|
82
|
-
}
|
|
83
|
-
const pathname = pattern.slice(0, ampIndex);
|
|
84
|
-
const search = pattern.slice(ampIndex + 1);
|
|
85
|
-
return { pathname, search };
|
|
86
|
-
}
|
|
87
|
-
function extractUnifiedParams(result, url) {
|
|
88
|
-
const params = {};
|
|
89
|
-
if (result.pathname?.groups) {
|
|
90
|
-
for (const [key, value] of Object.entries(result.pathname.groups)) {
|
|
91
|
-
if (value !== void 0) {
|
|
92
|
-
params[key] = value;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (result.search?.groups) {
|
|
97
|
-
const actualUrl = typeof url === "string" ? new URL(url) : url;
|
|
98
|
-
const searchParams = actualUrl.searchParams;
|
|
99
|
-
for (const [key, value] of searchParams) {
|
|
100
|
-
params[key] = value;
|
|
101
|
-
}
|
|
102
|
-
} else if (typeof url !== "string") {
|
|
103
|
-
const actualUrl = url instanceof URL ? url : new URL(url);
|
|
104
|
-
for (const [key, value] of actualUrl.searchParams) {
|
|
105
|
-
params[key] = value;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return params;
|
|
109
|
-
}
|
|
110
|
-
function buildCustomResult(pattern, input) {
|
|
111
|
-
const url = typeof input === "string" ? new URL(input) : input;
|
|
112
|
-
const result = {
|
|
113
|
-
inputs: [input],
|
|
114
|
-
pathname: { input: url.pathname, groups: {} },
|
|
115
|
-
search: { input: url.search, groups: {} },
|
|
116
|
-
hash: { input: url.hash, groups: {} },
|
|
117
|
-
protocol: { input: url.protocol, groups: {} },
|
|
118
|
-
hostname: { input: url.hostname, groups: {} },
|
|
119
|
-
port: { input: url.port, groups: {} },
|
|
120
|
-
username: { input: url.username, groups: {} },
|
|
121
|
-
password: { input: url.password, groups: {} },
|
|
122
|
-
params: {}
|
|
123
|
-
};
|
|
124
|
-
if (pattern.pathname && pattern.pathname !== "*") {
|
|
125
|
-
const pathPattern = new URLPattern({ pathname: pattern.pathname });
|
|
126
|
-
const pathResult = pathPattern.exec(url);
|
|
127
|
-
if (pathResult?.pathname?.groups) {
|
|
128
|
-
result.pathname.groups = pathResult.pathname.groups;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (pattern.search && pattern.search !== "*") {
|
|
132
|
-
const searchParams = parseSearchPattern(pattern.search);
|
|
133
|
-
const actualParams = url.searchParams;
|
|
134
|
-
for (const [key, paramDef] of searchParams) {
|
|
135
|
-
if (actualParams.has(key)) {
|
|
136
|
-
if (paramDef.type === "named" && paramDef.name) {
|
|
137
|
-
result.search.groups[paramDef.name] = actualParams.get(key);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
result.params = extractUnifiedParams(result, input);
|
|
143
|
-
return result;
|
|
144
|
-
}
|
|
145
|
-
function testSearchParameters(searchPattern, actualParams) {
|
|
146
|
-
const patternParams = parseSearchPattern(searchPattern);
|
|
147
|
-
for (const [key, paramPattern] of patternParams) {
|
|
148
|
-
if (!actualParams.has(key)) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
if (paramPattern.type === "literal") {
|
|
152
|
-
if (actualParams.get(key) !== paramPattern.value) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
function parseSearchPattern(pattern) {
|
|
160
|
-
const params = /* @__PURE__ */ new Map();
|
|
161
|
-
const parts = pattern.split("&");
|
|
162
|
-
for (const part of parts) {
|
|
163
|
-
const [key, value] = part.split("=");
|
|
164
|
-
if (!key || !value)
|
|
165
|
-
continue;
|
|
166
|
-
if (value.startsWith(":")) {
|
|
167
|
-
const isOptional = value.endsWith("?");
|
|
168
|
-
params.set(key, {
|
|
169
|
-
type: "named",
|
|
170
|
-
name: value.slice(1, isOptional ? -1 : void 0),
|
|
171
|
-
optional: isOptional
|
|
172
|
-
});
|
|
173
|
-
} else if (value === "*") {
|
|
174
|
-
params.set(key, { type: "wildcard" });
|
|
175
|
-
} else {
|
|
176
|
-
params.set(key, { type: "literal", value });
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return params;
|
|
180
|
-
}
|
|
181
|
-
export {
|
|
182
|
-
MatchPattern
|
|
183
|
-
};
|