full site update
This commit is contained in:
2
node_modules/regex/LICENSE
generated
vendored
2
node_modules/regex/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Steven Levithan
|
||||
Copyright (c) 2025 Steven Levithan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
29
node_modules/regex/README.md
generated
vendored
29
node_modules/regex/README.md
generated
vendored
@@ -64,6 +64,7 @@ With the Regex+ library, JavaScript steps up as one of the best regex flavors al
|
||||
- Atomic groups and possessive quantifiers can dramatically improve performance and prevent ReDoS.
|
||||
- Subroutines and definition groups enable powerful composition, improving readability and maintainability.
|
||||
- Recursive matching via an official plugin.
|
||||
- Custom syntax plugins supported.
|
||||
|
||||
**Context-aware and safe interpolation** of regexes, strings, and partial patterns.
|
||||
|
||||
@@ -148,7 +149,10 @@ regex`^ (?<first>.) ${double} ${double} $`;
|
||||
// → /^(?<first>.)(.)\2(.)\3$/v
|
||||
```
|
||||
|
||||
See also this example of using a subroutine definition group to [refactor an IP address regex for readability](https://x.com/slevithan/status/1828112006353953055).
|
||||
See also the following examples of using subroutine definition groups to refactor regexes for readability and maintainability:
|
||||
|
||||
- [IP address regex](https://x.com/slevithan/status/1828112006353953055).
|
||||
- [Date time regex](https://bsky.app/profile/slev.life/post/3lgc6ullyvk2x).
|
||||
|
||||
## ❓ Context
|
||||
|
||||
@@ -318,7 +322,7 @@ Above, the `{0}` quantifier at the end of the `(?<byte>…)` group allows *defin
|
||||
This next regex matches a record with multiple date fields, and captures each value:
|
||||
|
||||
```js
|
||||
const record = regex`
|
||||
const re = regex`
|
||||
^ Admitted:\ (?<admitted> \g<date>) \n
|
||||
Released:\ (?<released> \g<date>) $
|
||||
|
||||
@@ -359,9 +363,8 @@ const re = regex`
|
||||
(?<day> \d{2})
|
||||
)
|
||||
`;
|
||||
|
||||
const record = 'Admitted: 2024-01-01\nReleased: 2024-01-03';
|
||||
const match = record.match(re);
|
||||
const match = re.exec(record);
|
||||
console.log(match.groups);
|
||||
/* → {
|
||||
admitted: '2024-01-01',
|
||||
@@ -470,7 +473,7 @@ regex`\b(ab|cd)\b`
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Flag <kbd>n</kbd> is based on .NET, C++, Oniguruma, PCRE, Perl, and XRegExp. It's not always specified by a flag, but where it can be (.NET, PCRE, Perl, XRegExp) it's always <kbd>n</kbd>. The option is variously called *explicit capture*, *no auto capture*, *don't capture group*, or *nosubs*. In Regex+, flag <kbd>n</kbd> also prevents using numbered backreferences to refer to named groups, which follows the behavior of C++ and the default handling of Oniguruma and Ruby. Referring to named groups by number is a footgun, and the way that named groups are numbered is inconsistent across regex flavors.
|
||||
> Flag <kbd>n</kbd> is based on .NET, C++, Oniguruma, PCRE, Perl, and XRegExp. Most of these share the flag letter <kbd>n</kbd>, but the option is variously called *explicit capture*, *no auto capture*, *don't capture group*, or *nosubs*. In Regex+, flag <kbd>n</kbd> also prevents using numbered backreferences to named groups, which follows the behavior of C++ and the default handling of Oniguruma and Ruby. Referring to named groups by number is a footgun, and the way that named groups are numbered is inconsistent across regex flavors.
|
||||
|
||||
## 🧩 Interpolation
|
||||
|
||||
@@ -737,13 +740,13 @@ regex({
|
||||
|
||||
**`flags`** — For providing flags when using an options object.
|
||||
|
||||
**`subclass`** — When `true`, the resulting regex is constructed using a `RegExp` subclass that avoids edge case issues with numbered backreferences. Without subclassing, submatches referenced *by number* from outside of the regex (e.g. in replacement strings) might reference the wrong values, because `regex`'s emulation of extended syntax (including atomic groups and subroutines) can add unnamed captures to generated regex source that might affect group numbering.
|
||||
**`subclass`** — When `true`, the resulting regex is constructed using a `RegExp` subclass that avoids edge case issues with numbered backreferences. Without subclassing, submatches referenced *by number* from outside of the regex (e.g. in replacement strings) might reference the wrong values, because `regex`'s emulation of extended syntax might add unnamed captures to generated regex source that can affect group numbering.
|
||||
|
||||
Context: `regex`'s implicit flag <kbd>n</kbd> (*named capture only* mode) means that all captures have names, so normally there's no need to reference submatches by number. In fact, flag <kbd>n</kbd> *prevents* you from doing so within the regex. And even in edge cases (such as when interpolating `RegExp` instances with numbered backreferences, or when flag <kbd>n</kbd> is explicitly disabled), any numbered backreferences within the regex are automatically adjusted to work correctly. However, issues can arise if you reference submatches by number (instead of their group names) from outside of the regex. Setting `subclass: true` resolves this, since the subclass knows about added "emulation groups" and automatically adjusts match results in all contexts.
|
||||
Context: `regex`'s implicit flag <kbd>n</kbd> (*named capture only* mode) means that all captures have names, so normally there's no need to reference submatches by number. In fact, flag <kbd>n</kbd> *prevents* you from doing so within the regex. And even in edge cases (such as when interpolating `RegExp` instances with numbered backreferences, or when flag <kbd>n</kbd> is explicitly disabled), any numbered backreferences within the regex are automatically adjusted to work correctly. However, issues can arise if you reference submatches by number (instead of their group names) from outside of the regex. Setting `subclass: true` resolves this, since the subclass knows about captures that are added only to emulate extended syntax, and automatically adjusts match results in all contexts.
|
||||
|
||||
> This option isn't enabled by default because it would prevent Regex+'s Babel plugin from emitting regex literals. It also has a small performance cost, and is rarely needed. The primary use case is tools that use `regex` internally with flag <kbd>n</kbd> disabled.
|
||||
> This option isn't enabled by default because it would prevent Regex+'s Babel plugin from emitting regex literals. It also has a tiny performance cost, and is rarely needed. The primary use case is tools that use `regex` internally with flag <kbd>n</kbd> disabled.
|
||||
|
||||
**`plugins`** — An array of functions. Plugins are called in order, after applying emulated flags and interpolation, but before the built-in plugins for extended syntax. This means that plugins can output extended syntax like atomic groups and subroutines. Plugins are expected to return an updated pattern string, and are called with two arguments:
|
||||
**`plugins`** — An array of functions. Plugins are called in order, after applying emulated flags and interpolation, but before the built-in plugins for extended syntax. This means that plugins can output extended syntax like atomic groups and subroutines. Plugins are expected to return an object with a string property `pattern`, and are called with two arguments:
|
||||
|
||||
1. The pattern, as processed so far by preceding plugins, etc.
|
||||
2. An object with a `flags` property that includes the native (non-emulated) flags that will be used by the regex.
|
||||
@@ -761,7 +764,7 @@ The final result after running all plugins is provided to the `RegExp` construct
|
||||
**`disable`** — A set of options that can be individually disabled by setting their values to `true`.
|
||||
|
||||
- **`x`** — Disables implicit, emulated [flag <kbd>x</kbd>](#flag-x).
|
||||
- **`n`** — Disables implicit, emulated [flag <kbd>n</kbd>](#flag-n). Note that, although it's safe to use unnamed captures and numbered backreferences within a regex when flag <kbd>n</kbd> is disabled, referencing submatches by number from *outside* a regex (e.g. in replacement strings) can result in incorrect values because extended syntax (atomic groups and subroutines) might add "emulation groups" to generated regex source. It's therefore recommended to enable the `subclass` option when disabling `n`.
|
||||
- **`n`** — Disables implicit, emulated [flag <kbd>n</kbd>](#flag-n). Note that, although it's safe to use unnamed captures and numbered backreferences within a regex when flag <kbd>n</kbd> is disabled, referencing submatches by number from *outside* a regex (e.g. in replacement strings) can result in incorrect values because extended syntax might add additional unnamed captures to generated regex source. It's therefore recommended to enable the `subclass` option when disabling `n`.
|
||||
- **`v`** — Disables implicit [flag <kbd>v</kbd>](#flag-v) even when it's supported natively, resulting in flag <kbd>u</kbd> being added instead (in combination with the `unicodeSetsPlugin`).
|
||||
- **`atomic`** — Disables [atomic groups](#atomic-groups) and [possessive quantifiers](#possessive-quantifiers), resulting in a syntax error if they're used.
|
||||
- **`subroutines`** — Disables [subroutines](#subroutines) and [subroutine definition groups](#subroutine-definition-groups), resulting in a syntax error if they're used.
|
||||
@@ -773,15 +776,15 @@ The final result after running all plugins is provided to the `RegExp` construct
|
||||
|
||||
### Returning a string
|
||||
|
||||
Function `rewrite` returns an object with properties `expression` and `flags` as strings, rather than returning a `RegExp` instance. This can be useful when you want to apply postprocessing to the output.
|
||||
Function `rewrite` returns an object with properties `pattern` and `flags` as strings, rather than returning a `RegExp` instance. This can be useful when you want to apply postprocessing to the output.
|
||||
|
||||
```js
|
||||
import {rewrite} from 'regex';
|
||||
rewrite('^ (ab | cd)', {flags: 'm'});
|
||||
// → {expression: '^(?:ab|cd)', flags: 'mv'}
|
||||
// → {pattern: '^(?:ab|cd)', flags: 'mv'}
|
||||
```
|
||||
|
||||
`rewrite` shares all of `regex`'s options (described above) except `subclass`. Providing the resulting `expression` and `flags` to the `RegExp` constructor produces the same result as using the `regex` tag.
|
||||
`rewrite` shares all of `regex`'s options (described above) except `subclass`. Providing the resulting `pattern` and `flags` to the `RegExp` constructor produces the same result as using the `regex` tag.
|
||||
|
||||
> Since `rewrite` isn't a template tag, it doesn't provide context-aware interpolation and doesn't automatically handle input as a raw string (you need to escape your backslashes).
|
||||
|
||||
|
8
node_modules/regex/dist/cjs/atomic.d.ts
generated
vendored
8
node_modules/regex/dist/cjs/atomic.d.ts
generated
vendored
@@ -2,15 +2,15 @@
|
||||
Apply transformations for atomic groups: `(?>…)`.
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {Required<import('./regex.js').PluginResult>}
|
||||
*/
|
||||
export function atomic(expression: string, data?: import("./regex.js").PluginData): string;
|
||||
export function atomic(expression: string, data?: import("./regex.js").PluginData): Required<import("./regex.js").PluginResult>;
|
||||
/**
|
||||
Transform posessive quantifiers into atomic groups. The posessessive quantifiers are:
|
||||
`?+`, `*+`, `++`, `{N}+`, `{N,}+`, `{N,N}+`.
|
||||
This follows Java, PCRE, Perl, and Python.
|
||||
Possessive quantifiers in Oniguruma and Onigmo are only: `?+`, `*+`, `++`.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function possessive(expression: string): string;
|
||||
export function possessive(expression: string): import("./regex.js").PluginResult;
|
||||
|
4
node_modules/regex/dist/cjs/backcompat.d.ts
generated
vendored
4
node_modules/regex/dist/cjs/backcompat.d.ts
generated
vendored
@@ -2,6 +2,6 @@
|
||||
Applies flag v rules when using flag u, for forward compatibility.
|
||||
Assumes flag u and doesn't worry about syntax errors that are caught by it.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function backcompatPlugin(expression: string): string;
|
||||
export function backcompatPlugin(expression: string): import("./regex.js").PluginResult;
|
||||
|
4
node_modules/regex/dist/cjs/flag-x.d.ts
generated
vendored
4
node_modules/regex/dist/cjs/flag-x.d.ts
generated
vendored
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
Remove `(?:)` token separators (most likely added by flag x) in cases where it's safe to do so.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function clean(expression: string): string;
|
||||
export function clean(expression: string): import("./regex.js").PluginResult;
|
||||
export function flagXPreprocessor(value: import("./utils.js").InterpolatedValue, runningContext: import("./utils.js").RunningContext, options: Required<import("./utils.js").RegexTagOptions>): {
|
||||
transformed: string;
|
||||
runningContext: import("./utils.js").RunningContext;
|
||||
|
2
node_modules/regex/dist/cjs/internals.d.ts
generated
vendored
2
node_modules/regex/dist/cjs/internals.d.ts
generated
vendored
@@ -1,2 +1,2 @@
|
||||
export { RegExpSubclass } from "./subclass.js";
|
||||
export { atomic, possessive } from "./atomic.js";
|
||||
export { emulationGroupMarker, RegExpSubclass } from "./subclass.js";
|
||||
|
31
node_modules/regex/dist/cjs/regex.d.ts
generated
vendored
31
node_modules/regex/dist/cjs/regex.d.ts
generated
vendored
@@ -1,7 +1,13 @@
|
||||
export type InterpolatedValue = string | RegExp | Pattern | number;
|
||||
export type PluginData = {
|
||||
flags?: string;
|
||||
useEmulationGroups?: boolean;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
};
|
||||
export type PluginResult = {
|
||||
pattern: string;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
};
|
||||
export type RawTemplate = TemplateStringsArray | {
|
||||
raw: Array<string>;
|
||||
@@ -9,8 +15,8 @@ export type RawTemplate = TemplateStringsArray | {
|
||||
export type RegexTagOptions = {
|
||||
flags?: string;
|
||||
subclass?: boolean;
|
||||
plugins?: Array<(expression: string, data: PluginData) => string>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => string) | null;
|
||||
plugins?: Array<(expression: string, data: PluginData) => PluginResult>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => PluginResult) | null;
|
||||
disable?: {
|
||||
x?: boolean;
|
||||
n?: boolean;
|
||||
@@ -40,14 +46,20 @@ import { pattern } from './pattern.js';
|
||||
@typedef {string | RegExp | Pattern | number} InterpolatedValue
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
useEmulationGroups?: boolean;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginData
|
||||
@typedef {{
|
||||
pattern: string;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginResult
|
||||
@typedef {TemplateStringsArray | {raw: Array<string>}} RawTemplate
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
subclass?: boolean;
|
||||
plugins?: Array<(expression: string, data: PluginData) => string>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => string) | null;
|
||||
plugins?: Array<(expression: string, data: PluginData) => PluginResult>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => PluginResult) | null;
|
||||
disable?: {
|
||||
x?: boolean;
|
||||
n?: boolean;
|
||||
@@ -85,10 +97,13 @@ export const regex: RegexTag<RegExp>;
|
||||
Returns the processed expression and flags as strings.
|
||||
@param {string} expression
|
||||
@param {RegexTagOptions} [options]
|
||||
@returns {{expression: string; flags: string;}}
|
||||
@returns {{
|
||||
pattern: string;
|
||||
flags: string;
|
||||
}}
|
||||
*/
|
||||
export function rewrite(expression?: string, options?: RegexTagOptions): {
|
||||
expression: string;
|
||||
pattern: string;
|
||||
flags: string;
|
||||
};
|
||||
import { Pattern } from './pattern.js';
|
||||
|
350
node_modules/regex/dist/cjs/regex.js
generated
vendored
350
node_modules/regex/dist/cjs/regex.js
generated
vendored
@@ -25,6 +25,19 @@ __export(regex_exports, {
|
||||
});
|
||||
module.exports = __toCommonJS(regex_exports);
|
||||
|
||||
// src/utils-internals.js
|
||||
var noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
|
||||
function incrementIfAtLeast(arr, threshold) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] >= threshold) {
|
||||
arr[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
function spliceStr(str, pos, oldValue, newValue) {
|
||||
return str.slice(0, pos) + newValue + str.slice(pos + oldValue.length);
|
||||
}
|
||||
|
||||
// node_modules/.pnpm/regex-utilities@2.3.0/node_modules/regex-utilities/src/index.js
|
||||
var Context = Object.freeze({
|
||||
DEFAULT: "DEFAULT",
|
||||
@@ -117,134 +130,22 @@ function getGroupContents(expression, contentsStartPos) {
|
||||
return expression.slice(contentsStartPos, contentsEndPos);
|
||||
}
|
||||
|
||||
// src/subclass.js
|
||||
var emulationGroupMarker = "$E$";
|
||||
var RegExpSubclass = class _RegExpSubclass extends RegExp {
|
||||
// Avoid `#private` to allow for subclassing
|
||||
/**
|
||||
@private
|
||||
@type {Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}> | undefined}
|
||||
*/
|
||||
_captureMap;
|
||||
/**
|
||||
@private
|
||||
@type {Record<number, string> | undefined}
|
||||
*/
|
||||
_namesByIndex;
|
||||
/**
|
||||
@param {string | RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
@param {{useEmulationGroups: boolean;}} [options]
|
||||
*/
|
||||
constructor(expression, flags, options) {
|
||||
if (expression instanceof RegExp && options) {
|
||||
throw new Error("Cannot provide options when copying a regexp");
|
||||
}
|
||||
const useEmulationGroups = !!options?.useEmulationGroups;
|
||||
const unmarked = useEmulationGroups ? unmarkEmulationGroups(expression) : null;
|
||||
super(unmarked?.expression || expression, flags);
|
||||
const src = useEmulationGroups ? unmarked : expression instanceof _RegExpSubclass ? expression : null;
|
||||
if (src) {
|
||||
this._captureMap = src._captureMap;
|
||||
this._namesByIndex = src._namesByIndex;
|
||||
}
|
||||
}
|
||||
/**
|
||||
Called internally by all String/RegExp methods that use regexes.
|
||||
@override
|
||||
@param {string} str
|
||||
@returns {RegExpExecArray | null}
|
||||
*/
|
||||
exec(str) {
|
||||
const match = RegExp.prototype.exec.call(this, str);
|
||||
if (!match || !this._captureMap) {
|
||||
return match;
|
||||
}
|
||||
const matchCopy = [...match];
|
||||
match.length = 1;
|
||||
let indicesCopy;
|
||||
if (this.hasIndices) {
|
||||
indicesCopy = [...match.indices];
|
||||
match.indices.length = 1;
|
||||
}
|
||||
for (let i = 1; i < matchCopy.length; i++) {
|
||||
if (this._captureMap[i].exclude) {
|
||||
const transfer = this._captureMap[i].transfer;
|
||||
if (transfer && match.length > transfer) {
|
||||
match[transfer] = matchCopy[i];
|
||||
const transferName = this._namesByIndex[transfer];
|
||||
if (transferName) {
|
||||
match.groups[transferName] = matchCopy[i];
|
||||
if (this.hasIndices) {
|
||||
match.indices.groups[transferName] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
if (this.hasIndices) {
|
||||
match.indices[transfer] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match.push(matchCopy[i]);
|
||||
if (this.hasIndices) {
|
||||
match.indices.push(indicesCopy[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
};
|
||||
function unmarkEmulationGroups(expression) {
|
||||
const marker = emulationGroupMarker.replace(/\$/g, "\\$");
|
||||
const _captureMap = [{ exclude: false }];
|
||||
const _namesByIndex = { 0: "" };
|
||||
let realCaptureNum = 0;
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\((?:(?!\?)|\?<(?![=!])(?<name>[^>]+)>)(?<mark>(?:\$(?<transfer>[1-9]\d*))?${marker})?`,
|
||||
({ 0: m, groups: { name, mark, transfer } }) => {
|
||||
if (mark) {
|
||||
_captureMap.push({
|
||||
exclude: true,
|
||||
transfer: transfer && +transfer
|
||||
});
|
||||
return m.slice(0, -mark.length);
|
||||
}
|
||||
realCaptureNum++;
|
||||
if (name) {
|
||||
_namesByIndex[realCaptureNum] = name;
|
||||
}
|
||||
_captureMap.push({
|
||||
exclude: false
|
||||
});
|
||||
return m;
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return {
|
||||
_captureMap,
|
||||
_namesByIndex,
|
||||
expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/utils-internals.js
|
||||
var noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
|
||||
function spliceStr(str, pos, oldValue, newValue) {
|
||||
return str.slice(0, pos) + newValue + str.slice(pos + oldValue.length);
|
||||
}
|
||||
|
||||
// src/atomic.js
|
||||
var atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncapturingDelim})|(?<capturingStart>\((?:\?<[^>]+>)?)|\\?.`, "gsu");
|
||||
function atomic(expression, data) {
|
||||
const hiddenCaptures = data?.hiddenCaptures ?? [];
|
||||
let captureTransfers = data?.captureTransfers ?? /* @__PURE__ */ new Map();
|
||||
if (!/\(\?>/.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
const aGDelim = "(?>";
|
||||
const emulatedAGDelim = `(?:(?=(${data?.useEmulationGroups ? emulationGroupMarker : ""}`;
|
||||
const emulatedAGDelim = "(?:(?=(";
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesBeforeAG = 0;
|
||||
let numAGs = 0;
|
||||
let aGPos = NaN;
|
||||
@@ -276,8 +177,21 @@ function atomic(expression, data) {
|
||||
} else if (m === ")" && inAG) {
|
||||
if (!numGroupsOpenInAG) {
|
||||
numAGs++;
|
||||
expression = `${expression.slice(0, aGPos)}${emulatedAGDelim}${expression.slice(aGPos + aGDelim.length, index)}))<$$${numAGs + numCapturesBeforeAG}>)${expression.slice(index + 1)}`;
|
||||
const addedCaptureNum = numCapturesBeforeAG + numAGs;
|
||||
expression = `${expression.slice(0, aGPos)}${emulatedAGDelim}${expression.slice(aGPos + aGDelim.length, index)}))<$$${addedCaptureNum}>)${expression.slice(index + 1)}`;
|
||||
hasProcessedAG = true;
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
if (captureTransfers.size) {
|
||||
const newCaptureTransfers = /* @__PURE__ */ new Map();
|
||||
captureTransfers.forEach((from, to) => {
|
||||
newCaptureTransfers.set(
|
||||
to >= addedCaptureNum ? to + 1 : to,
|
||||
from.map((f) => f >= addedCaptureNum ? f + 1 : f)
|
||||
);
|
||||
});
|
||||
captureTransfers = newCaptureTransfers;
|
||||
}
|
||||
break;
|
||||
}
|
||||
numGroupsOpenInAG--;
|
||||
@@ -287,6 +201,7 @@ function atomic(expression, data) {
|
||||
}
|
||||
}
|
||||
} while (hasProcessedAG);
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\\(?<backrefNum>[1-9]\d*)|<\$\$(?<wrappedBackrefNum>\d+)>`,
|
||||
@@ -302,7 +217,11 @@ function atomic(expression, data) {
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
var baseQuantifier = String.raw`(?:[?*+]|\{\d+(?:,\d*)?\})`;
|
||||
var possessivePluginToken = new RegExp(String.raw`
|
||||
@@ -323,7 +242,9 @@ var possessivePluginToken = new RegExp(String.raw`
|
||||
`.replace(/\s+/g, ""), "gsu");
|
||||
function possessive(expression) {
|
||||
if (!new RegExp(`${baseQuantifier}\\+`).test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
const openGroupIndices = [];
|
||||
let lastGroupIndex = null;
|
||||
@@ -374,7 +295,9 @@ function possessive(expression) {
|
||||
}
|
||||
lastToken = m;
|
||||
}
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/pattern.js
|
||||
@@ -695,7 +618,9 @@ function backcompatPlugin(expression) {
|
||||
}
|
||||
result += m;
|
||||
}
|
||||
return result;
|
||||
return {
|
||||
pattern: result
|
||||
};
|
||||
}
|
||||
|
||||
// src/flag-n.js
|
||||
@@ -848,21 +773,104 @@ function flagXPreprocessor(value, runningContext, options) {
|
||||
function clean(expression) {
|
||||
const sep = String.raw`\(\?:\)`;
|
||||
expression = replaceUnescaped(expression, `(?:${sep}){2,}`, "(?:)", Context.DEFAULT);
|
||||
const marker = emulationGroupMarker.replace(/\$/g, "\\$");
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`(?:${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{]))(?!${marker})`,
|
||||
String.raw`${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{])`,
|
||||
"",
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/subclass.js
|
||||
var RegExpSubclass = class _RegExpSubclass extends RegExp {
|
||||
// Avoid `#private` to allow for subclassing
|
||||
/**
|
||||
@private
|
||||
@type {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
_captureMap;
|
||||
/**
|
||||
@overload
|
||||
@param {string} expression
|
||||
@param {string} [flags]
|
||||
@param {{
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} [options]
|
||||
*/
|
||||
/**
|
||||
@overload
|
||||
@param {RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
*/
|
||||
constructor(expression, flags, options) {
|
||||
if (expression instanceof RegExp) {
|
||||
if (options) {
|
||||
throw new Error("Cannot provide options when copying a regexp");
|
||||
}
|
||||
super(expression, flags);
|
||||
if (expression instanceof _RegExpSubclass) {
|
||||
this._captureMap = expression._captureMap;
|
||||
} else {
|
||||
this._captureMap = /* @__PURE__ */ new Map();
|
||||
}
|
||||
} else {
|
||||
super(expression, flags);
|
||||
const hiddenCaptures = options?.hiddenCaptures ?? [];
|
||||
this._captureMap = createCaptureMap(hiddenCaptures);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Called internally by all String/RegExp methods that use regexes.
|
||||
@override
|
||||
@param {string} str
|
||||
@returns {RegExpExecArray | null}
|
||||
*/
|
||||
exec(str) {
|
||||
const match = super.exec(str);
|
||||
if (!match || !this._captureMap.size) {
|
||||
return match;
|
||||
}
|
||||
const matchCopy = [...match];
|
||||
match.length = 1;
|
||||
let indicesCopy;
|
||||
if (this.hasIndices) {
|
||||
indicesCopy = [...match.indices];
|
||||
match.indices.length = 1;
|
||||
}
|
||||
for (let i = 1; i < matchCopy.length; i++) {
|
||||
if (!this._captureMap.get(i)?.hidden) {
|
||||
match.push(matchCopy[i]);
|
||||
if (this.hasIndices) {
|
||||
match.indices.push(indicesCopy[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
};
|
||||
function createCaptureMap(hiddenCaptures) {
|
||||
const captureMap = /* @__PURE__ */ new Map();
|
||||
for (const num of hiddenCaptures) {
|
||||
captureMap.set(num, {
|
||||
hidden: true
|
||||
});
|
||||
}
|
||||
return captureMap;
|
||||
}
|
||||
|
||||
// src/subroutines.js
|
||||
function subroutines(expression, data) {
|
||||
const namedGroups = getNamedCapturingGroups(expression, { includeContents: true });
|
||||
const transformed = processSubroutines(expression, namedGroups, !!data?.useEmulationGroups);
|
||||
return processDefinitionGroup(transformed, namedGroups);
|
||||
const transformed = processSubroutines(expression, namedGroups, data?.hiddenCaptures ?? []);
|
||||
return {
|
||||
pattern: processDefinitionGroup(transformed.pattern, namedGroups),
|
||||
hiddenCaptures: transformed.hiddenCaptures
|
||||
};
|
||||
}
|
||||
var subroutinePattern = String.raw`\\g<(?<subroutineName>[^>&]+)>`;
|
||||
var token4 = new RegExp(String.raw`
|
||||
@@ -872,24 +880,27 @@ ${subroutinePattern}
|
||||
| \\k<(?<backrefName>[^>]+)>
|
||||
| \\?.
|
||||
`.replace(/\s+/g, ""), "gsu");
|
||||
function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
function processSubroutines(expression, namedGroups, hiddenCaptures) {
|
||||
if (!/\\g</.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
const hasBackrefs = hasUnescaped(expression, "\\\\(?:[1-9]|k<[^>]+>)", Context.DEFAULT);
|
||||
const subroutineWrapper = hasBackrefs ? `(${useEmulationGroups ? emulationGroupMarker : ""}` : "(?:";
|
||||
const subroutineWrapper = hasBackrefs ? "(" : "(?:";
|
||||
const openSubroutines = /* @__PURE__ */ new Map();
|
||||
const openSubroutinesStack = [];
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesPassedOutsideSubroutines = 0;
|
||||
let numCapturesPassedInsideSubroutines = 0;
|
||||
let numCapturesPassedInsideThisSubroutine = 0;
|
||||
let numSubroutineCapturesTrackedInRemap = 0;
|
||||
let numCharClassesOpen = 0;
|
||||
let result = expression;
|
||||
let match;
|
||||
token4.lastIndex = 0;
|
||||
while (match = token4.exec(result)) {
|
||||
while (match = token4.exec(expression)) {
|
||||
const { 0: m, index, groups: { subroutineName, capturingStart, backrefNum, backrefName } } = match;
|
||||
if (m === "[") {
|
||||
numCharClassesOpen++;
|
||||
@@ -906,22 +917,32 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine = 0;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
openSubroutines.set(subroutineName, {
|
||||
// Incrementally decremented to track when we've left the group
|
||||
unclosedGroupCount: countOpenParens(subroutineValue)
|
||||
});
|
||||
openSubroutinesStack.push(subroutineName);
|
||||
result = spliceStr(result, index, m, subroutineValue);
|
||||
expression = spliceStr(expression, index, m, subroutineValue);
|
||||
token4.lastIndex -= m.length - subroutineWrapper.length;
|
||||
} else if (capturingStart) {
|
||||
if (openSubroutines.size) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine++;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
if (m !== "(") {
|
||||
result = spliceStr(result, index, m, subroutineWrapper);
|
||||
expression = spliceStr(expression, index, m, subroutineWrapper);
|
||||
token4.lastIndex -= m.length - subroutineWrapper.length;
|
||||
}
|
||||
} else if (hasBackrefs) {
|
||||
@@ -945,7 +966,7 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
const group = namedGroups.get(lastOf(openSubroutinesStack));
|
||||
const subroutineNum = numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines - numCapturesPassedInsideThisSubroutine;
|
||||
const metadata = `\\k<$$b${num}s${subroutineNum}r${group.groupNum}c${group.numCaptures}>`;
|
||||
result = spliceStr(result, index, m, metadata);
|
||||
expression = spliceStr(expression, index, m, metadata);
|
||||
token4.lastIndex += metadata.length - m.length;
|
||||
}
|
||||
} else if (m === ")") {
|
||||
@@ -961,9 +982,10 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
numCharClassesOpen--;
|
||||
}
|
||||
}
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
if (hasBackrefs) {
|
||||
result = replaceUnescaped(
|
||||
result,
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\\(?:(?<bNum>[1-9]\d*)|k<\$\$b(?<bNumSub>\d+)s(?<subNum>\d+)r(?<refNum>\d+)c(?<refCaps>\d+)>)`,
|
||||
({ 0: m, groups: { bNum, bNumSub, subNum, refNum, refCaps } }) => {
|
||||
if (bNum) {
|
||||
@@ -985,7 +1007,10 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
Context.DEFAULT
|
||||
);
|
||||
}
|
||||
return result;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
var defineGroupToken = new RegExp(String.raw`${namedCapturingDelim}|\(\?:\)|(?<invalid>\\?.)`, "gsu");
|
||||
function processDefinitionGroup(expression, namedGroups) {
|
||||
@@ -1083,6 +1108,10 @@ function getNamedCapturingGroups(expression, { includeContents }) {
|
||||
function lastOf(arr) {
|
||||
return arr[arr.length - 1];
|
||||
}
|
||||
function updateHiddenCaptureTracking(hiddenCaptures, addedHiddenCaptures, addedCaptureNum) {
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
}
|
||||
|
||||
// src/regex.js
|
||||
var regex = (first, ...substitutions) => {
|
||||
@@ -1097,7 +1126,7 @@ var regex = (first, ...substitutions) => {
|
||||
};
|
||||
var regexFromTemplate = (options, template, ...substitutions) => {
|
||||
const opts = getOptions(options);
|
||||
const prepped = handlePreprocessors(template, substitutions, opts);
|
||||
const prepped = runPreprocessors(template, substitutions, opts);
|
||||
let precedingCaptures = 0;
|
||||
let expression = "";
|
||||
let runningContext;
|
||||
@@ -1117,9 +1146,10 @@ var regexFromTemplate = (options, template, ...substitutions) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
expression = handlePlugins(expression, opts);
|
||||
const plugged = runPlugins(expression, opts);
|
||||
expression = plugged.pattern;
|
||||
try {
|
||||
return opts.subclass ? new RegExpSubclass(expression, opts.flags, { useEmulationGroups: true }) : new RegExp(expression, opts.flags);
|
||||
return opts.subclass ? new RegExpSubclass(expression, opts.flags, { hiddenCaptures: plugged.hiddenCaptures }) : new RegExp(expression, opts.flags);
|
||||
} catch (err) {
|
||||
const stripped = err.message.replace(/ \/.+\/[a-z]*:/, "");
|
||||
err.message = `${stripped}: /${expression}/${opts.flags}`;
|
||||
@@ -1132,10 +1162,12 @@ function rewrite(expression = "", options) {
|
||||
throw new Error("Cannot use option subclass");
|
||||
}
|
||||
return {
|
||||
expression: handlePlugins(
|
||||
handlePreprocessors({ raw: [expression] }, [], opts).template.raw[0],
|
||||
// NOTE: Since `pattern` is a Regex+ export with special meaning, the term `expression` is used
|
||||
// in code to refer to regex source strings, except in the public API
|
||||
pattern: runPlugins(
|
||||
runPreprocessors({ raw: [expression] }, [], opts).template.raw[0],
|
||||
opts
|
||||
),
|
||||
).pattern,
|
||||
flags: opts.flags
|
||||
};
|
||||
}
|
||||
@@ -1163,7 +1195,7 @@ function getOptions(options) {
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
function handlePreprocessors(template, substitutions, options) {
|
||||
function runPreprocessors(template, substitutions, options) {
|
||||
const preprocessors = [];
|
||||
if (!options.disable.x) {
|
||||
preprocessors.push(flagXPreprocessor);
|
||||
@@ -1179,8 +1211,8 @@ function handlePreprocessors(template, substitutions, options) {
|
||||
substitutions
|
||||
};
|
||||
}
|
||||
function handlePlugins(expression, options) {
|
||||
const { flags, plugins, unicodeSetsPlugin, disable, subclass } = options;
|
||||
function runPlugins(expression, { flags, plugins, unicodeSetsPlugin, disable }) {
|
||||
let hiddenCaptures = [];
|
||||
[
|
||||
...plugins,
|
||||
// Run first, so provided plugins can output extended syntax
|
||||
@@ -1189,8 +1221,20 @@ function handlePlugins(expression, options) {
|
||||
...disable.x ? [] : [clean],
|
||||
// Run last, so it doesn't have to worry about parsing extended syntax
|
||||
...!unicodeSetsPlugin ? [] : [unicodeSetsPlugin]
|
||||
].forEach((p) => expression = p(expression, { flags, useEmulationGroups: subclass }));
|
||||
return expression;
|
||||
].forEach((plugin) => {
|
||||
const result = plugin(expression, { flags, hiddenCaptures });
|
||||
if (typeof result?.pattern !== "string") {
|
||||
throw new Error('Plugin must return an object with a string property "pattern"');
|
||||
}
|
||||
expression = result.pattern;
|
||||
if (result.hiddenCaptures) {
|
||||
hiddenCaptures = result.hiddenCaptures;
|
||||
}
|
||||
});
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
function interpolate(value, flags, regexContext, charClassContext, wrapEscapedStr, precedingCaptures) {
|
||||
if (value instanceof RegExp && regexContext !== RegexContext.DEFAULT) {
|
||||
|
6
node_modules/regex/dist/cjs/regex.js.map
generated
vendored
6
node_modules/regex/dist/cjs/regex.js.map
generated
vendored
File diff suppressed because one or more lines are too long
37
node_modules/regex/dist/cjs/subclass.d.ts
generated
vendored
37
node_modules/regex/dist/cjs/subclass.d.ts
generated
vendored
@@ -1,28 +1,31 @@
|
||||
export const emulationGroupMarker: "$E$";
|
||||
/**
|
||||
Works the same as JavaScript's native `RegExp` constructor in all contexts, but automatically
|
||||
adjusts matches and subpattern indices (with flag `d`) to account for injected emulation groups.
|
||||
adjusts subpattern matches and indices (with flag `d`) to account for captures added as part of
|
||||
emulating extended syntax.
|
||||
*/
|
||||
export class RegExpSubclass extends RegExp {
|
||||
/**
|
||||
@param {string | RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
@param {{useEmulationGroups: boolean;}} [options]
|
||||
*/
|
||||
constructor(expression: string | RegExpSubclass, flags?: string, options?: {
|
||||
useEmulationGroups: boolean;
|
||||
@overload
|
||||
@param {string} expression
|
||||
@param {string} [flags]
|
||||
@param {{
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} [options]
|
||||
*/
|
||||
constructor(expression: string, flags?: string, options?: {
|
||||
hiddenCaptures?: Array<number>;
|
||||
});
|
||||
/**
|
||||
@private
|
||||
@type {Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}> | undefined}
|
||||
*/
|
||||
private _captureMap;
|
||||
@overload
|
||||
@param {RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
*/
|
||||
constructor(expression: RegExpSubclass, flags?: string);
|
||||
/**
|
||||
@private
|
||||
@type {Record<number, string> | undefined}
|
||||
@type {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
private _namesByIndex;
|
||||
private _captureMap;
|
||||
}
|
||||
|
4
node_modules/regex/dist/cjs/subroutines.d.ts
generated
vendored
4
node_modules/regex/dist/cjs/subroutines.d.ts
generated
vendored
@@ -7,6 +7,6 @@ export type NamedCapturingGroupsMap = Map<string, {
|
||||
/**
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function subroutines(expression: string, data?: import("./regex.js").PluginData): string;
|
||||
export function subroutines(expression: string, data?: import("./regex.js").PluginData): import("./regex.js").PluginResult;
|
||||
|
6
node_modules/regex/dist/cjs/utils-internals.d.ts
generated
vendored
6
node_modules/regex/dist/cjs/utils-internals.d.ts
generated
vendored
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
Updates the array in place by incrementing each value greater than or equal to the threshold.
|
||||
@param {Array<number>} arr
|
||||
@param {number} threshold
|
||||
*/
|
||||
export function incrementIfAtLeast(arr: Array<number>, threshold: number): void;
|
||||
export const noncapturingDelim: any;
|
||||
/**
|
||||
@param {string} str
|
||||
|
8
node_modules/regex/dist/esm/atomic.d.ts
generated
vendored
8
node_modules/regex/dist/esm/atomic.d.ts
generated
vendored
@@ -2,15 +2,15 @@
|
||||
Apply transformations for atomic groups: `(?>…)`.
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {Required<import('./regex.js').PluginResult>}
|
||||
*/
|
||||
export function atomic(expression: string, data?: import("./regex.js").PluginData): string;
|
||||
export function atomic(expression: string, data?: import("./regex.js").PluginData): Required<import("./regex.js").PluginResult>;
|
||||
/**
|
||||
Transform posessive quantifiers into atomic groups. The posessessive quantifiers are:
|
||||
`?+`, `*+`, `++`, `{N}+`, `{N,}+`, `{N,N}+`.
|
||||
This follows Java, PCRE, Perl, and Python.
|
||||
Possessive quantifiers in Oniguruma and Onigmo are only: `?+`, `*+`, `++`.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function possessive(expression: string): string;
|
||||
export function possessive(expression: string): import("./regex.js").PluginResult;
|
||||
|
4
node_modules/regex/dist/esm/backcompat.d.ts
generated
vendored
4
node_modules/regex/dist/esm/backcompat.d.ts
generated
vendored
@@ -2,6 +2,6 @@
|
||||
Applies flag v rules when using flag u, for forward compatibility.
|
||||
Assumes flag u and doesn't worry about syntax errors that are caught by it.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function backcompatPlugin(expression: string): string;
|
||||
export function backcompatPlugin(expression: string): import("./regex.js").PluginResult;
|
||||
|
4
node_modules/regex/dist/esm/flag-x.d.ts
generated
vendored
4
node_modules/regex/dist/esm/flag-x.d.ts
generated
vendored
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
Remove `(?:)` token separators (most likely added by flag x) in cases where it's safe to do so.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function clean(expression: string): string;
|
||||
export function clean(expression: string): import("./regex.js").PluginResult;
|
||||
export function flagXPreprocessor(value: import("./utils.js").InterpolatedValue, runningContext: import("./utils.js").RunningContext, options: Required<import("./utils.js").RegexTagOptions>): {
|
||||
transformed: string;
|
||||
runningContext: import("./utils.js").RunningContext;
|
||||
|
2
node_modules/regex/dist/esm/internals.d.ts
generated
vendored
2
node_modules/regex/dist/esm/internals.d.ts
generated
vendored
@@ -1,2 +1,2 @@
|
||||
export { RegExpSubclass } from "./subclass.js";
|
||||
export { atomic, possessive } from "./atomic.js";
|
||||
export { emulationGroupMarker, RegExpSubclass } from "./subclass.js";
|
||||
|
31
node_modules/regex/dist/esm/regex.d.ts
generated
vendored
31
node_modules/regex/dist/esm/regex.d.ts
generated
vendored
@@ -1,7 +1,13 @@
|
||||
export type InterpolatedValue = string | RegExp | Pattern | number;
|
||||
export type PluginData = {
|
||||
flags?: string;
|
||||
useEmulationGroups?: boolean;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
};
|
||||
export type PluginResult = {
|
||||
pattern: string;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
};
|
||||
export type RawTemplate = TemplateStringsArray | {
|
||||
raw: Array<string>;
|
||||
@@ -9,8 +15,8 @@ export type RawTemplate = TemplateStringsArray | {
|
||||
export type RegexTagOptions = {
|
||||
flags?: string;
|
||||
subclass?: boolean;
|
||||
plugins?: Array<(expression: string, data: PluginData) => string>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => string) | null;
|
||||
plugins?: Array<(expression: string, data: PluginData) => PluginResult>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => PluginResult) | null;
|
||||
disable?: {
|
||||
x?: boolean;
|
||||
n?: boolean;
|
||||
@@ -40,14 +46,20 @@ import { pattern } from './pattern.js';
|
||||
@typedef {string | RegExp | Pattern | number} InterpolatedValue
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
useEmulationGroups?: boolean;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginData
|
||||
@typedef {{
|
||||
pattern: string;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginResult
|
||||
@typedef {TemplateStringsArray | {raw: Array<string>}} RawTemplate
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
subclass?: boolean;
|
||||
plugins?: Array<(expression: string, data: PluginData) => string>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => string) | null;
|
||||
plugins?: Array<(expression: string, data: PluginData) => PluginResult>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => PluginResult) | null;
|
||||
disable?: {
|
||||
x?: boolean;
|
||||
n?: boolean;
|
||||
@@ -85,10 +97,13 @@ export const regex: RegexTag<RegExp>;
|
||||
Returns the processed expression and flags as strings.
|
||||
@param {string} expression
|
||||
@param {RegexTagOptions} [options]
|
||||
@returns {{expression: string; flags: string;}}
|
||||
@returns {{
|
||||
pattern: string;
|
||||
flags: string;
|
||||
}}
|
||||
*/
|
||||
export function rewrite(expression?: string, options?: RegexTagOptions): {
|
||||
expression: string;
|
||||
pattern: string;
|
||||
flags: string;
|
||||
};
|
||||
import { Pattern } from './pattern.js';
|
||||
|
350
node_modules/regex/dist/esm/regex.js
generated
vendored
350
node_modules/regex/dist/esm/regex.js
generated
vendored
@@ -1,3 +1,16 @@
|
||||
// src/utils-internals.js
|
||||
var noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
|
||||
function incrementIfAtLeast(arr, threshold) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] >= threshold) {
|
||||
arr[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
function spliceStr(str, pos, oldValue, newValue) {
|
||||
return str.slice(0, pos) + newValue + str.slice(pos + oldValue.length);
|
||||
}
|
||||
|
||||
// node_modules/.pnpm/regex-utilities@2.3.0/node_modules/regex-utilities/src/index.js
|
||||
var Context = Object.freeze({
|
||||
DEFAULT: "DEFAULT",
|
||||
@@ -90,134 +103,22 @@ function getGroupContents(expression, contentsStartPos) {
|
||||
return expression.slice(contentsStartPos, contentsEndPos);
|
||||
}
|
||||
|
||||
// src/subclass.js
|
||||
var emulationGroupMarker = "$E$";
|
||||
var RegExpSubclass = class _RegExpSubclass extends RegExp {
|
||||
// Avoid `#private` to allow for subclassing
|
||||
/**
|
||||
@private
|
||||
@type {Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}> | undefined}
|
||||
*/
|
||||
_captureMap;
|
||||
/**
|
||||
@private
|
||||
@type {Record<number, string> | undefined}
|
||||
*/
|
||||
_namesByIndex;
|
||||
/**
|
||||
@param {string | RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
@param {{useEmulationGroups: boolean;}} [options]
|
||||
*/
|
||||
constructor(expression, flags, options) {
|
||||
if (expression instanceof RegExp && options) {
|
||||
throw new Error("Cannot provide options when copying a regexp");
|
||||
}
|
||||
const useEmulationGroups = !!options?.useEmulationGroups;
|
||||
const unmarked = useEmulationGroups ? unmarkEmulationGroups(expression) : null;
|
||||
super(unmarked?.expression || expression, flags);
|
||||
const src = useEmulationGroups ? unmarked : expression instanceof _RegExpSubclass ? expression : null;
|
||||
if (src) {
|
||||
this._captureMap = src._captureMap;
|
||||
this._namesByIndex = src._namesByIndex;
|
||||
}
|
||||
}
|
||||
/**
|
||||
Called internally by all String/RegExp methods that use regexes.
|
||||
@override
|
||||
@param {string} str
|
||||
@returns {RegExpExecArray | null}
|
||||
*/
|
||||
exec(str) {
|
||||
const match = RegExp.prototype.exec.call(this, str);
|
||||
if (!match || !this._captureMap) {
|
||||
return match;
|
||||
}
|
||||
const matchCopy = [...match];
|
||||
match.length = 1;
|
||||
let indicesCopy;
|
||||
if (this.hasIndices) {
|
||||
indicesCopy = [...match.indices];
|
||||
match.indices.length = 1;
|
||||
}
|
||||
for (let i = 1; i < matchCopy.length; i++) {
|
||||
if (this._captureMap[i].exclude) {
|
||||
const transfer = this._captureMap[i].transfer;
|
||||
if (transfer && match.length > transfer) {
|
||||
match[transfer] = matchCopy[i];
|
||||
const transferName = this._namesByIndex[transfer];
|
||||
if (transferName) {
|
||||
match.groups[transferName] = matchCopy[i];
|
||||
if (this.hasIndices) {
|
||||
match.indices.groups[transferName] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
if (this.hasIndices) {
|
||||
match.indices[transfer] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match.push(matchCopy[i]);
|
||||
if (this.hasIndices) {
|
||||
match.indices.push(indicesCopy[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
};
|
||||
function unmarkEmulationGroups(expression) {
|
||||
const marker = emulationGroupMarker.replace(/\$/g, "\\$");
|
||||
const _captureMap = [{ exclude: false }];
|
||||
const _namesByIndex = { 0: "" };
|
||||
let realCaptureNum = 0;
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\((?:(?!\?)|\?<(?![=!])(?<name>[^>]+)>)(?<mark>(?:\$(?<transfer>[1-9]\d*))?${marker})?`,
|
||||
({ 0: m, groups: { name, mark, transfer } }) => {
|
||||
if (mark) {
|
||||
_captureMap.push({
|
||||
exclude: true,
|
||||
transfer: transfer && +transfer
|
||||
});
|
||||
return m.slice(0, -mark.length);
|
||||
}
|
||||
realCaptureNum++;
|
||||
if (name) {
|
||||
_namesByIndex[realCaptureNum] = name;
|
||||
}
|
||||
_captureMap.push({
|
||||
exclude: false
|
||||
});
|
||||
return m;
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return {
|
||||
_captureMap,
|
||||
_namesByIndex,
|
||||
expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/utils-internals.js
|
||||
var noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
|
||||
function spliceStr(str, pos, oldValue, newValue) {
|
||||
return str.slice(0, pos) + newValue + str.slice(pos + oldValue.length);
|
||||
}
|
||||
|
||||
// src/atomic.js
|
||||
var atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncapturingDelim})|(?<capturingStart>\((?:\?<[^>]+>)?)|\\?.`, "gsu");
|
||||
function atomic(expression, data) {
|
||||
const hiddenCaptures = data?.hiddenCaptures ?? [];
|
||||
let captureTransfers = data?.captureTransfers ?? /* @__PURE__ */ new Map();
|
||||
if (!/\(\?>/.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
const aGDelim = "(?>";
|
||||
const emulatedAGDelim = `(?:(?=(${data?.useEmulationGroups ? emulationGroupMarker : ""}`;
|
||||
const emulatedAGDelim = "(?:(?=(";
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesBeforeAG = 0;
|
||||
let numAGs = 0;
|
||||
let aGPos = NaN;
|
||||
@@ -249,8 +150,21 @@ function atomic(expression, data) {
|
||||
} else if (m === ")" && inAG) {
|
||||
if (!numGroupsOpenInAG) {
|
||||
numAGs++;
|
||||
expression = `${expression.slice(0, aGPos)}${emulatedAGDelim}${expression.slice(aGPos + aGDelim.length, index)}))<$$${numAGs + numCapturesBeforeAG}>)${expression.slice(index + 1)}`;
|
||||
const addedCaptureNum = numCapturesBeforeAG + numAGs;
|
||||
expression = `${expression.slice(0, aGPos)}${emulatedAGDelim}${expression.slice(aGPos + aGDelim.length, index)}))<$$${addedCaptureNum}>)${expression.slice(index + 1)}`;
|
||||
hasProcessedAG = true;
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
if (captureTransfers.size) {
|
||||
const newCaptureTransfers = /* @__PURE__ */ new Map();
|
||||
captureTransfers.forEach((from, to) => {
|
||||
newCaptureTransfers.set(
|
||||
to >= addedCaptureNum ? to + 1 : to,
|
||||
from.map((f) => f >= addedCaptureNum ? f + 1 : f)
|
||||
);
|
||||
});
|
||||
captureTransfers = newCaptureTransfers;
|
||||
}
|
||||
break;
|
||||
}
|
||||
numGroupsOpenInAG--;
|
||||
@@ -260,6 +174,7 @@ function atomic(expression, data) {
|
||||
}
|
||||
}
|
||||
} while (hasProcessedAG);
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\\(?<backrefNum>[1-9]\d*)|<\$\$(?<wrappedBackrefNum>\d+)>`,
|
||||
@@ -275,7 +190,11 @@ function atomic(expression, data) {
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
var baseQuantifier = String.raw`(?:[?*+]|\{\d+(?:,\d*)?\})`;
|
||||
var possessivePluginToken = new RegExp(String.raw`
|
||||
@@ -296,7 +215,9 @@ var possessivePluginToken = new RegExp(String.raw`
|
||||
`.replace(/\s+/g, ""), "gsu");
|
||||
function possessive(expression) {
|
||||
if (!new RegExp(`${baseQuantifier}\\+`).test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
const openGroupIndices = [];
|
||||
let lastGroupIndex = null;
|
||||
@@ -347,7 +268,9 @@ function possessive(expression) {
|
||||
}
|
||||
lastToken = m;
|
||||
}
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/pattern.js
|
||||
@@ -668,7 +591,9 @@ function backcompatPlugin(expression) {
|
||||
}
|
||||
result += m;
|
||||
}
|
||||
return result;
|
||||
return {
|
||||
pattern: result
|
||||
};
|
||||
}
|
||||
|
||||
// src/flag-n.js
|
||||
@@ -821,21 +746,104 @@ function flagXPreprocessor(value, runningContext, options) {
|
||||
function clean(expression) {
|
||||
const sep = String.raw`\(\?:\)`;
|
||||
expression = replaceUnescaped(expression, `(?:${sep}){2,}`, "(?:)", Context.DEFAULT);
|
||||
const marker = emulationGroupMarker.replace(/\$/g, "\\$");
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`(?:${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{]))(?!${marker})`,
|
||||
String.raw`${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{])`,
|
||||
"",
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression
|
||||
};
|
||||
}
|
||||
|
||||
// src/subclass.js
|
||||
var RegExpSubclass = class _RegExpSubclass extends RegExp {
|
||||
// Avoid `#private` to allow for subclassing
|
||||
/**
|
||||
@private
|
||||
@type {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
_captureMap;
|
||||
/**
|
||||
@overload
|
||||
@param {string} expression
|
||||
@param {string} [flags]
|
||||
@param {{
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} [options]
|
||||
*/
|
||||
/**
|
||||
@overload
|
||||
@param {RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
*/
|
||||
constructor(expression, flags, options) {
|
||||
if (expression instanceof RegExp) {
|
||||
if (options) {
|
||||
throw new Error("Cannot provide options when copying a regexp");
|
||||
}
|
||||
super(expression, flags);
|
||||
if (expression instanceof _RegExpSubclass) {
|
||||
this._captureMap = expression._captureMap;
|
||||
} else {
|
||||
this._captureMap = /* @__PURE__ */ new Map();
|
||||
}
|
||||
} else {
|
||||
super(expression, flags);
|
||||
const hiddenCaptures = options?.hiddenCaptures ?? [];
|
||||
this._captureMap = createCaptureMap(hiddenCaptures);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Called internally by all String/RegExp methods that use regexes.
|
||||
@override
|
||||
@param {string} str
|
||||
@returns {RegExpExecArray | null}
|
||||
*/
|
||||
exec(str) {
|
||||
const match = super.exec(str);
|
||||
if (!match || !this._captureMap.size) {
|
||||
return match;
|
||||
}
|
||||
const matchCopy = [...match];
|
||||
match.length = 1;
|
||||
let indicesCopy;
|
||||
if (this.hasIndices) {
|
||||
indicesCopy = [...match.indices];
|
||||
match.indices.length = 1;
|
||||
}
|
||||
for (let i = 1; i < matchCopy.length; i++) {
|
||||
if (!this._captureMap.get(i)?.hidden) {
|
||||
match.push(matchCopy[i]);
|
||||
if (this.hasIndices) {
|
||||
match.indices.push(indicesCopy[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
};
|
||||
function createCaptureMap(hiddenCaptures) {
|
||||
const captureMap = /* @__PURE__ */ new Map();
|
||||
for (const num of hiddenCaptures) {
|
||||
captureMap.set(num, {
|
||||
hidden: true
|
||||
});
|
||||
}
|
||||
return captureMap;
|
||||
}
|
||||
|
||||
// src/subroutines.js
|
||||
function subroutines(expression, data) {
|
||||
const namedGroups = getNamedCapturingGroups(expression, { includeContents: true });
|
||||
const transformed = processSubroutines(expression, namedGroups, !!data?.useEmulationGroups);
|
||||
return processDefinitionGroup(transformed, namedGroups);
|
||||
const transformed = processSubroutines(expression, namedGroups, data?.hiddenCaptures ?? []);
|
||||
return {
|
||||
pattern: processDefinitionGroup(transformed.pattern, namedGroups),
|
||||
hiddenCaptures: transformed.hiddenCaptures
|
||||
};
|
||||
}
|
||||
var subroutinePattern = String.raw`\\g<(?<subroutineName>[^>&]+)>`;
|
||||
var token4 = new RegExp(String.raw`
|
||||
@@ -845,24 +853,27 @@ ${subroutinePattern}
|
||||
| \\k<(?<backrefName>[^>]+)>
|
||||
| \\?.
|
||||
`.replace(/\s+/g, ""), "gsu");
|
||||
function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
function processSubroutines(expression, namedGroups, hiddenCaptures) {
|
||||
if (!/\\g</.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
const hasBackrefs = hasUnescaped(expression, "\\\\(?:[1-9]|k<[^>]+>)", Context.DEFAULT);
|
||||
const subroutineWrapper = hasBackrefs ? `(${useEmulationGroups ? emulationGroupMarker : ""}` : "(?:";
|
||||
const subroutineWrapper = hasBackrefs ? "(" : "(?:";
|
||||
const openSubroutines = /* @__PURE__ */ new Map();
|
||||
const openSubroutinesStack = [];
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesPassedOutsideSubroutines = 0;
|
||||
let numCapturesPassedInsideSubroutines = 0;
|
||||
let numCapturesPassedInsideThisSubroutine = 0;
|
||||
let numSubroutineCapturesTrackedInRemap = 0;
|
||||
let numCharClassesOpen = 0;
|
||||
let result = expression;
|
||||
let match;
|
||||
token4.lastIndex = 0;
|
||||
while (match = token4.exec(result)) {
|
||||
while (match = token4.exec(expression)) {
|
||||
const { 0: m, index, groups: { subroutineName, capturingStart, backrefNum, backrefName } } = match;
|
||||
if (m === "[") {
|
||||
numCharClassesOpen++;
|
||||
@@ -879,22 +890,32 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine = 0;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
openSubroutines.set(subroutineName, {
|
||||
// Incrementally decremented to track when we've left the group
|
||||
unclosedGroupCount: countOpenParens(subroutineValue)
|
||||
});
|
||||
openSubroutinesStack.push(subroutineName);
|
||||
result = spliceStr(result, index, m, subroutineValue);
|
||||
expression = spliceStr(expression, index, m, subroutineValue);
|
||||
token4.lastIndex -= m.length - subroutineWrapper.length;
|
||||
} else if (capturingStart) {
|
||||
if (openSubroutines.size) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine++;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
if (m !== "(") {
|
||||
result = spliceStr(result, index, m, subroutineWrapper);
|
||||
expression = spliceStr(expression, index, m, subroutineWrapper);
|
||||
token4.lastIndex -= m.length - subroutineWrapper.length;
|
||||
}
|
||||
} else if (hasBackrefs) {
|
||||
@@ -918,7 +939,7 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
const group = namedGroups.get(lastOf(openSubroutinesStack));
|
||||
const subroutineNum = numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines - numCapturesPassedInsideThisSubroutine;
|
||||
const metadata = `\\k<$$b${num}s${subroutineNum}r${group.groupNum}c${group.numCaptures}>`;
|
||||
result = spliceStr(result, index, m, metadata);
|
||||
expression = spliceStr(expression, index, m, metadata);
|
||||
token4.lastIndex += metadata.length - m.length;
|
||||
}
|
||||
} else if (m === ")") {
|
||||
@@ -934,9 +955,10 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
numCharClassesOpen--;
|
||||
}
|
||||
}
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
if (hasBackrefs) {
|
||||
result = replaceUnescaped(
|
||||
result,
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\\(?:(?<bNum>[1-9]\d*)|k<\$\$b(?<bNumSub>\d+)s(?<subNum>\d+)r(?<refNum>\d+)c(?<refCaps>\d+)>)`,
|
||||
({ 0: m, groups: { bNum, bNumSub, subNum, refNum, refCaps } }) => {
|
||||
if (bNum) {
|
||||
@@ -958,7 +980,10 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
Context.DEFAULT
|
||||
);
|
||||
}
|
||||
return result;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
var defineGroupToken = new RegExp(String.raw`${namedCapturingDelim}|\(\?:\)|(?<invalid>\\?.)`, "gsu");
|
||||
function processDefinitionGroup(expression, namedGroups) {
|
||||
@@ -1056,6 +1081,10 @@ function getNamedCapturingGroups(expression, { includeContents }) {
|
||||
function lastOf(arr) {
|
||||
return arr[arr.length - 1];
|
||||
}
|
||||
function updateHiddenCaptureTracking(hiddenCaptures, addedHiddenCaptures, addedCaptureNum) {
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
}
|
||||
|
||||
// src/regex.js
|
||||
var regex = (first, ...substitutions) => {
|
||||
@@ -1070,7 +1099,7 @@ var regex = (first, ...substitutions) => {
|
||||
};
|
||||
var regexFromTemplate = (options, template, ...substitutions) => {
|
||||
const opts = getOptions(options);
|
||||
const prepped = handlePreprocessors(template, substitutions, opts);
|
||||
const prepped = runPreprocessors(template, substitutions, opts);
|
||||
let precedingCaptures = 0;
|
||||
let expression = "";
|
||||
let runningContext;
|
||||
@@ -1090,9 +1119,10 @@ var regexFromTemplate = (options, template, ...substitutions) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
expression = handlePlugins(expression, opts);
|
||||
const plugged = runPlugins(expression, opts);
|
||||
expression = plugged.pattern;
|
||||
try {
|
||||
return opts.subclass ? new RegExpSubclass(expression, opts.flags, { useEmulationGroups: true }) : new RegExp(expression, opts.flags);
|
||||
return opts.subclass ? new RegExpSubclass(expression, opts.flags, { hiddenCaptures: plugged.hiddenCaptures }) : new RegExp(expression, opts.flags);
|
||||
} catch (err) {
|
||||
const stripped = err.message.replace(/ \/.+\/[a-z]*:/, "");
|
||||
err.message = `${stripped}: /${expression}/${opts.flags}`;
|
||||
@@ -1105,10 +1135,12 @@ function rewrite(expression = "", options) {
|
||||
throw new Error("Cannot use option subclass");
|
||||
}
|
||||
return {
|
||||
expression: handlePlugins(
|
||||
handlePreprocessors({ raw: [expression] }, [], opts).template.raw[0],
|
||||
// NOTE: Since `pattern` is a Regex+ export with special meaning, the term `expression` is used
|
||||
// in code to refer to regex source strings, except in the public API
|
||||
pattern: runPlugins(
|
||||
runPreprocessors({ raw: [expression] }, [], opts).template.raw[0],
|
||||
opts
|
||||
),
|
||||
).pattern,
|
||||
flags: opts.flags
|
||||
};
|
||||
}
|
||||
@@ -1136,7 +1168,7 @@ function getOptions(options) {
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
function handlePreprocessors(template, substitutions, options) {
|
||||
function runPreprocessors(template, substitutions, options) {
|
||||
const preprocessors = [];
|
||||
if (!options.disable.x) {
|
||||
preprocessors.push(flagXPreprocessor);
|
||||
@@ -1152,8 +1184,8 @@ function handlePreprocessors(template, substitutions, options) {
|
||||
substitutions
|
||||
};
|
||||
}
|
||||
function handlePlugins(expression, options) {
|
||||
const { flags, plugins, unicodeSetsPlugin, disable, subclass } = options;
|
||||
function runPlugins(expression, { flags, plugins, unicodeSetsPlugin, disable }) {
|
||||
let hiddenCaptures = [];
|
||||
[
|
||||
...plugins,
|
||||
// Run first, so provided plugins can output extended syntax
|
||||
@@ -1162,8 +1194,20 @@ function handlePlugins(expression, options) {
|
||||
...disable.x ? [] : [clean],
|
||||
// Run last, so it doesn't have to worry about parsing extended syntax
|
||||
...!unicodeSetsPlugin ? [] : [unicodeSetsPlugin]
|
||||
].forEach((p) => expression = p(expression, { flags, useEmulationGroups: subclass }));
|
||||
return expression;
|
||||
].forEach((plugin) => {
|
||||
const result = plugin(expression, { flags, hiddenCaptures });
|
||||
if (typeof result?.pattern !== "string") {
|
||||
throw new Error('Plugin must return an object with a string property "pattern"');
|
||||
}
|
||||
expression = result.pattern;
|
||||
if (result.hiddenCaptures) {
|
||||
hiddenCaptures = result.hiddenCaptures;
|
||||
}
|
||||
});
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures
|
||||
};
|
||||
}
|
||||
function interpolate(value, flags, regexContext, charClassContext, wrapEscapedStr, precedingCaptures) {
|
||||
if (value instanceof RegExp && regexContext !== RegexContext.DEFAULT) {
|
||||
|
6
node_modules/regex/dist/esm/regex.js.map
generated
vendored
6
node_modules/regex/dist/esm/regex.js.map
generated
vendored
File diff suppressed because one or more lines are too long
37
node_modules/regex/dist/esm/subclass.d.ts
generated
vendored
37
node_modules/regex/dist/esm/subclass.d.ts
generated
vendored
@@ -1,28 +1,31 @@
|
||||
export const emulationGroupMarker: "$E$";
|
||||
/**
|
||||
Works the same as JavaScript's native `RegExp` constructor in all contexts, but automatically
|
||||
adjusts matches and subpattern indices (with flag `d`) to account for injected emulation groups.
|
||||
adjusts subpattern matches and indices (with flag `d`) to account for captures added as part of
|
||||
emulating extended syntax.
|
||||
*/
|
||||
export class RegExpSubclass extends RegExp {
|
||||
/**
|
||||
@param {string | RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
@param {{useEmulationGroups: boolean;}} [options]
|
||||
*/
|
||||
constructor(expression: string | RegExpSubclass, flags?: string, options?: {
|
||||
useEmulationGroups: boolean;
|
||||
@overload
|
||||
@param {string} expression
|
||||
@param {string} [flags]
|
||||
@param {{
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} [options]
|
||||
*/
|
||||
constructor(expression: string, flags?: string, options?: {
|
||||
hiddenCaptures?: Array<number>;
|
||||
});
|
||||
/**
|
||||
@private
|
||||
@type {Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}> | undefined}
|
||||
*/
|
||||
private _captureMap;
|
||||
@overload
|
||||
@param {RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
*/
|
||||
constructor(expression: RegExpSubclass, flags?: string);
|
||||
/**
|
||||
@private
|
||||
@type {Record<number, string> | undefined}
|
||||
@type {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
private _namesByIndex;
|
||||
private _captureMap;
|
||||
}
|
||||
|
4
node_modules/regex/dist/esm/subroutines.d.ts
generated
vendored
4
node_modules/regex/dist/esm/subroutines.d.ts
generated
vendored
@@ -7,6 +7,6 @@ export type NamedCapturingGroupsMap = Map<string, {
|
||||
/**
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
export function subroutines(expression: string, data?: import("./regex.js").PluginData): string;
|
||||
export function subroutines(expression: string, data?: import("./regex.js").PluginData): import("./regex.js").PluginResult;
|
||||
|
6
node_modules/regex/dist/esm/utils-internals.d.ts
generated
vendored
6
node_modules/regex/dist/esm/utils-internals.d.ts
generated
vendored
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
Updates the array in place by incrementing each value greater than or equal to the threshold.
|
||||
@param {Array<number>} arr
|
||||
@param {number} threshold
|
||||
*/
|
||||
export function incrementIfAtLeast(arr: Array<number>, threshold: number): void;
|
||||
export const noncapturingDelim: any;
|
||||
/**
|
||||
@param {string} str
|
||||
|
28
node_modules/regex/dist/regex.min.js
generated
vendored
28
node_modules/regex/dist/regex.min.js
generated
vendored
File diff suppressed because one or more lines are too long
8
node_modules/regex/dist/regex.min.js.map
generated
vendored
8
node_modules/regex/dist/regex.min.js.map
generated
vendored
File diff suppressed because one or more lines are too long
31
node_modules/regex/package.json
generated
vendored
31
node_modules/regex/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "regex",
|
||||
"version": "5.1.1",
|
||||
"version": "6.0.1",
|
||||
"description": "Regex template tag with extended syntax, context-aware interpolation, and always-on best practices",
|
||||
"author": "Steven Levithan",
|
||||
"license": "MIT",
|
||||
@@ -24,18 +24,6 @@
|
||||
"browser": "./dist/regex.min.js",
|
||||
"main": "./dist/cjs/regex.js",
|
||||
"types": "./dist/cjs/regex.d.ts",
|
||||
"scripts": {
|
||||
"bundle:global": "esbuild src/regex.js --global-name=Regex --bundle --minify --sourcemap --outfile=dist/regex.min.js",
|
||||
"bundle:esm": "esbuild src/regex.js --format=esm --bundle --sourcemap --outfile=dist/esm/regex.js",
|
||||
"bundle:cjs": "esbuild src/regex.js --format=cjs --bundle --sourcemap --outfile=dist/cjs/regex.js",
|
||||
"types": "tsc src/regex.js src/internals.js --rootDir src --declaration --allowJs --emitDeclarationOnly --outDir types",
|
||||
"prebuild": "rm -rf dist/* types/*",
|
||||
"build": "pnpm run bundle:global && pnpm run bundle:esm && pnpm run bundle:cjs && pnpm run types",
|
||||
"postbuild": "node scripts/postbuild.js",
|
||||
"pretest": "pnpm run build",
|
||||
"test": "jasmine && tsc --project spec/types/tsconfig.test.json && attw --pack . --entrypoints .",
|
||||
"prepublishOnly": "pnpm test"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
@@ -52,10 +40,21 @@
|
||||
"regex-utilities": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "~0.17.2",
|
||||
"@arethetypeswrong/cli": "^0.17.3",
|
||||
"esbuild": "^0.24.2",
|
||||
"expect-type": "^1.1.0",
|
||||
"jasmine": "^5.5.0",
|
||||
"typescript": "~5.7.2"
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"bundle:global": "esbuild src/regex.js --global-name=Regex --bundle --minify --sourcemap --outfile=dist/regex.min.js",
|
||||
"bundle:esm": "esbuild src/regex.js --format=esm --bundle --sourcemap --outfile=dist/esm/regex.js",
|
||||
"bundle:cjs": "esbuild src/regex.js --format=cjs --bundle --sourcemap --outfile=dist/cjs/regex.js",
|
||||
"types": "tsc src/regex.js src/internals.js --rootDir src --declaration --allowJs --emitDeclarationOnly --outDir types",
|
||||
"prebuild": "rm -rf dist/* types/*",
|
||||
"build": "pnpm run bundle:global && pnpm run bundle:esm && pnpm run bundle:cjs && pnpm run types",
|
||||
"postbuild": "node scripts/postbuild.js",
|
||||
"pretest": "pnpm run build",
|
||||
"test": "jasmine && tsc --project spec/types/tsconfig.test.json && attw --pack . --entrypoints ."
|
||||
}
|
||||
}
|
||||
}
|
62
node_modules/regex/src/atomic.js
generated
vendored
62
node_modules/regex/src/atomic.js
generated
vendored
@@ -1,5 +1,4 @@
|
||||
import {emulationGroupMarker} from './subclass.js';
|
||||
import {noncapturingDelim, spliceStr} from './utils-internals.js';
|
||||
import {incrementIfAtLeast, noncapturingDelim, spliceStr} from './utils-internals.js';
|
||||
import {Context, replaceUnescaped} from 'regex-utilities';
|
||||
|
||||
const atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncapturingDelim})|(?<capturingStart>\((?:\?<[^>]+>)?)|\\?.`, 'gsu');
|
||||
@@ -8,15 +7,24 @@ const atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncaptur
|
||||
Apply transformations for atomic groups: `(?>…)`.
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {Required<import('./regex.js').PluginResult>}
|
||||
*/
|
||||
function atomic(expression, data) {
|
||||
const hiddenCaptures = data?.hiddenCaptures ?? [];
|
||||
// Capture transfer is used by <github.com/slevithan/oniguruma-to-es>
|
||||
let captureTransfers = data?.captureTransfers ?? new Map();
|
||||
if (!/\(\?>/.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
const aGDelim = '(?>';
|
||||
const emulatedAGDelim = `(?:(?=(${data?.useEmulationGroups ? emulationGroupMarker : ''}`;
|
||||
const emulatedAGDelim = '(?:(?=(';
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesBeforeAG = 0;
|
||||
let numAGs = 0;
|
||||
let aGPos = NaN;
|
||||
@@ -49,14 +57,27 @@ function atomic(expression, data) {
|
||||
} else if (m === ')' && inAG) {
|
||||
if (!numGroupsOpenInAG) {
|
||||
numAGs++;
|
||||
const addedCaptureNum = numCapturesBeforeAG + numAGs;
|
||||
// Replace `expression` and use `<$$N>` as a temporary wrapper for the backref so it
|
||||
// can avoid backref renumbering afterward. Need to wrap the whole substitution
|
||||
// (including the lookahead and following backref) in a noncapturing group to handle
|
||||
// following quantifiers and literal digits
|
||||
// can avoid backref renumbering afterward. Wrap the whole substitution (including the
|
||||
// lookahead and following backref) in a noncapturing group to handle following
|
||||
// quantifiers and literal digits
|
||||
expression = `${expression.slice(0, aGPos)}${emulatedAGDelim}${
|
||||
expression.slice(aGPos + aGDelim.length, index)
|
||||
}))<$$${numAGs + numCapturesBeforeAG}>)${expression.slice(index + 1)}`;
|
||||
}))<$$${addedCaptureNum}>)${expression.slice(index + 1)}`;
|
||||
hasProcessedAG = true;
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
if (captureTransfers.size) {
|
||||
const newCaptureTransfers = new Map();
|
||||
captureTransfers.forEach((from, to) => {
|
||||
newCaptureTransfers.set(
|
||||
to >= addedCaptureNum ? to + 1 : to,
|
||||
from.map(f => f >= addedCaptureNum ? f + 1 : f)
|
||||
);
|
||||
});
|
||||
captureTransfers = newCaptureTransfers;
|
||||
}
|
||||
break;
|
||||
}
|
||||
numGroupsOpenInAG--;
|
||||
@@ -66,10 +87,12 @@ function atomic(expression, data) {
|
||||
numCharClassesOpen--;
|
||||
}
|
||||
}
|
||||
// Start over from the beginning of the last atomic group's contents, in case the processed group
|
||||
// Start over from the beginning of the atomic group's contents, in case the processed group
|
||||
// contains additional atomic groups
|
||||
} while (hasProcessedAG);
|
||||
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
|
||||
// Second pass to adjust numbered backrefs
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
@@ -86,7 +109,12 @@ function atomic(expression, data) {
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
|
||||
return {
|
||||
pattern: expression,
|
||||
captureTransfers,
|
||||
hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
const baseQuantifier = String.raw`(?:[?*+]|\{\d+(?:,\d*)?\})`;
|
||||
@@ -114,12 +142,15 @@ Transform posessive quantifiers into atomic groups. The posessessive quantifiers
|
||||
This follows Java, PCRE, Perl, and Python.
|
||||
Possessive quantifiers in Oniguruma and Onigmo are only: `?+`, `*+`, `++`.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
function possessive(expression) {
|
||||
if (!(new RegExp(`${baseQuantifier}\\+`).test(expression))) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
};
|
||||
}
|
||||
|
||||
const openGroupIndices = [];
|
||||
let lastGroupIndex = null;
|
||||
let lastCharClassIndex = null;
|
||||
@@ -178,7 +209,10 @@ function possessive(expression) {
|
||||
}
|
||||
lastToken = m;
|
||||
}
|
||||
return expression;
|
||||
|
||||
return {
|
||||
pattern: expression,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
|
6
node_modules/regex/src/backcompat.js
generated
vendored
6
node_modules/regex/src/backcompat.js
generated
vendored
@@ -15,7 +15,7 @@ const token = new RegExp(String.raw`
|
||||
Applies flag v rules when using flag u, for forward compatibility.
|
||||
Assumes flag u and doesn't worry about syntax errors that are caught by it.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
function backcompatPlugin(expression) {
|
||||
const unescapedLiteralHyphenMsg = 'Invalid unescaped "-" in character class';
|
||||
@@ -51,7 +51,9 @@ function backcompatPlugin(expression) {
|
||||
}
|
||||
result += m;
|
||||
}
|
||||
return result;
|
||||
return {
|
||||
pattern: result,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
|
11
node_modules/regex/src/flag-x.js
generated
vendored
11
node_modules/regex/src/flag-x.js
generated
vendored
@@ -1,4 +1,3 @@
|
||||
import {emulationGroupMarker} from './subclass.js';
|
||||
import {CharClassContext, doublePunctuatorChars, getEndContextForIncompleteExpression, RegexContext, sandboxLoneDoublePunctuatorChar, sandboxUnsafeNulls} from './utils.js';
|
||||
import {noncapturingDelim} from './utils-internals.js';
|
||||
import {Context, replaceUnescaped} from 'regex-utilities';
|
||||
@@ -157,7 +156,7 @@ function flagXPreprocessor(value, runningContext, options) {
|
||||
/**
|
||||
Remove `(?:)` token separators (most likely added by flag x) in cases where it's safe to do so.
|
||||
@param {string} expression
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
function clean(expression) {
|
||||
const sep = String.raw`\(\?:\)`;
|
||||
@@ -173,20 +172,20 @@ function clean(expression) {
|
||||
// so we already get an error from that.
|
||||
// - If preceded by one of `()|.]^>`, `\\[bBdDfnrsStvwW]`, `(?:`, or a lookaround opening.
|
||||
// - So long as the separator is not followed by a quantifier.
|
||||
// - And, not followed by an emulation group marker.
|
||||
// Examples of things that are not safe to remove `(?:)` at the boundaries of:
|
||||
// - Anywhere: Letters, numbers, or any of `-=_,<?*+{}`.
|
||||
// - If followed by any of `:!>`.
|
||||
// - If preceded by any of `\\[cgkpPux]`.
|
||||
// - Anything inside character classes.
|
||||
const marker = emulationGroupMarker.replace(/\$/g, '\\$');
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`(?:${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{]))(?!${marker})`,
|
||||
String.raw`${sep}(?=[)|.[$\\]|\((?!DEFINE)|$)|(?<=[()|.\]^>]|\\[bBdDfnrsStvwW]|\(\?(?:[:=!]|<[=!])|^)${sep}(?![?*+{])`,
|
||||
'',
|
||||
Context.DEFAULT
|
||||
);
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
|
2
node_modules/regex/src/internals.js
generated
vendored
2
node_modules/regex/src/internals.js
generated
vendored
@@ -1,2 +1,2 @@
|
||||
export {atomic, possessive} from './atomic.js';
|
||||
export {emulationGroupMarker, RegExpSubclass} from './subclass.js';
|
||||
export {RegExpSubclass} from './subclass.js';
|
||||
|
57
node_modules/regex/src/regex.js
generated
vendored
57
node_modules/regex/src/regex.js
generated
vendored
@@ -12,14 +12,20 @@ import {Context, hasUnescaped, replaceUnescaped} from 'regex-utilities';
|
||||
@typedef {string | RegExp | Pattern | number} InterpolatedValue
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
useEmulationGroups?: boolean;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginData
|
||||
@typedef {{
|
||||
pattern: string;
|
||||
captureTransfers?: Map<number, Array<number>>;
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} PluginResult
|
||||
@typedef {TemplateStringsArray | {raw: Array<string>}} RawTemplate
|
||||
@typedef {{
|
||||
flags?: string;
|
||||
subclass?: boolean;
|
||||
plugins?: Array<(expression: string, data: PluginData) => string>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => string) | null;
|
||||
plugins?: Array<(expression: string, data: PluginData) => PluginResult>;
|
||||
unicodeSetsPlugin?: ((expression: string, data: PluginData) => PluginResult) | null;
|
||||
disable?: {
|
||||
x?: boolean;
|
||||
n?: boolean;
|
||||
@@ -79,7 +85,7 @@ Returns a RegExp from a template and substitutions to fill the template holes.
|
||||
*/
|
||||
const regexFromTemplate = (options, template, ...substitutions) => {
|
||||
const opts = getOptions(options);
|
||||
const prepped = handlePreprocessors(template, substitutions, opts);
|
||||
const prepped = runPreprocessors(template, substitutions, opts);
|
||||
|
||||
let precedingCaptures = 0;
|
||||
let expression = '';
|
||||
@@ -105,10 +111,11 @@ const regexFromTemplate = (options, template, ...substitutions) => {
|
||||
}
|
||||
});
|
||||
|
||||
expression = handlePlugins(expression, opts);
|
||||
const plugged = runPlugins(expression, opts);
|
||||
expression = plugged.pattern;
|
||||
try {
|
||||
return opts.subclass ?
|
||||
new RegExpSubclass(expression, opts.flags, {useEmulationGroups: true}) :
|
||||
new RegExpSubclass(expression, opts.flags, {hiddenCaptures: plugged.hiddenCaptures}) :
|
||||
new RegExp(expression, opts.flags);
|
||||
} catch (err) {
|
||||
// Improve DX by always including the generated source in the error message. Some browsers
|
||||
@@ -123,19 +130,23 @@ const regexFromTemplate = (options, template, ...substitutions) => {
|
||||
Returns the processed expression and flags as strings.
|
||||
@param {string} expression
|
||||
@param {RegexTagOptions} [options]
|
||||
@returns {{expression: string; flags: string;}}
|
||||
@returns {{
|
||||
pattern: string;
|
||||
flags: string;
|
||||
}}
|
||||
*/
|
||||
function rewrite(expression = '', options) {
|
||||
const opts = getOptions(options);
|
||||
if (opts.subclass) {
|
||||
// Don't allow including emulation group markers in output
|
||||
throw new Error('Cannot use option subclass');
|
||||
}
|
||||
return {
|
||||
expression: handlePlugins(
|
||||
handlePreprocessors({raw: [expression]}, [], opts).template.raw[0],
|
||||
// NOTE: Since `pattern` is a Regex+ export with special meaning, the term `expression` is used
|
||||
// in code to refer to regex source strings, except in the public API
|
||||
pattern: runPlugins(
|
||||
runPreprocessors({raw: [expression]}, [], opts).template.raw[0],
|
||||
opts
|
||||
),
|
||||
).pattern,
|
||||
flags: opts.flags,
|
||||
};
|
||||
}
|
||||
@@ -176,7 +187,7 @@ function getOptions(options) {
|
||||
substitutions: ReadonlyArray<InterpolatedValue>;
|
||||
}}
|
||||
*/
|
||||
function handlePreprocessors(template, substitutions, options) {
|
||||
function runPreprocessors(template, substitutions, options) {
|
||||
const preprocessors = [];
|
||||
// Implicit flag x is handled first because otherwise some regex syntax (if unescaped) within
|
||||
// comments could cause problems when parsing
|
||||
@@ -200,18 +211,30 @@ function handlePreprocessors(template, substitutions, options) {
|
||||
/**
|
||||
@param {string} expression
|
||||
@param {Required<RegexTagOptions>} options
|
||||
@returns {string}
|
||||
@returns {Required<PluginResult>}
|
||||
*/
|
||||
function handlePlugins(expression, options) {
|
||||
const {flags, plugins, unicodeSetsPlugin, disable, subclass} = options;
|
||||
function runPlugins(expression, {flags, plugins, unicodeSetsPlugin, disable}) {
|
||||
let hiddenCaptures = [];
|
||||
[ ...plugins, // Run first, so provided plugins can output extended syntax
|
||||
...(disable.subroutines ? [] : [subroutines]),
|
||||
...(disable.atomic ? [] : [possessive, atomic]),
|
||||
...(disable.x ? [] : [clean]),
|
||||
// Run last, so it doesn't have to worry about parsing extended syntax
|
||||
...(!unicodeSetsPlugin ? [] : [unicodeSetsPlugin]),
|
||||
].forEach(p => expression = p(expression, {flags, useEmulationGroups: subclass}));
|
||||
return expression;
|
||||
].forEach(plugin => {
|
||||
const result = plugin(expression, {flags, hiddenCaptures});
|
||||
if (typeof result?.pattern !== 'string') {
|
||||
throw new Error('Plugin must return an object with a string property "pattern"');
|
||||
}
|
||||
expression = result.pattern;
|
||||
if (result.hiddenCaptures) {
|
||||
hiddenCaptures = result.hiddenCaptures;
|
||||
}
|
||||
});
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
145
node_modules/regex/src/subclass.js
generated
vendored
145
node_modules/regex/src/subclass.js
generated
vendored
@@ -1,51 +1,47 @@
|
||||
import {Context, replaceUnescaped} from 'regex-utilities';
|
||||
|
||||
// This marker was chosen because it's impossible to match (so its extemely unlikely to be used in
|
||||
// a user-provided regex); it's not at risk of being optimized away, transformed, or flagged as an
|
||||
// error by a plugin; and it ends with an unquantifiable token
|
||||
const emulationGroupMarker = '$E$';
|
||||
// Note: Emulation groups with transfer are also supported. They look like `($N$E$…)` where `N` is
|
||||
// an integer 1 or greater. They're not used directly by Regex+ but can be used by plugins and
|
||||
// libraries that use Regex+ internals. Emulation groups with transfer are not only excluded from
|
||||
// match results, but additionally transfer their match to the group specified by `N`
|
||||
|
||||
/**
|
||||
Works the same as JavaScript's native `RegExp` constructor in all contexts, but automatically
|
||||
adjusts matches and subpattern indices (with flag `d`) to account for injected emulation groups.
|
||||
adjusts subpattern matches and indices (with flag `d`) to account for captures added as part of
|
||||
emulating extended syntax.
|
||||
*/
|
||||
class RegExpSubclass extends RegExp {
|
||||
// Avoid `#private` to allow for subclassing
|
||||
/**
|
||||
@private
|
||||
@type {Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}> | undefined}
|
||||
@type {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
_captureMap;
|
||||
/**
|
||||
@private
|
||||
@type {Record<number, string> | undefined}
|
||||
*/
|
||||
_namesByIndex;
|
||||
/**
|
||||
@param {string | RegExpSubclass} expression
|
||||
@overload
|
||||
@param {string} expression
|
||||
@param {string} [flags]
|
||||
@param {{
|
||||
hiddenCaptures?: Array<number>;
|
||||
}} [options]
|
||||
*/
|
||||
/**
|
||||
@overload
|
||||
@param {RegExpSubclass} expression
|
||||
@param {string} [flags]
|
||||
@param {{useEmulationGroups: boolean;}} [options]
|
||||
*/
|
||||
constructor(expression, flags, options) {
|
||||
if (expression instanceof RegExp && options) {
|
||||
throw new Error('Cannot provide options when copying a regexp');
|
||||
}
|
||||
const useEmulationGroups = !!options?.useEmulationGroups;
|
||||
const unmarked = useEmulationGroups ? unmarkEmulationGroups(expression) : null;
|
||||
super(unmarked?.expression || expression, flags);
|
||||
// The third argument `options` isn't provided when regexes are copied as part of the internal
|
||||
// handling of string methods `matchAll` and `split`
|
||||
const src = useEmulationGroups ? unmarked : (expression instanceof RegExpSubclass ? expression : null);
|
||||
if (src) {
|
||||
this._captureMap = src._captureMap;
|
||||
this._namesByIndex = src._namesByIndex;
|
||||
// Argument `options` isn't provided when regexes are copied via `new RegExpSubclass(regexp)`,
|
||||
// including as part of the internal handling of string methods `matchAll` and `split`
|
||||
if (expression instanceof RegExp) {
|
||||
if (options) {
|
||||
throw new Error('Cannot provide options when copying a regexp');
|
||||
}
|
||||
super(expression, flags);
|
||||
if (expression instanceof RegExpSubclass) {
|
||||
this._captureMap = expression._captureMap;
|
||||
} else {
|
||||
this._captureMap = new Map();
|
||||
}
|
||||
} else {
|
||||
super(expression, flags);
|
||||
const hiddenCaptures = options?.hiddenCaptures ?? [];
|
||||
this._captureMap = createCaptureMap(hiddenCaptures);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -55,8 +51,8 @@ class RegExpSubclass extends RegExp {
|
||||
@returns {RegExpExecArray | null}
|
||||
*/
|
||||
exec(str) {
|
||||
const match = RegExp.prototype.exec.call(this, str);
|
||||
if (!match || !this._captureMap) {
|
||||
const match = super.exec(str);
|
||||
if (!match || !this._captureMap.size) {
|
||||
return match;
|
||||
}
|
||||
const matchCopy = [...match];
|
||||
@@ -68,22 +64,7 @@ class RegExpSubclass extends RegExp {
|
||||
match.indices.length = 1;
|
||||
}
|
||||
for (let i = 1; i < matchCopy.length; i++) {
|
||||
if (this._captureMap[i].exclude) {
|
||||
const transfer = this._captureMap[i].transfer;
|
||||
if (transfer && match.length > transfer) {
|
||||
match[transfer] = matchCopy[i];
|
||||
const transferName = this._namesByIndex[transfer];
|
||||
if (transferName) {
|
||||
match.groups[transferName] = matchCopy[i];
|
||||
if (this.hasIndices) {
|
||||
match.indices.groups[transferName] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
if (this.hasIndices) {
|
||||
match.indices[transfer] = indicesCopy[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!this._captureMap.get(i)?.hidden) {
|
||||
match.push(matchCopy[i]);
|
||||
if (this.hasIndices) {
|
||||
match.indices.push(indicesCopy[i]);
|
||||
@@ -95,53 +76,23 @@ class RegExpSubclass extends RegExp {
|
||||
}
|
||||
|
||||
/**
|
||||
Build the capturing group map (with emulation groups marked to indicate their submatches shouldn't
|
||||
appear in results), and remove the markers for captures that were added to emulate extended syntax.
|
||||
@param {string} expression
|
||||
@returns {{
|
||||
_captureMap: Array<{
|
||||
exclude: boolean;
|
||||
transfer?: number;
|
||||
}>;
|
||||
_namesByIndex: Record<number, string>;
|
||||
expression: string;
|
||||
}}
|
||||
Build the capturing group map, with hidden captures marked to indicate their submatches shouldn't
|
||||
appear in match results.
|
||||
@param {Array<number>} hiddenCaptures
|
||||
@returns {Map<number, {
|
||||
hidden: true;
|
||||
}>}
|
||||
*/
|
||||
function unmarkEmulationGroups(expression) {
|
||||
const marker = emulationGroupMarker.replace(/\$/g, '\\$');
|
||||
const _captureMap = [{exclude: false}];
|
||||
const _namesByIndex = {0: ''};
|
||||
let realCaptureNum = 0;
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\((?:(?!\?)|\?<(?![=!])(?<name>[^>]+)>)(?<mark>(?:\$(?<transfer>[1-9]\d*))?${marker})?`,
|
||||
({0: m, groups: {name, mark, transfer}}) => {
|
||||
if (mark) {
|
||||
_captureMap.push({
|
||||
exclude: true,
|
||||
transfer: transfer && +transfer,
|
||||
});
|
||||
return m.slice(0, -mark.length);
|
||||
}
|
||||
realCaptureNum++;
|
||||
if (name) {
|
||||
_namesByIndex[realCaptureNum] = name;
|
||||
}
|
||||
_captureMap.push({
|
||||
exclude: false,
|
||||
});
|
||||
return m;
|
||||
},
|
||||
Context.DEFAULT
|
||||
);
|
||||
return {
|
||||
_captureMap,
|
||||
_namesByIndex,
|
||||
expression,
|
||||
};
|
||||
function createCaptureMap(hiddenCaptures) {
|
||||
const captureMap = new Map();
|
||||
for (const num of hiddenCaptures) {
|
||||
captureMap.set(num, {
|
||||
hidden: true,
|
||||
});
|
||||
}
|
||||
return captureMap;
|
||||
}
|
||||
|
||||
export {
|
||||
emulationGroupMarker,
|
||||
RegExpSubclass,
|
||||
};
|
||||
|
67
node_modules/regex/src/subroutines.js
generated
vendored
67
node_modules/regex/src/subroutines.js
generated
vendored
@@ -1,20 +1,22 @@
|
||||
import {emulationGroupMarker} from './subclass.js';
|
||||
import {capturingDelim, countCaptures, namedCapturingDelim} from './utils.js';
|
||||
import {spliceStr} from './utils-internals.js';
|
||||
import {incrementIfAtLeast, spliceStr} from './utils-internals.js';
|
||||
import {Context, execUnescaped, forEachUnescaped, getGroupContents, hasUnescaped, replaceUnescaped} from 'regex-utilities';
|
||||
|
||||
/**
|
||||
@param {string} expression
|
||||
@param {import('./regex.js').PluginData} [data]
|
||||
@returns {string}
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
function subroutines(expression, data) {
|
||||
// NOTE: subroutines and definition groups fully support numbered backreferences and unnamed
|
||||
// captures (from interpolated regexes or from turning implicit flag n off), and all of the
|
||||
// complex forward and backward backreference adjustments that can result
|
||||
const namedGroups = getNamedCapturingGroups(expression, {includeContents: true});
|
||||
const transformed = processSubroutines(expression, namedGroups, !!data?.useEmulationGroups);
|
||||
return processDefinitionGroup(transformed, namedGroups);
|
||||
const transformed = processSubroutines(expression, namedGroups, data?.hiddenCaptures ?? []);
|
||||
return {
|
||||
pattern: processDefinitionGroup(transformed.pattern, namedGroups),
|
||||
hiddenCaptures: transformed.hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
// Explicitly exclude `&` from subroutine name chars because it's used by extension
|
||||
@@ -41,28 +43,32 @@ ${subroutinePattern}
|
||||
Apply transformations for subroutines: `\g<name>`.
|
||||
@param {string} expression
|
||||
@param {NamedCapturingGroupsMap} namedGroups
|
||||
@param {boolean} useEmulationGroups
|
||||
@returns {string}
|
||||
@param {Array<number>} hiddenCaptures
|
||||
@returns {import('./regex.js').PluginResult}
|
||||
*/
|
||||
function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
function processSubroutines(expression, namedGroups, hiddenCaptures) {
|
||||
if (!/\\g</.test(expression)) {
|
||||
return expression;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
// Can skip a lot of processing and avoid adding captures if there are no backrefs
|
||||
const hasBackrefs = hasUnescaped(expression, '\\\\(?:[1-9]|k<[^>]+>)', Context.DEFAULT);
|
||||
const subroutineWrapper = hasBackrefs ? `(${useEmulationGroups ? emulationGroupMarker : ''}` : '(?:';
|
||||
const subroutineWrapper = hasBackrefs ? '(' : '(?:';
|
||||
const openSubroutines = new Map();
|
||||
const openSubroutinesStack = [];
|
||||
const captureNumMap = [0];
|
||||
const addedHiddenCaptures = [];
|
||||
let numCapturesPassedOutsideSubroutines = 0;
|
||||
let numCapturesPassedInsideSubroutines = 0;
|
||||
let numCapturesPassedInsideThisSubroutine = 0;
|
||||
let numSubroutineCapturesTrackedInRemap = 0;
|
||||
let numCharClassesOpen = 0;
|
||||
let result = expression;
|
||||
let match;
|
||||
token.lastIndex = 0;
|
||||
while (match = token.exec(result)) {
|
||||
while (match = token.exec(expression)) {
|
||||
const {0: m, index, groups: {subroutineName, capturingStart, backrefNum, backrefName}} = match;
|
||||
if (m === '[') {
|
||||
numCharClassesOpen++;
|
||||
@@ -85,6 +91,11 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine = 0;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
openSubroutines.set(subroutineName, {
|
||||
// Incrementally decremented to track when we've left the group
|
||||
@@ -92,7 +103,7 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
});
|
||||
openSubroutinesStack.push(subroutineName);
|
||||
// Expand the subroutine's contents into the pattern we're looping over
|
||||
result = spliceStr(result, index, m, subroutineValue);
|
||||
expression = spliceStr(expression, index, m, subroutineValue);
|
||||
token.lastIndex -= m.length - subroutineWrapper.length;
|
||||
} else if (capturingStart) {
|
||||
// Somewhere within an expanded subroutine
|
||||
@@ -100,6 +111,11 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
if (hasBackrefs) {
|
||||
numCapturesPassedInsideThisSubroutine++;
|
||||
numCapturesPassedInsideSubroutines++;
|
||||
updateHiddenCaptureTracking(
|
||||
hiddenCaptures,
|
||||
addedHiddenCaptures,
|
||||
numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines
|
||||
);
|
||||
}
|
||||
// Named capturing group
|
||||
if (m !== '(') {
|
||||
@@ -108,7 +124,7 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
// Given that flag n prevents unnamed capture and thereby requires you to rely on named
|
||||
// backrefs and `groups`, switching to unnamed essentially accomplishes not creating a
|
||||
// capture. Can fully avoid capturing if there are no backrefs in the expression
|
||||
result = spliceStr(result, index, m, subroutineWrapper);
|
||||
expression = spliceStr(expression, index, m, subroutineWrapper);
|
||||
token.lastIndex -= m.length - subroutineWrapper.length;
|
||||
}
|
||||
} else if (hasBackrefs) {
|
||||
@@ -144,7 +160,7 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
// - c: The number of captures within `r`, not counting the effects of subroutines
|
||||
const subroutineNum = numCapturesPassedOutsideSubroutines + numCapturesPassedInsideSubroutines - numCapturesPassedInsideThisSubroutine;
|
||||
const metadata = `\\k<$$b${num}s${subroutineNum}r${group.groupNum}c${group.numCaptures}>`;
|
||||
result = spliceStr(result, index, m, metadata);
|
||||
expression = spliceStr(expression, index, m, metadata);
|
||||
token.lastIndex += metadata.length - m.length;
|
||||
}
|
||||
} else if (m === ')') {
|
||||
@@ -162,10 +178,12 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
}
|
||||
}
|
||||
|
||||
hiddenCaptures.push(...addedHiddenCaptures);
|
||||
|
||||
if (hasBackrefs) {
|
||||
// Second pass to adjust backrefs
|
||||
result = replaceUnescaped(
|
||||
result,
|
||||
expression = replaceUnescaped(
|
||||
expression,
|
||||
String.raw`\\(?:(?<bNum>[1-9]\d*)|k<\$\$b(?<bNumSub>\d+)s(?<subNum>\d+)r(?<refNum>\d+)c(?<refCaps>\d+)>)`,
|
||||
({0: m, groups: {bNum, bNumSub, subNum, refNum, refCaps}}) => {
|
||||
if (bNum) {
|
||||
@@ -188,7 +206,10 @@ function processSubroutines(expression, namedGroups, useEmulationGroups) {
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
return {
|
||||
pattern: expression,
|
||||
hiddenCaptures,
|
||||
};
|
||||
}
|
||||
|
||||
// `(?:)` allowed because it can be added by flag x's preprocessing of whitespace and comments
|
||||
@@ -336,6 +357,16 @@ function lastOf(arr) {
|
||||
return arr[arr.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
@param {Array<number>} hiddenCaptures
|
||||
@param {Array<number>} addedHiddenCaptures
|
||||
@param {number} addedCaptureNum
|
||||
*/
|
||||
function updateHiddenCaptureTracking(hiddenCaptures, addedHiddenCaptures, addedCaptureNum) {
|
||||
addedHiddenCaptures.push(addedCaptureNum);
|
||||
incrementIfAtLeast(hiddenCaptures, addedCaptureNum);
|
||||
}
|
||||
|
||||
export {
|
||||
subroutines,
|
||||
};
|
||||
|
14
node_modules/regex/src/utils-internals.js
generated
vendored
14
node_modules/regex/src/utils-internals.js
generated
vendored
@@ -2,6 +2,19 @@
|
||||
|
||||
const noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
|
||||
|
||||
/**
|
||||
Updates the array in place by incrementing each value greater than or equal to the threshold.
|
||||
@param {Array<number>} arr
|
||||
@param {number} threshold
|
||||
*/
|
||||
function incrementIfAtLeast(arr, threshold) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] >= threshold) {
|
||||
arr[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param {string} str
|
||||
@param {number} pos
|
||||
@@ -14,6 +27,7 @@ function spliceStr(str, pos, oldValue, newValue) {
|
||||
}
|
||||
|
||||
export {
|
||||
incrementIfAtLeast,
|
||||
noncapturingDelim,
|
||||
spliceStr,
|
||||
};
|
||||
|
Reference in New Issue
Block a user