@peter.naydenov/url-pattern 1.0.1 → 1.0.2

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.
@@ -89,6 +89,11 @@ const result = pattern.match ( '/user/john/post/123' )
89
89
  console.log ( result )
90
90
  // Output: { username: 'john', postId: '123' }
91
91
  ```
92
+ ## URL Patterns
93
+
94
+ See [supported URL pattern types with examples](./PATTERNS.md).
95
+
96
+
92
97
 
93
98
  ## API Reference
94
99
 
@@ -124,13 +129,21 @@ Generates a URL string from provided data object.
124
129
 
125
130
  Returns an object with `regex` (compiled RegExp), `segments` (parsed segments array), and `segmentNames` (segment name mappings).
126
131
 
127
- ## Links
128
132
 
133
+
134
+ ## Links
135
+ - [Supported URL patterns with examples](./PATTERNS.md).
129
136
  - [History of changes](CHANGELOG.md)
130
137
  - [TypeScript definitions](types/index.d.ts)
131
138
 
139
+
140
+
132
141
  ## Credits
133
142
 
134
143
  '@peter.naydenov/url-pattern' was created and supported by [Peter Naydenov](https://github.com/PeterNaydenov).
135
144
 
145
+
146
+
147
+ ## License
148
+
136
149
  '@peter.naydenov/url-pattern' is released under the [MIT License](https://github.com/PeterNaydenov/git-url-pattern/blob/main/LICENSE).
@@ -214,7 +214,7 @@ const parsePattern = (pattern, options) => {
214
214
  * @param {UrlPatternOptions} options - Options
215
215
  * @returns {{regex: string, segmentNames: Array<SegmentName>}} Compiled regex and segment names
216
216
  */
217
- const compileRegex = (segments, options) => {
217
+ const compileRegex = (segments, _options) => {
218
218
  let regex = '^';
219
219
  let groupIndex = 0;
220
220
  /** @type {Array<SegmentName>} */
@@ -210,7 +210,7 @@ const parsePattern = (pattern, options) => {
210
210
  * @param {UrlPatternOptions} options - Options
211
211
  * @returns {{regex: string, segmentNames: Array<SegmentName>}} Compiled regex and segment names
212
212
  */
213
- const compileRegex = (segments, options) => {
213
+ const compileRegex = (segments, _options) => {
214
214
  let regex = '^';
215
215
  let groupIndex = 0;
216
216
  /** @type {Array<SegmentName>} */
@@ -1,509 +1 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.urlPattern = {}));
5
- })(this, (function (exports) { 'use strict';
6
-
7
- /**
8
- * @fileoverview URL pattern matching library
9
- * @module url-pattern
10
- */
11
-
12
- /**
13
- * @typedef {Object} UrlPatternOptions
14
- * @property {string} [escapeChar='\\'] - Character used for escaping special characters
15
- * @property {string} [segmentNameStartChar=':'] - Character that starts a named segment
16
- * @property {string} [segmentNameCharset='a-zA-Z0-9'] - Characters allowed in segment names
17
- * @property {string} [segmentValueCharset='a-zA-Z0-9-_~ %'] - Characters allowed in segment values
18
- * @property {string} [optionalSegmentStartChar='('] - Character that starts an optional segment
19
- * @property {string} [optionalSegmentEndChar=')'] - Character that ends an optional segment
20
- * @property {string} [wildcardChar='*'] - Character that denotes a wildcard
21
- */
22
-
23
- /**
24
- * @typedef {Object} ParsedSegment
25
- * @property {string} name - Segment name
26
- * @property {string} type - Segment type ('named' | 'wildcard' | 'literal')
27
- * @property {boolean} [optional=false] - Whether the segment is optional
28
- * @property {string} regex - Compiled regex string
29
- */
30
-
31
- /**
32
- * @typedef {Object} SegmentName
33
- * @property {string} name - Segment name
34
- * @property {number} index - Capture group index
35
- * @property {string} type - Segment type ('named' | 'wildcard')
36
- */
37
-
38
- /**
39
- * @typedef {Object} CompiledPattern
40
- * @property {string} regex - Compiled regex string
41
- * @property {RegExp} regexObj - Compiled regex object
42
- * @property {Array<ParsedSegment>} segments - Parsed segments
43
- * @property {Array<SegmentName>} segmentNames - Segment name mappings
44
- * @property {UrlPatternOptions} options - Options used
45
- * @property {boolean} isRegex - Whether pattern was created from regex
46
- * @property {string} [pattern] - Original pattern string
47
- * @property {Array<string>} [keys] - Keys for regex patterns
48
- */
49
-
50
- /**
51
- * Default options for URL pattern matching
52
- * @type {UrlPatternOptions}
53
- */
54
- const DEFAULT_OPTIONS = {
55
- escapeChar: '\\',
56
- segmentNameStartChar: ':',
57
- segmentNameCharset: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
58
- segmentValueCharset: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_~ %',
59
- optionalSegmentStartChar: '(',
60
- optionalSegmentEndChar: ')',
61
- wildcardChar: '*'
62
- };
63
-
64
- /**
65
- * Escapes special regex characters in a string
66
- * @param {string} str - String to escape
67
- * @returns {string} Escaped string
68
- */
69
- const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
70
-
71
- /**
72
- * Merges default options with user provided options
73
- * @param {UrlPatternOptions} [userOptions={}] - User provided options
74
- * @returns {UrlPatternOptions} Merged options
75
- */
76
- const mergeOptions = (userOptions = {}) => ({
77
- ...DEFAULT_OPTIONS,
78
- ...userOptions
79
- });
80
-
81
- /**
82
- * Finds the position of the next special character in the pattern
83
- * @param {string} pattern - Pattern string
84
- * @param {number} start - Starting position
85
- * @param {UrlPatternOptions} options - Parsing options
86
- * @returns {number} Position of next special character
87
- */
88
- const findNextSpecialChar = (pattern, start, options) => {
89
- const chars = [
90
- options.escapeChar,
91
- options.optionalSegmentStartChar,
92
- options.optionalSegmentEndChar,
93
- options.wildcardChar,
94
- options.segmentNameStartChar
95
- ];
96
-
97
- let minPos = pattern.length;
98
-
99
- for (let i = 0; i < chars.length; i++) {
100
- const char = chars[i];
101
- if (!char) continue;
102
- const pos = pattern.indexOf(char, start);
103
- if (pos !== -1 && pos < minPos) {
104
- minPos = pos;
105
- }
106
- }
107
-
108
- return minPos;
109
- };
110
-
111
- /**
112
- * Parses a pattern string into segments
113
- * @param {string} pattern - Pattern string to parse
114
- * @param {UrlPatternOptions} options - Parsing options
115
- * @returns {Array<ParsedSegment>} Parsed segments
116
- */
117
- const parsePattern = (pattern, options) => {
118
- const segments = [];
119
- let i = 0;
120
- let inOptional = false;
121
-
122
- while (i < pattern.length) {
123
- const char = pattern[i];
124
-
125
- if (char === options.escapeChar && i + 1 < pattern.length) {
126
- segments.push({
127
- type: 'literal',
128
- name: pattern[i + 1],
129
- regex: escapeRegex(pattern[i + 1]),
130
- optional: inOptional
131
- });
132
- i += 2;
133
- continue;
134
- }
135
-
136
- if (char === options.optionalSegmentStartChar) {
137
- inOptional = true;
138
- i++;
139
- continue;
140
- }
141
-
142
- if (char === options.optionalSegmentEndChar) {
143
- inOptional = false;
144
- i++;
145
- continue;
146
- }
147
-
148
- if (char === options.wildcardChar) {
149
- segments.push({
150
- type: 'wildcard',
151
- name: '_',
152
- regex: '.*',
153
- optional: inOptional
154
- });
155
- i++;
156
- continue;
157
- }
158
-
159
- if (char === options.segmentNameStartChar && i + 1 < pattern.length) {
160
- const remaining = pattern.slice(i + 1);
161
- let nameEnd = 0;
162
- const charset = options.segmentNameCharset || '';
163
-
164
- for (let j = 0; j < remaining.length; j++) {
165
- if (!charset.includes(remaining[j])) {
166
- break;
167
- }
168
- nameEnd = j + 1;
169
- }
170
-
171
- const name = remaining.slice(0, nameEnd);
172
-
173
- if (name.length > 0) {
174
- let valueCharset = options.segmentValueCharset || '';
175
- if (valueCharset.includes('-') && valueCharset.indexOf('-') > 0 && valueCharset.indexOf('-') < valueCharset.length - 1) {
176
- valueCharset = valueCharset.replace(/-/g, '');
177
- valueCharset += '-';
178
- }
179
- const escapedValueCharset = valueCharset.replace(/\]/g, '\\]');
180
- const valueRegex = `([${escapedValueCharset}]+)`;
181
-
182
- segments.push({
183
- type: 'named',
184
- name,
185
- regex: valueRegex,
186
- optional: inOptional
187
- });
188
- i += 1 + nameEnd;
189
- continue;
190
- }
191
- }
192
-
193
- const literalEnd = findNextSpecialChar(pattern, i, options);
194
-
195
- if (literalEnd > i) {
196
- const literal = pattern.slice(i, literalEnd);
197
- segments.push({
198
- type: 'literal',
199
- name: literal,
200
- regex: escapeRegex(literal),
201
- optional: inOptional
202
- });
203
- i = literalEnd;
204
- continue;
205
- }
206
-
207
- i++;
208
- }
209
-
210
- return segments;
211
- };
212
-
213
- /**
214
- * Compiles segments into a regex pattern
215
- * @param {Array<ParsedSegment>} segments - Parsed segments
216
- * @param {UrlPatternOptions} options - Options
217
- * @returns {{regex: string, segmentNames: Array<SegmentName>}} Compiled regex and segment names
218
- */
219
- const compileRegex = (segments, options) => {
220
- let regex = '^';
221
- let groupIndex = 0;
222
- /** @type {Array<SegmentName>} */
223
- const segmentNames = [];
224
- let i = 0;
225
-
226
- while (i < segments.length) {
227
- const segment = segments[i];
228
-
229
- if (segment.optional) {
230
- let optionalPart = '';
231
- let j = i;
232
-
233
- while (j < segments.length && segments[j].optional) {
234
- const seg = segments[j];
235
-
236
- if (seg.type === 'wildcard') {
237
- optionalPart += '(.*)';
238
- segmentNames.push({ name: '_', index: groupIndex, type: 'wildcard' });
239
- groupIndex++;
240
- } else if (seg.type === 'named') {
241
- optionalPart += seg.regex;
242
- segmentNames.push({ name: seg.name, index: groupIndex, type: 'named' });
243
- groupIndex++;
244
- } else {
245
- optionalPart += seg.regex;
246
- }
247
-
248
- j++;
249
- }
250
-
251
- regex += `(?:${optionalPart})?`;
252
- i = j;
253
- continue;
254
- }
255
-
256
- if (segment.type === 'wildcard') {
257
- regex += '(.*)';
258
- segmentNames.push({ name: '_', index: groupIndex, type: 'wildcard' });
259
- groupIndex++;
260
- } else if (segment.type === 'named') {
261
- regex += segment.regex;
262
- segmentNames.push({ name: segment.name, index: groupIndex, type: 'named' });
263
- groupIndex++;
264
- } else {
265
- regex += segment.regex;
266
- }
267
-
268
- i++;
269
- }
270
-
271
- regex += '$';
272
-
273
- return { regex, segmentNames };
274
- };
275
-
276
- /**
277
- * Creates a compiled pattern from a string
278
- * @param {string} pattern - Pattern string
279
- * @param {UrlPatternOptions} [options={}] - Options
280
- * @returns {CompiledPattern} Compiled pattern
281
- */
282
- const makePattern = (pattern, options = {}) => {
283
- const mergedOptions = mergeOptions(options);
284
- const segments = parsePattern(pattern, mergedOptions);
285
- const { regex, segmentNames } = compileRegex(segments);
286
-
287
- return {
288
- regex,
289
- regexObj: new RegExp(regex),
290
- segments,
291
- segmentNames,
292
- options: mergedOptions,
293
- isRegex: false,
294
- pattern
295
- };
296
- };
297
-
298
- /**
299
- * Creates a compiled pattern from a regex
300
- * @param {RegExp} regex - Regex pattern
301
- * @param {Array<string>} [keys=[]] - Array of key names for captured groups
302
- * @returns {CompiledPattern} Compiled pattern
303
- */
304
- const makePatternFromRegex = (regex, keys = []) => {
305
- return {
306
- regex: regex.source,
307
- regexObj: regex,
308
- segments: [],
309
- segmentNames: keys.map((name, index) => ({ name, index, type: 'named' })),
310
- options: DEFAULT_OPTIONS,
311
- isRegex: true,
312
- keys
313
- };
314
- };
315
-
316
- /**
317
- * Matches a string against a compiled pattern
318
- * @param {CompiledPattern} compiled - Compiled pattern
319
- * @param {string} str - String to match
320
- * @returns {Object|null} Extracted values or null if no match
321
- */
322
- const match = (compiled, str) => {
323
- const matchResult = compiled.regexObj.exec(str);
324
-
325
- if (!matchResult) {
326
- return null;
327
- }
328
-
329
- if (compiled.isRegex) {
330
- if (compiled.keys && compiled.keys.length > 0) {
331
- const result = {};
332
- compiled.keys.forEach((key, index) => {
333
- const val = matchResult[index + 1];
334
- result[key] = val !== undefined ? val : null;
335
- });
336
- return result;
337
- }
338
- return matchResult.slice(1);
339
- }
340
-
341
- const result = {};
342
- const usedNames = new Set();
343
-
344
- for (let i = 0; i < compiled.segmentNames.length; i++) {
345
- const segInfo = compiled.segmentNames[i];
346
- const value = matchResult[segInfo.index + 1] || '';
347
-
348
- if (usedNames.has(segInfo.name)) {
349
- if (!Array.isArray(result[segInfo.name])) {
350
- result[segInfo.name] = [result[segInfo.name]];
351
- }
352
- result[segInfo.name].push(value);
353
- } else {
354
- usedNames.add(segInfo.name);
355
- result[segInfo.name] = value;
356
- }
357
- }
358
-
359
- for (const key in result) {
360
- if (result[key] === '') {
361
- delete result[key];
362
- }
363
- }
364
-
365
- return result;
366
- };
367
-
368
- /**
369
- * Stringifies a pattern with given values
370
- * @param {CompiledPattern} compiled - Compiled pattern
371
- * @param {Object} [values={}] - Values to stringify
372
- * @returns {string} Generated string
373
- * @throws {Error} If required values are missing
374
- */
375
- const stringify = (compiled, values = {}) => {
376
- if (compiled.isRegex) {
377
- throw new Error('Cannot stringify a pattern created from regex');
378
- }
379
-
380
- let result = '';
381
- let i = 0;
382
-
383
- while (i < compiled.segments.length) {
384
- const segment = compiled.segments[i];
385
-
386
- if (segment.optional) {
387
- let optionalPart = '';
388
- let j = i;
389
-
390
- while (j < compiled.segments.length && compiled.segments[j].optional) {
391
- const seg = compiled.segments[j];
392
-
393
- if (seg.type === 'literal') {
394
- optionalPart += seg.name;
395
- } else if (seg.type === 'named') {
396
- const val = values[seg.name];
397
- if (val !== undefined && val !== null && val !== '') {
398
- optionalPart += Array.isArray(val) ? val.join('/') : val;
399
- } else {
400
- optionalPart = '';
401
- break;
402
- }
403
- } else if (seg.type === 'wildcard') {
404
- const val = values._;
405
- if (val !== undefined && val !== null && val !== '') {
406
- optionalPart += Array.isArray(val) ? val.join('/') : val;
407
- } else {
408
- optionalPart = '';
409
- break;
410
- }
411
- }
412
-
413
- j++;
414
- }
415
-
416
- if (optionalPart !== '') {
417
- result += optionalPart;
418
- }
419
-
420
- if (i === j) {
421
- i++;
422
- } else {
423
- i = j;
424
- }
425
- continue;
426
- }
427
-
428
- if (segment.type === 'literal') {
429
- result += segment.name;
430
- } else if (segment.type === 'named') {
431
- const value = values[segment.name];
432
- if (value === undefined || value === null || value === '') {
433
- throw new Error(`Missing required value for segment: ${segment.name}`);
434
- }
435
- result += Array.isArray(value) ? value.join('/') : value;
436
- } else if (segment.type === 'wildcard') {
437
- const value = values._;
438
- if (value === undefined || value === null || value === '') {
439
- throw new Error('Missing required wildcard value');
440
- }
441
- result += Array.isArray(value) ? value.join('/') : value;
442
- }
443
-
444
- i++;
445
- }
446
-
447
- return result;
448
- };
449
-
450
- /**
451
- * UrlPattern class for matching and generating URLs
452
- */
453
- class UrlPattern {
454
- /**
455
- * @param {string|RegExp} pattern - Pattern string or regex
456
- * @param {UrlPatternOptions|Array<string>} [options={}] - Options or keys (for regex)
457
- */
458
- constructor(pattern, options = {}) {
459
- if (pattern instanceof RegExp) {
460
- const keys = Array.isArray(options) ? options : [];
461
- /** @type {CompiledPattern} */
462
- this.compiled = makePatternFromRegex(pattern, keys);
463
- } else {
464
- /** @type {CompiledPattern} */
465
- this.compiled = makePattern(pattern, /** @type {UrlPatternOptions} */ (options));
466
- }
467
- }
468
-
469
- /**
470
- * Match a string against the pattern
471
- * @param {string} str - String to match
472
- * @returns {Object|null} Extracted values or null if no match
473
- */
474
- match(str) {
475
- return match(this.compiled, str);
476
- }
477
-
478
- /**
479
- * Generate a string from the pattern
480
- * @param {Object} [values={}] - Values to stringify
481
- * @returns {string} Generated string
482
- */
483
- stringify(values) {
484
- return stringify(this.compiled, values);
485
- }
486
- }
487
-
488
- /**
489
- * Creates a new UrlPattern instance (functional API)
490
- * @param {string|RegExp} pattern - Pattern string or regex
491
- * @param {UrlPatternOptions|Array<string>} [options={}] - Options or keys
492
- * @returns {UrlPattern} UrlPattern instance
493
- */
494
- const urlPattern = (pattern, options = {}) => {
495
- return new UrlPattern(pattern, options);
496
- };
497
-
498
- exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
499
- exports.UrlPattern = UrlPattern;
500
- exports.default = UrlPattern;
501
- exports.makePattern = makePattern;
502
- exports.makePatternFromRegex = makePatternFromRegex;
503
- exports.match = match;
504
- exports.stringify = stringify;
505
- exports.urlPattern = urlPattern;
506
-
507
- Object.defineProperty(exports, '__esModule', { value: true });
508
-
509
- }));
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).urlPattern={})}(this,function(e){"use strict";const n={escapeChar:"\\",segmentNameStartChar:":",segmentNameCharset:"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",segmentValueCharset:"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_~ %",optionalSegmentStartChar:"(",optionalSegmentEndChar:")",wildcardChar:"*"},t=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=(e,n,t)=>{const r=[t.escapeChar,t.optionalSegmentStartChar,t.optionalSegmentEndChar,t.wildcardChar,t.segmentNameStartChar];let a=e.length;for(let t=0;t<r.length;t++){const s=r[t];if(!s)continue;const i=e.indexOf(s,n);-1!==i&&i<a&&(a=i)}return a},a=(e,a={})=>{const s=((e={})=>({...n,...e}))(a),i=((e,n)=>{const a=[];let s=0,i=!1;for(;s<e.length;){const o=e[s];if(o===n.escapeChar&&s+1<e.length){a.push({type:"literal",name:e[s+1],regex:t(e[s+1]),optional:i}),s+=2;continue}if(o===n.optionalSegmentStartChar){i=!0,s++;continue}if(o===n.optionalSegmentEndChar){i=!1,s++;continue}if(o===n.wildcardChar){a.push({type:"wildcard",name:"_",regex:".*",optional:i}),s++;continue}if(o===n.segmentNameStartChar&&s+1<e.length){const t=e.slice(s+1);let r=0;const o=n.segmentNameCharset||"";for(let e=0;e<t.length&&o.includes(t[e]);e++)r=e+1;const l=t.slice(0,r);if(l.length>0){let e=n.segmentValueCharset||"";e.includes("-")&&e.indexOf("-")>0&&e.indexOf("-")<e.length-1&&(e=e.replace(/-/g,""),e+="-");const t=`([${e.replace(/\]/g,"\\]")}]+)`;a.push({type:"named",name:l,regex:t,optional:i}),s+=1+r;continue}}const l=r(e,s,n);if(l>s){const n=e.slice(s,l);a.push({type:"literal",name:n,regex:t(n),optional:i}),s=l;continue}s++}return a})(e,s),{regex:o,segmentNames:l}=(e=>{let n="^",t=0;const r=[];let a=0;for(;a<e.length;){const s=e[a];if(s.optional){let s="",i=a;for(;i<e.length&&e[i].optional;){const n=e[i];"wildcard"===n.type?(s+="(.*)",r.push({name:"_",index:t,type:"wildcard"}),t++):"named"===n.type?(s+=n.regex,r.push({name:n.name,index:t,type:"named"}),t++):s+=n.regex,i++}n+=`(?:${s})?`,a=i;continue}"wildcard"===s.type?(n+="(.*)",r.push({name:"_",index:t,type:"wildcard"}),t++):"named"===s.type?(n+=s.regex,r.push({name:s.name,index:t,type:"named"}),t++):n+=s.regex,a++}return n+="$",{regex:n,segmentNames:r}})(i);return{regex:o,regexObj:new RegExp(o),segments:i,segmentNames:l,options:s,isRegex:!1,pattern:e}},s=(e,t=[])=>({regex:e.source,regexObj:e,segments:[],segmentNames:t.map((e,n)=>({name:e,index:n,type:"named"})),options:n,isRegex:!0,keys:t}),i=(e,n)=>{const t=e.regexObj.exec(n);if(!t)return null;if(e.isRegex){if(e.keys&&e.keys.length>0){const n={};return e.keys.forEach((e,r)=>{const a=t[r+1];n[e]=void 0!==a?a:null}),n}return t.slice(1)}const r={},a=new Set;for(let n=0;n<e.segmentNames.length;n++){const s=e.segmentNames[n],i=t[s.index+1]||"";a.has(s.name)?(Array.isArray(r[s.name])||(r[s.name]=[r[s.name]]),r[s.name].push(i)):(a.add(s.name),r[s.name]=i)}for(const e in r)""===r[e]&&delete r[e];return r},o=(e,n={})=>{if(e.isRegex)throw new Error("Cannot stringify a pattern created from regex");let t="",r=0;for(;r<e.segments.length;){const a=e.segments[r];if(a.optional){let a="",s=r;for(;s<e.segments.length&&e.segments[s].optional;){const t=e.segments[s];if("literal"===t.type)a+=t.name;else if("named"===t.type){const e=n[t.name];if(null==e||""===e){a="";break}a+=Array.isArray(e)?e.join("/"):e}else if("wildcard"===t.type){const e=n._;if(null==e||""===e){a="";break}a+=Array.isArray(e)?e.join("/"):e}s++}""!==a&&(t+=a),r===s?r++:r=s;continue}if("literal"===a.type)t+=a.name;else if("named"===a.type){const e=n[a.name];if(null==e||""===e)throw new Error(`Missing required value for segment: ${a.name}`);t+=Array.isArray(e)?e.join("/"):e}else if("wildcard"===a.type){const e=n._;if(null==e||""===e)throw new Error("Missing required wildcard value");t+=Array.isArray(e)?e.join("/"):e}r++}return t};class l{constructor(e,n={}){if(e instanceof RegExp){const t=Array.isArray(n)?n:[];this.compiled=s(e,t)}else this.compiled=a(e,n)}match(e){return i(this.compiled,e)}stringify(e){return o(this.compiled,e)}}e.DEFAULT_OPTIONS=n,e.UrlPattern=l,e.default=l,e.makePattern=a,e.makePatternFromRegex=s,e.match=i,e.stringify=o,e.urlPattern=(e,n={})=>new l(e,n),Object.defineProperty(e,"__esModule",{value:!0})});
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@peter.naydenov/url-pattern",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Matching patterns for urls and other strings. Turn strings into data or data into strings.",
5
5
  "type": "module",
6
6
  "main": "./src/main.js",
7
7
  "module": "./dist/url-pattern.es.js",
8
- "types": "./types/index.d.ts",
8
+ "types": "./types/main.d.ts",
9
9
  "files": [
10
10
  "dist",
11
11
  "types",
@@ -28,7 +28,7 @@
28
28
  "test": "vitest run",
29
29
  "test:watch": "vitest",
30
30
  "cover": "vitest run --coverage",
31
- "lint": "eslint src --ext .js",
31
+ "lint": "oxlint src",
32
32
  "prepublishOnly": "npm run build"
33
33
  },
34
34
  "keywords": [
@@ -45,11 +45,14 @@
45
45
  "url": "https://github.com/PeterNaydenov/url-pattern"
46
46
  },
47
47
  "devDependencies": {
48
- "@rollup/plugin-terser": "^0.4.4",
49
- "@vitest/coverage-v8": "^4.1.5",
50
- "eslint": "^10.3.0",
51
- "rollup": "^4.9.6",
48
+ "@rollup/plugin-terser": "^1.0.0",
49
+ "@vitest/coverage-v8": "^4.1.7",
50
+ "oxlint": "^1.68.0",
51
+ "rollup": "^4.61.1",
52
52
  "typescript": "^6.0.3",
53
- "vitest": "^4.1.5"
53
+ "vitest": "^4.1.7"
54
+ },
55
+ "allowScripts": {
56
+ "fsevents@2.3.3": true
54
57
  }
55
58
  }
package/src/main.js CHANGED
@@ -210,7 +210,7 @@ const parsePattern = (pattern, options) => {
210
210
  * @param {UrlPatternOptions} options - Options
211
211
  * @returns {{regex: string, segmentNames: Array<SegmentName>}} Compiled regex and segment names
212
212
  */
213
- const compileRegex = (segments, options) => {
213
+ const compileRegex = (segments, _options) => {
214
214
  let regex = '^';
215
215
  let groupIndex = 0;
216
216
  /** @type {Array<SegmentName>} */