update
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
"name": "minimatch",
|
||||
"description": "a glob matcher in javascript",
|
||||
"version": "3.1.2",
|
||||
"publishConfig": {
|
||||
"tag": "v3-legacy"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/minimatch.git"
|
||||
},
|
||||
"main": "minimatch.js",
|
||||
"scripts": {
|
||||
"test": "tap",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^15.1.6"
|
||||
},
|
||||
"license": "ISC",
|
||||
"files": [
|
||||
"minimatch.js"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,86 @@
|
||||
import { HotPayload } from '../../types/hmrPayload.js';
|
||||
|
||||
interface FetchFunctionOptions {
|
||||
cached?: boolean;
|
||||
startOffset?: number;
|
||||
}
|
||||
type FetchResult = CachedFetchResult | ExternalFetchResult | ViteFetchResult;
|
||||
interface CachedFetchResult {
|
||||
/**
|
||||
* If module cached in the runner, we can just confirm
|
||||
* it wasn't invalidated on the server side.
|
||||
*/
|
||||
cache: true;
|
||||
}
|
||||
interface ExternalFetchResult {
|
||||
/**
|
||||
* The path to the externalized module starting with file://,
|
||||
* by default this will be imported via a dynamic "import"
|
||||
* instead of being transformed by vite and loaded with vite runner
|
||||
*/
|
||||
externalize: string;
|
||||
/**
|
||||
* Type of the module. Will be used to determine if import statement is correct.
|
||||
* For example, if Vite needs to throw an error if variable is not actually exported
|
||||
*/
|
||||
type: 'module' | 'commonjs' | 'builtin' | 'network';
|
||||
}
|
||||
interface ViteFetchResult {
|
||||
/**
|
||||
* Code that will be evaluated by vite runner
|
||||
* by default this will be wrapped in an async function
|
||||
*/
|
||||
code: string;
|
||||
/**
|
||||
* File path of the module on disk.
|
||||
* This will be resolved as import.meta.url/filename
|
||||
* Will be equal to `null` for virtual modules
|
||||
*/
|
||||
file: string | null;
|
||||
/**
|
||||
* Module ID in the server module graph.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Module URL used in the import.
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Invalidate module on the client side.
|
||||
*/
|
||||
invalidate: boolean;
|
||||
}
|
||||
type InvokeMethods = {
|
||||
fetchModule: (id: string, importer?: string, options?: FetchFunctionOptions) => Promise<FetchResult>;
|
||||
};
|
||||
|
||||
type ModuleRunnerTransportHandlers = {
|
||||
onMessage: (data: HotPayload) => void;
|
||||
onDisconnection: () => void;
|
||||
};
|
||||
/**
|
||||
* "send and connect" or "invoke" must be implemented
|
||||
*/
|
||||
interface ModuleRunnerTransport {
|
||||
connect?(handlers: ModuleRunnerTransportHandlers): Promise<void> | void;
|
||||
disconnect?(): Promise<void> | void;
|
||||
send?(data: HotPayload): Promise<void> | void;
|
||||
invoke?(data: HotPayload): Promise<{
|
||||
result: any;
|
||||
} | {
|
||||
error: any;
|
||||
}>;
|
||||
timeout?: number;
|
||||
}
|
||||
interface NormalizedModuleRunnerTransport {
|
||||
connect?(onMessage?: (data: HotPayload) => void): Promise<void> | void;
|
||||
disconnect?(): Promise<void> | void;
|
||||
send(data: HotPayload): Promise<void>;
|
||||
invoke<T extends keyof InvokeMethods>(name: T, data: Parameters<InvokeMethods[T]>): Promise<ReturnType<Awaited<InvokeMethods[T]>>>;
|
||||
}
|
||||
declare const createWebSocketModuleRunnerTransport: (options: {
|
||||
createConnection: () => WebSocket;
|
||||
pingInterval?: number;
|
||||
}) => Required<Pick<ModuleRunnerTransport, "connect" | "disconnect" | "send">>;
|
||||
|
||||
export { type ExternalFetchResult as E, type FetchFunctionOptions as F, type ModuleRunnerTransport as M, type NormalizedModuleRunnerTransport as N, type ViteFetchResult as V, type FetchResult as a, type ModuleRunnerTransportHandlers as b, createWebSocketModuleRunnerTransport as c };
|
||||
@@ -0,0 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 8
|
||||
- 10
|
||||
- 12
|
||||
- 14
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* @fileoverview A rule to ensure consistent quotes used in jsx syntax.
|
||||
* @author Mathias Schreck <https://github.com/lo1tuma>
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constants
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const QUOTE_SETTINGS = {
|
||||
"prefer-double": {
|
||||
quote: '"',
|
||||
description: "singlequote",
|
||||
convert(str) {
|
||||
return str.replace(/'/gu, '"');
|
||||
},
|
||||
},
|
||||
"prefer-single": {
|
||||
quote: "'",
|
||||
description: "doublequote",
|
||||
convert(str) {
|
||||
return str.replace(/"/gu, "'");
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: {
|
||||
message: "Formatting rules are being moved out of ESLint core.",
|
||||
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
||||
deprecatedSince: "8.53.0",
|
||||
availableUntil: "10.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin-js",
|
||||
url: "https://eslint.style/packages/js",
|
||||
},
|
||||
rule: {
|
||||
name: "jsx-quotes",
|
||||
url: "https://eslint.style/rules/js/jsx-quotes",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Enforce the consistent use of either double or single quotes in JSX attributes",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/jsx-quotes",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
enum: ["prefer-single", "prefer-double"],
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpected: "Unexpected usage of {{description}}.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const quoteOption = context.options[0] || "prefer-double",
|
||||
setting = QUOTE_SETTINGS[quoteOption];
|
||||
|
||||
/**
|
||||
* Checks if the given string literal node uses the expected quotes
|
||||
* @param {ASTNode} node A string literal node.
|
||||
* @returns {boolean} Whether or not the string literal used the expected quotes.
|
||||
* @public
|
||||
*/
|
||||
function usesExpectedQuotes(node) {
|
||||
return (
|
||||
node.value.includes(setting.quote) ||
|
||||
astUtils.isSurroundedBy(node.raw, setting.quote)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
JSXAttribute(node) {
|
||||
const attributeValue = node.value;
|
||||
|
||||
if (
|
||||
attributeValue &&
|
||||
astUtils.isStringLiteral(attributeValue) &&
|
||||
!usesExpectedQuotes(attributeValue)
|
||||
) {
|
||||
context.report({
|
||||
node: attributeValue,
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
description: setting.description,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(
|
||||
attributeValue,
|
||||
setting.convert(attributeValue.raw),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["_readOnlyError","name","TypeError"],"sources":["../../src/helpers/readOnlyError.ts"],"sourcesContent":["/* @minVersion 7.0.0-beta.0 */\n\nexport default function _readOnlyError(name: string) {\n throw new TypeError('\"' + name + '\" is read-only');\n}\n"],"mappings":";;;;;;AAEe,SAASA,cAAcA,CAACC,IAAY,EAAE;EACnD,MAAM,IAAIC,SAAS,CAAC,GAAG,GAAGD,IAAI,GAAG,gBAAgB,CAAC;AACpD","ignoreList":[]}
|
||||
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = _objectWithoutPropertiesLoose;
|
||||
function _objectWithoutPropertiesLoose(source, excluded) {
|
||||
if (source == null) return {};
|
||||
var target = {};
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
if (excluded.indexOf(key) !== -1) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=objectWithoutPropertiesLoose.js.map
|
||||
@@ -0,0 +1,53 @@
|
||||
# github-from-package
|
||||
|
||||
return the github url from a package.json file
|
||||
|
||||
[](http://travis-ci.org/substack/github-from-package)
|
||||
|
||||
# example
|
||||
|
||||
For the `./package.json` file:
|
||||
|
||||
``` json
|
||||
{
|
||||
"name": "beep-boop",
|
||||
"version": "1.2.3",
|
||||
"repository" : {
|
||||
"type" : "git",
|
||||
"url": "git@github.com:substack/beep-boop.git"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
``` js
|
||||
var github = require('github-from-package');
|
||||
var url = github(require('./package.json'));
|
||||
console.log(url);
|
||||
```
|
||||
|
||||
```
|
||||
https://github.com/substack/beep-boop
|
||||
```
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var github = require('github-from-package')
|
||||
```
|
||||
|
||||
## var url = github(pkg)
|
||||
|
||||
Return the most likely github url from the package.json contents `pkg`. If no
|
||||
github url can be determined, return `undefined`.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install github-from-package
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,44 @@
|
||||
export declare const HOLE = -1;
|
||||
export declare const NAN = -2;
|
||||
export declare const NEGATIVE_INFINITY = -3;
|
||||
export declare const NEGATIVE_ZERO = -4;
|
||||
export declare const NULL = -5;
|
||||
export declare const POSITIVE_INFINITY = -6;
|
||||
export declare const UNDEFINED = -7;
|
||||
export declare const TYPE_BIGINT = "B";
|
||||
export declare const TYPE_DATE = "D";
|
||||
export declare const TYPE_ERROR = "E";
|
||||
export declare const TYPE_MAP = "M";
|
||||
export declare const TYPE_NULL_OBJECT = "N";
|
||||
export declare const TYPE_PROMISE = "P";
|
||||
export declare const TYPE_REGEXP = "R";
|
||||
export declare const TYPE_SET = "S";
|
||||
export declare const TYPE_SYMBOL = "Y";
|
||||
export declare const TYPE_URL = "U";
|
||||
export declare const TYPE_PREVIOUS_RESOLVED = "Z";
|
||||
export type DecodePlugin = (type: string, ...data: unknown[]) => {
|
||||
value: unknown;
|
||||
} | false | null | undefined;
|
||||
export type EncodePlugin = (value: unknown) => [string, ...unknown[]] | false | null | undefined;
|
||||
export interface ThisDecode {
|
||||
values: unknown[];
|
||||
hydrated: unknown[];
|
||||
deferred: Record<number, Deferred<unknown>>;
|
||||
plugins?: DecodePlugin[];
|
||||
}
|
||||
export interface ThisEncode {
|
||||
index: number;
|
||||
indices: Map<unknown, number>;
|
||||
stringified: string[];
|
||||
deferred: Record<number, Promise<unknown>>;
|
||||
plugins?: EncodePlugin[];
|
||||
postPlugins?: EncodePlugin[];
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
export declare class Deferred<T = unknown> {
|
||||
promise: Promise<T>;
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason: unknown) => void;
|
||||
constructor();
|
||||
}
|
||||
export declare function createLineSplittingTransform(): TransformStream<any, any>;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = stringTemplate;
|
||||
var _options = require("./options.js");
|
||||
var _parse = require("./parse.js");
|
||||
var _populate = require("./populate.js");
|
||||
function stringTemplate(formatter, code, opts) {
|
||||
code = formatter.code(code);
|
||||
let metadata;
|
||||
return arg => {
|
||||
const replacements = (0, _options.normalizeReplacements)(arg);
|
||||
if (!metadata) metadata = (0, _parse.default)(formatter, code, opts);
|
||||
return formatter.unwrap((0, _populate.default)(metadata, replacements));
|
||||
};
|
||||
}
|
||||
|
||||
//# sourceMappingURL=string.js.map
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const { CLIEngine } = require("./cli-engine");
|
||||
|
||||
module.exports = {
|
||||
CLIEngine,
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"K D E F A B mC"},B:{"2":"0 9 C L M G N O P Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I"},C:{"2":"nC LC J PB K D qC rC","132":"1 2 3 4 5 6 7 8 E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T","450":"0 9 U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC"},D:{"2":"0 1 2 3 4 5 6 7 8 9 J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","66":"eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB"},E:{"2":"J PB K D E F A B C L M G sC SC tC uC vC wC TC FC GC xC yC zC UC VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC 3C"},F:{"2":"0 1 2 3 4 5 6 7 8 F B C G N O P QB RB SB TB UB VB WB XB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 4C 5C 6C 7C FC kC 8C GC","66":"YB ZB aB bB cB dB eB fB gB hB iB jB"},G:{"2":"E SC 9C lC AD BD CD DD ED FD GD HD ID JD KD LD MD ND OD PD QD RD SD UC VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC"},H:{"2":"WD"},I:{"2":"LC J I XD YD ZD aD lC bD cD"},J:{"2":"D A"},K:{"2":"A B C H FC kC GC"},L:{"2":"I"},M:{"450":"EC"},N:{"2":"A B"},O:{"2":"HC"},P:{"2":"1 2 3 4 5 6 7 8 J dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD"},Q:{"2":"oD"},R:{"2":"pD"},S:{"2":"qD rD"}},B:7,C:"Context menu item (menuitem element)",D:true};
|
||||
@@ -0,0 +1,716 @@
|
||||
// Generated by LiveScript 1.6.0
|
||||
var each, map, compact, filter, reject, remove, partition, find, head, first, tail, last, initial, empty, reverse, unique, uniqueBy, fold, foldl, fold1, foldl1, foldr, foldr1, unfoldr, concat, concatMap, flatten, difference, intersection, union, countBy, groupBy, andList, orList, any, all, sort, sortWith, sortBy, sum, product, mean, average, maximum, minimum, maximumBy, minimumBy, scan, scanl, scan1, scanl1, scanr, scanr1, slice, take, drop, splitAt, takeWhile, dropWhile, span, breakList, zip, zipWith, zipAll, zipAllWith, at, elemIndex, elemIndices, findIndex, findIndices, toString$ = {}.toString;
|
||||
each = curry$(function(f, xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
f(x);
|
||||
}
|
||||
return xs;
|
||||
});
|
||||
map = curry$(function(f, xs){
|
||||
var i$, len$, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
results$.push(f(x));
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
compact = function(xs){
|
||||
var i$, len$, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (x) {
|
||||
results$.push(x);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
};
|
||||
filter = curry$(function(f, xs){
|
||||
var i$, len$, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (f(x)) {
|
||||
results$.push(x);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
reject = curry$(function(f, xs){
|
||||
var i$, len$, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (!f(x)) {
|
||||
results$.push(x);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
remove = curry$(function(el, xs){
|
||||
var i, x$;
|
||||
i = elemIndex(el, xs);
|
||||
x$ = xs.slice();
|
||||
if (i != null) {
|
||||
x$.splice(i, 1);
|
||||
}
|
||||
return x$;
|
||||
});
|
||||
partition = curry$(function(f, xs){
|
||||
var passed, failed, i$, len$, x;
|
||||
passed = [];
|
||||
failed = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
(f(x) ? passed : failed).push(x);
|
||||
}
|
||||
return [passed, failed];
|
||||
});
|
||||
find = curry$(function(f, xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (f(x)) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
});
|
||||
head = first = function(xs){
|
||||
return xs[0];
|
||||
};
|
||||
tail = function(xs){
|
||||
if (!xs.length) {
|
||||
return;
|
||||
}
|
||||
return xs.slice(1);
|
||||
};
|
||||
last = function(xs){
|
||||
return xs[xs.length - 1];
|
||||
};
|
||||
initial = function(xs){
|
||||
if (!xs.length) {
|
||||
return;
|
||||
}
|
||||
return xs.slice(0, -1);
|
||||
};
|
||||
empty = function(xs){
|
||||
return !xs.length;
|
||||
};
|
||||
reverse = function(xs){
|
||||
return xs.concat().reverse();
|
||||
};
|
||||
unique = function(xs){
|
||||
var result, i$, len$, x;
|
||||
result = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (!in$(x, result)) {
|
||||
result.push(x);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
uniqueBy = curry$(function(f, xs){
|
||||
var seen, i$, len$, x, val, results$ = [];
|
||||
seen = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
val = f(x);
|
||||
if (in$(val, seen)) {
|
||||
continue;
|
||||
}
|
||||
seen.push(val);
|
||||
results$.push(x);
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
fold = foldl = curry$(function(f, memo, xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
memo = f(memo, x);
|
||||
}
|
||||
return memo;
|
||||
});
|
||||
fold1 = foldl1 = curry$(function(f, xs){
|
||||
return fold(f, xs[0], xs.slice(1));
|
||||
});
|
||||
foldr = curry$(function(f, memo, xs){
|
||||
var i$, x;
|
||||
for (i$ = xs.length - 1; i$ >= 0; --i$) {
|
||||
x = xs[i$];
|
||||
memo = f(x, memo);
|
||||
}
|
||||
return memo;
|
||||
});
|
||||
foldr1 = curry$(function(f, xs){
|
||||
return foldr(f, xs[xs.length - 1], xs.slice(0, -1));
|
||||
});
|
||||
unfoldr = curry$(function(f, b){
|
||||
var result, x, that;
|
||||
result = [];
|
||||
x = b;
|
||||
while ((that = f(x)) != null) {
|
||||
result.push(that[0]);
|
||||
x = that[1];
|
||||
}
|
||||
return result;
|
||||
});
|
||||
concat = function(xss){
|
||||
return [].concat.apply([], xss);
|
||||
};
|
||||
concatMap = curry$(function(f, xs){
|
||||
var x;
|
||||
return [].concat.apply([], (function(){
|
||||
var i$, ref$, len$, results$ = [];
|
||||
for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
results$.push(f(x));
|
||||
}
|
||||
return results$;
|
||||
}()));
|
||||
});
|
||||
flatten = function(xs){
|
||||
var x;
|
||||
return [].concat.apply([], (function(){
|
||||
var i$, ref$, len$, results$ = [];
|
||||
for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
if (toString$.call(x).slice(8, -1) === 'Array') {
|
||||
results$.push(flatten(x));
|
||||
} else {
|
||||
results$.push(x);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
}()));
|
||||
};
|
||||
difference = function(xs){
|
||||
var yss, res$, i$, to$, results, len$, x, j$, len1$, ys;
|
||||
res$ = [];
|
||||
for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
|
||||
res$.push(arguments[i$]);
|
||||
}
|
||||
yss = res$;
|
||||
results = [];
|
||||
outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) {
|
||||
ys = yss[j$];
|
||||
if (in$(x, ys)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
results.push(x);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
intersection = function(xs){
|
||||
var yss, res$, i$, to$, results, len$, x, j$, len1$, ys;
|
||||
res$ = [];
|
||||
for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
|
||||
res$.push(arguments[i$]);
|
||||
}
|
||||
yss = res$;
|
||||
results = [];
|
||||
outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) {
|
||||
ys = yss[j$];
|
||||
if (!in$(x, ys)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
results.push(x);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
union = function(){
|
||||
var xss, res$, i$, to$, results, len$, xs, j$, len1$, x;
|
||||
res$ = [];
|
||||
for (i$ = 0, to$ = arguments.length; i$ < to$; ++i$) {
|
||||
res$.push(arguments[i$]);
|
||||
}
|
||||
xss = res$;
|
||||
results = [];
|
||||
for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
|
||||
xs = xss[i$];
|
||||
for (j$ = 0, len1$ = xs.length; j$ < len1$; ++j$) {
|
||||
x = xs[j$];
|
||||
if (!in$(x, results)) {
|
||||
results.push(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
countBy = curry$(function(f, xs){
|
||||
var results, i$, len$, x, key;
|
||||
results = {};
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
key = f(x);
|
||||
if (key in results) {
|
||||
results[key] += 1;
|
||||
} else {
|
||||
results[key] = 1;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
});
|
||||
groupBy = curry$(function(f, xs){
|
||||
var results, i$, len$, x, key;
|
||||
results = {};
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
key = f(x);
|
||||
if (key in results) {
|
||||
results[key].push(x);
|
||||
} else {
|
||||
results[key] = [x];
|
||||
}
|
||||
}
|
||||
return results;
|
||||
});
|
||||
andList = function(xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (!x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
orList = function(xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (x) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
any = curry$(function(f, xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (f(x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
all = curry$(function(f, xs){
|
||||
var i$, len$, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
if (!f(x)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
sort = function(xs){
|
||||
return xs.concat().sort(function(x, y){
|
||||
if (x > y) {
|
||||
return 1;
|
||||
} else if (x < y) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
sortWith = curry$(function(f, xs){
|
||||
return xs.concat().sort(f);
|
||||
});
|
||||
sortBy = curry$(function(f, xs){
|
||||
return xs.concat().sort(function(x, y){
|
||||
if (f(x) > f(y)) {
|
||||
return 1;
|
||||
} else if (f(x) < f(y)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
sum = function(xs){
|
||||
var result, i$, len$, x;
|
||||
result = 0;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
result += x;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
product = function(xs){
|
||||
var result, i$, len$, x;
|
||||
result = 1;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
result *= x;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
mean = average = function(xs){
|
||||
var sum, i$, len$, x;
|
||||
sum = 0;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
x = xs[i$];
|
||||
sum += x;
|
||||
}
|
||||
return sum / xs.length;
|
||||
};
|
||||
maximum = function(xs){
|
||||
var max, i$, ref$, len$, x;
|
||||
max = xs[0];
|
||||
for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
if (x > max) {
|
||||
max = x;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
};
|
||||
minimum = function(xs){
|
||||
var min, i$, ref$, len$, x;
|
||||
min = xs[0];
|
||||
for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
if (x < min) {
|
||||
min = x;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
};
|
||||
maximumBy = curry$(function(f, xs){
|
||||
var max, i$, ref$, len$, x;
|
||||
max = xs[0];
|
||||
for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
if (f(x) > f(max)) {
|
||||
max = x;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
});
|
||||
minimumBy = curry$(function(f, xs){
|
||||
var min, i$, ref$, len$, x;
|
||||
min = xs[0];
|
||||
for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
if (f(x) < f(min)) {
|
||||
min = x;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
});
|
||||
scan = scanl = curry$(function(f, memo, xs){
|
||||
var last, x;
|
||||
last = memo;
|
||||
return [memo].concat((function(){
|
||||
var i$, ref$, len$, results$ = [];
|
||||
for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) {
|
||||
x = ref$[i$];
|
||||
results$.push(last = f(last, x));
|
||||
}
|
||||
return results$;
|
||||
}()));
|
||||
});
|
||||
scan1 = scanl1 = curry$(function(f, xs){
|
||||
if (!xs.length) {
|
||||
return;
|
||||
}
|
||||
return scan(f, xs[0], xs.slice(1));
|
||||
});
|
||||
scanr = curry$(function(f, memo, xs){
|
||||
xs = xs.concat().reverse();
|
||||
return scan(f, memo, xs).reverse();
|
||||
});
|
||||
scanr1 = curry$(function(f, xs){
|
||||
if (!xs.length) {
|
||||
return;
|
||||
}
|
||||
xs = xs.concat().reverse();
|
||||
return scan(f, xs[0], xs.slice(1)).reverse();
|
||||
});
|
||||
slice = curry$(function(x, y, xs){
|
||||
return xs.slice(x, y);
|
||||
});
|
||||
take = curry$(function(n, xs){
|
||||
if (n <= 0) {
|
||||
return xs.slice(0, 0);
|
||||
} else {
|
||||
return xs.slice(0, n);
|
||||
}
|
||||
});
|
||||
drop = curry$(function(n, xs){
|
||||
if (n <= 0) {
|
||||
return xs;
|
||||
} else {
|
||||
return xs.slice(n);
|
||||
}
|
||||
});
|
||||
splitAt = curry$(function(n, xs){
|
||||
return [take(n, xs), drop(n, xs)];
|
||||
});
|
||||
takeWhile = curry$(function(p, xs){
|
||||
var len, i;
|
||||
len = xs.length;
|
||||
if (!len) {
|
||||
return xs;
|
||||
}
|
||||
i = 0;
|
||||
while (i < len && p(xs[i])) {
|
||||
i += 1;
|
||||
}
|
||||
return xs.slice(0, i);
|
||||
});
|
||||
dropWhile = curry$(function(p, xs){
|
||||
var len, i;
|
||||
len = xs.length;
|
||||
if (!len) {
|
||||
return xs;
|
||||
}
|
||||
i = 0;
|
||||
while (i < len && p(xs[i])) {
|
||||
i += 1;
|
||||
}
|
||||
return xs.slice(i);
|
||||
});
|
||||
span = curry$(function(p, xs){
|
||||
return [takeWhile(p, xs), dropWhile(p, xs)];
|
||||
});
|
||||
breakList = curry$(function(p, xs){
|
||||
return span(compose$(p, not$), xs);
|
||||
});
|
||||
zip = curry$(function(xs, ys){
|
||||
var result, len, i$, len$, i, x;
|
||||
result = [];
|
||||
len = ys.length;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (i === len) {
|
||||
break;
|
||||
}
|
||||
result.push([x, ys[i]]);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
zipWith = curry$(function(f, xs, ys){
|
||||
var result, len, i$, len$, i, x;
|
||||
result = [];
|
||||
len = ys.length;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (i === len) {
|
||||
break;
|
||||
}
|
||||
result.push(f(x, ys[i]));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
zipAll = function(){
|
||||
var xss, res$, i$, to$, minLength, len$, xs, ref$, i, lresult$, j$, results$ = [];
|
||||
res$ = [];
|
||||
for (i$ = 0, to$ = arguments.length; i$ < to$; ++i$) {
|
||||
res$.push(arguments[i$]);
|
||||
}
|
||||
xss = res$;
|
||||
minLength = undefined;
|
||||
for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
|
||||
xs = xss[i$];
|
||||
minLength <= (ref$ = xs.length) || (minLength = ref$);
|
||||
}
|
||||
for (i$ = 0; i$ < minLength; ++i$) {
|
||||
i = i$;
|
||||
lresult$ = [];
|
||||
for (j$ = 0, len$ = xss.length; j$ < len$; ++j$) {
|
||||
xs = xss[j$];
|
||||
lresult$.push(xs[i]);
|
||||
}
|
||||
results$.push(lresult$);
|
||||
}
|
||||
return results$;
|
||||
};
|
||||
zipAllWith = function(f){
|
||||
var xss, res$, i$, to$, minLength, len$, xs, ref$, i, results$ = [];
|
||||
res$ = [];
|
||||
for (i$ = 1, to$ = arguments.length; i$ < to$; ++i$) {
|
||||
res$.push(arguments[i$]);
|
||||
}
|
||||
xss = res$;
|
||||
minLength = undefined;
|
||||
for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) {
|
||||
xs = xss[i$];
|
||||
minLength <= (ref$ = xs.length) || (minLength = ref$);
|
||||
}
|
||||
for (i$ = 0; i$ < minLength; ++i$) {
|
||||
i = i$;
|
||||
results$.push(f.apply(null, (fn$())));
|
||||
}
|
||||
return results$;
|
||||
function fn$(){
|
||||
var i$, ref$, len$, results$ = [];
|
||||
for (i$ = 0, len$ = (ref$ = xss).length; i$ < len$; ++i$) {
|
||||
xs = ref$[i$];
|
||||
results$.push(xs[i]);
|
||||
}
|
||||
return results$;
|
||||
}
|
||||
};
|
||||
at = curry$(function(n, xs){
|
||||
if (n < 0) {
|
||||
return xs[xs.length + n];
|
||||
} else {
|
||||
return xs[n];
|
||||
}
|
||||
});
|
||||
elemIndex = curry$(function(el, xs){
|
||||
var i$, len$, i, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (x === el) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
});
|
||||
elemIndices = curry$(function(el, xs){
|
||||
var i$, len$, i, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (x === el) {
|
||||
results$.push(i);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
findIndex = curry$(function(f, xs){
|
||||
var i$, len$, i, x;
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (f(x)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
});
|
||||
findIndices = curry$(function(f, xs){
|
||||
var i$, len$, i, x, results$ = [];
|
||||
for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) {
|
||||
i = i$;
|
||||
x = xs[i$];
|
||||
if (f(x)) {
|
||||
results$.push(i);
|
||||
}
|
||||
}
|
||||
return results$;
|
||||
});
|
||||
module.exports = {
|
||||
each: each,
|
||||
map: map,
|
||||
filter: filter,
|
||||
compact: compact,
|
||||
reject: reject,
|
||||
remove: remove,
|
||||
partition: partition,
|
||||
find: find,
|
||||
head: head,
|
||||
first: first,
|
||||
tail: tail,
|
||||
last: last,
|
||||
initial: initial,
|
||||
empty: empty,
|
||||
reverse: reverse,
|
||||
difference: difference,
|
||||
intersection: intersection,
|
||||
union: union,
|
||||
countBy: countBy,
|
||||
groupBy: groupBy,
|
||||
fold: fold,
|
||||
fold1: fold1,
|
||||
foldl: foldl,
|
||||
foldl1: foldl1,
|
||||
foldr: foldr,
|
||||
foldr1: foldr1,
|
||||
unfoldr: unfoldr,
|
||||
andList: andList,
|
||||
orList: orList,
|
||||
any: any,
|
||||
all: all,
|
||||
unique: unique,
|
||||
uniqueBy: uniqueBy,
|
||||
sort: sort,
|
||||
sortWith: sortWith,
|
||||
sortBy: sortBy,
|
||||
sum: sum,
|
||||
product: product,
|
||||
mean: mean,
|
||||
average: average,
|
||||
concat: concat,
|
||||
concatMap: concatMap,
|
||||
flatten: flatten,
|
||||
maximum: maximum,
|
||||
minimum: minimum,
|
||||
maximumBy: maximumBy,
|
||||
minimumBy: minimumBy,
|
||||
scan: scan,
|
||||
scan1: scan1,
|
||||
scanl: scanl,
|
||||
scanl1: scanl1,
|
||||
scanr: scanr,
|
||||
scanr1: scanr1,
|
||||
slice: slice,
|
||||
take: take,
|
||||
drop: drop,
|
||||
splitAt: splitAt,
|
||||
takeWhile: takeWhile,
|
||||
dropWhile: dropWhile,
|
||||
span: span,
|
||||
breakList: breakList,
|
||||
zip: zip,
|
||||
zipWith: zipWith,
|
||||
zipAll: zipAll,
|
||||
zipAllWith: zipAllWith,
|
||||
at: at,
|
||||
elemIndex: elemIndex,
|
||||
elemIndices: elemIndices,
|
||||
findIndex: findIndex,
|
||||
findIndices: findIndices
|
||||
};
|
||||
function curry$(f, bound){
|
||||
var context,
|
||||
_curry = function(args) {
|
||||
return f.length > 1 ? function(){
|
||||
var params = args ? args.concat() : [];
|
||||
context = bound ? context || this : this;
|
||||
return params.push.apply(params, arguments) <
|
||||
f.length && arguments.length ?
|
||||
_curry.call(context, params) : f.apply(context, params);
|
||||
} : f;
|
||||
};
|
||||
return _curry();
|
||||
}
|
||||
function in$(x, xs){
|
||||
var i = -1, l = xs.length >>> 0;
|
||||
while (++i < l) if (x === xs[i]) return true;
|
||||
return false;
|
||||
}
|
||||
function compose$() {
|
||||
var functions = arguments;
|
||||
return function() {
|
||||
var i, result;
|
||||
result = functions[0].apply(this, arguments);
|
||||
for (i = 1; i < functions.length; ++i) {
|
||||
result = functions[i](result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
function not$(x){ return !x; }
|
||||
@@ -0,0 +1,84 @@
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
|
||||
function find(iter, tar, key) {
|
||||
for (key of iter.keys()) {
|
||||
if (dequal(key, tar)) return key;
|
||||
}
|
||||
}
|
||||
|
||||
export function dequal(foo, bar) {
|
||||
var ctor, len, tmp;
|
||||
if (foo === bar) return true;
|
||||
|
||||
if (foo && bar && (ctor=foo.constructor) === bar.constructor) {
|
||||
if (ctor === Date) return foo.getTime() === bar.getTime();
|
||||
if (ctor === RegExp) return foo.toString() === bar.toString();
|
||||
|
||||
if (ctor === Array) {
|
||||
if ((len=foo.length) === bar.length) {
|
||||
while (len-- && dequal(foo[len], bar[len]));
|
||||
}
|
||||
return len === -1;
|
||||
}
|
||||
|
||||
if (ctor === Set) {
|
||||
if (foo.size !== bar.size) {
|
||||
return false;
|
||||
}
|
||||
for (len of foo) {
|
||||
tmp = len;
|
||||
if (tmp && typeof tmp === 'object') {
|
||||
tmp = find(bar, tmp);
|
||||
if (!tmp) return false;
|
||||
}
|
||||
if (!bar.has(tmp)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ctor === Map) {
|
||||
if (foo.size !== bar.size) {
|
||||
return false;
|
||||
}
|
||||
for (len of foo) {
|
||||
tmp = len[0];
|
||||
if (tmp && typeof tmp === 'object') {
|
||||
tmp = find(bar, tmp);
|
||||
if (!tmp) return false;
|
||||
}
|
||||
if (!dequal(len[1], bar.get(tmp))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ctor === ArrayBuffer) {
|
||||
foo = new Uint8Array(foo);
|
||||
bar = new Uint8Array(bar);
|
||||
} else if (ctor === DataView) {
|
||||
if ((len=foo.byteLength) === bar.byteLength) {
|
||||
while (len-- && foo.getInt8(len) === bar.getInt8(len));
|
||||
}
|
||||
return len === -1;
|
||||
}
|
||||
|
||||
if (ArrayBuffer.isView(foo)) {
|
||||
if ((len=foo.byteLength) === bar.byteLength) {
|
||||
while (len-- && foo[len] === bar[len]);
|
||||
}
|
||||
return len === -1;
|
||||
}
|
||||
|
||||
if (!ctor || typeof foo === 'object') {
|
||||
len = 0;
|
||||
for (ctor in foo) {
|
||||
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
||||
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
||||
}
|
||||
return Object.keys(bar).length === len;
|
||||
}
|
||||
}
|
||||
|
||||
return foo !== foo && bar !== bar;
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* @fileoverview Rule to disallow useless backreferences in regular expressions
|
||||
* @author Milos Djermanovic
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const {
|
||||
CALL,
|
||||
CONSTRUCT,
|
||||
ReferenceTracker,
|
||||
getStringIfConstant,
|
||||
} = require("@eslint-community/eslint-utils");
|
||||
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const parser = new RegExpParser();
|
||||
|
||||
/**
|
||||
* Finds the path from the given `regexpp` AST node to the root node.
|
||||
* @param {regexpp.Node} node Node.
|
||||
* @returns {regexpp.Node[]} Array that starts with the given node and ends with the root node.
|
||||
*/
|
||||
function getPathToRoot(node) {
|
||||
const path = [];
|
||||
let current = node;
|
||||
|
||||
do {
|
||||
path.push(current);
|
||||
current = current.parent;
|
||||
} while (current);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given `regexpp` AST node is a lookaround node.
|
||||
* @param {regexpp.Node} node Node.
|
||||
* @returns {boolean} `true` if it is a lookaround node.
|
||||
*/
|
||||
function isLookaround(node) {
|
||||
return (
|
||||
node.type === "Assertion" &&
|
||||
(node.kind === "lookahead" || node.kind === "lookbehind")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given `regexpp` AST node is a negative lookaround node.
|
||||
* @param {regexpp.Node} node Node.
|
||||
* @returns {boolean} `true` if it is a negative lookaround node.
|
||||
*/
|
||||
function isNegativeLookaround(node) {
|
||||
return isLookaround(node) && node.negate;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow useless backreferences in regular expressions",
|
||||
recommended: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-useless-backreference",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} from within that group.",
|
||||
forward:
|
||||
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears later in the pattern.",
|
||||
backward:
|
||||
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears before in the same lookbehind.",
|
||||
disjunctive:
|
||||
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in another alternative.",
|
||||
intoNegativeLookaround:
|
||||
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in a negative lookaround.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Checks and reports useless backreferences in the given regular expression.
|
||||
* @param {ASTNode} node Node that represents regular expression. A regex literal or RegExp constructor call.
|
||||
* @param {string} pattern Regular expression pattern.
|
||||
* @param {string} flags Regular expression flags.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkRegex(node, pattern, flags) {
|
||||
let regExpAST;
|
||||
|
||||
try {
|
||||
regExpAST = parser.parsePattern(pattern, 0, pattern.length, {
|
||||
unicode: flags.includes("u"),
|
||||
unicodeSets: flags.includes("v"),
|
||||
});
|
||||
} catch {
|
||||
// Ignore regular expressions with syntax errors
|
||||
return;
|
||||
}
|
||||
|
||||
visitRegExpAST(regExpAST, {
|
||||
onBackreferenceEnter(bref) {
|
||||
const groups = [bref.resolved].flat(),
|
||||
brefPath = getPathToRoot(bref);
|
||||
|
||||
const problems = groups.map(group => {
|
||||
const groupPath = getPathToRoot(group);
|
||||
|
||||
if (brefPath.includes(group)) {
|
||||
// group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match.
|
||||
return {
|
||||
messageId: "nested",
|
||||
group,
|
||||
};
|
||||
}
|
||||
|
||||
// Start from the root to find the lowest common ancestor.
|
||||
let i = brefPath.length - 1,
|
||||
j = groupPath.length - 1;
|
||||
|
||||
do {
|
||||
i--;
|
||||
j--;
|
||||
} while (brefPath[i] === groupPath[j]);
|
||||
|
||||
const indexOfLowestCommonAncestor = j + 1,
|
||||
groupCut = groupPath.slice(
|
||||
0,
|
||||
indexOfLowestCommonAncestor,
|
||||
),
|
||||
commonPath = groupPath.slice(
|
||||
indexOfLowestCommonAncestor,
|
||||
),
|
||||
lowestCommonLookaround =
|
||||
commonPath.find(isLookaround),
|
||||
isMatchingBackward =
|
||||
lowestCommonLookaround &&
|
||||
lowestCommonLookaround.kind === "lookbehind";
|
||||
|
||||
if (groupCut.at(-1).type === "Alternative") {
|
||||
// group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.
|
||||
return {
|
||||
messageId: "disjunctive",
|
||||
group,
|
||||
};
|
||||
}
|
||||
if (!isMatchingBackward && bref.end <= group.start) {
|
||||
// bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match.
|
||||
return {
|
||||
messageId: "forward",
|
||||
group,
|
||||
};
|
||||
}
|
||||
if (isMatchingBackward && group.end <= bref.start) {
|
||||
// the opposite of the previous when the regex is matching backward in a lookbehind context.
|
||||
return {
|
||||
messageId: "backward",
|
||||
group,
|
||||
};
|
||||
}
|
||||
if (groupCut.some(isNegativeLookaround)) {
|
||||
// group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match.
|
||||
return {
|
||||
messageId: "intoNegativeLookaround",
|
||||
group,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
if (
|
||||
problems.length === 0 ||
|
||||
problems.some(problem => !problem)
|
||||
) {
|
||||
// If there are no problems or no problems with any group then do not report it.
|
||||
return;
|
||||
}
|
||||
|
||||
let problemsToReport;
|
||||
|
||||
// Gets problems that appear in the same disjunction.
|
||||
const problemsInSameDisjunction = problems.filter(
|
||||
problem => problem.messageId !== "disjunctive",
|
||||
);
|
||||
|
||||
if (problemsInSameDisjunction.length) {
|
||||
// Only report problems that appear in the same disjunction.
|
||||
problemsToReport = problemsInSameDisjunction;
|
||||
} else {
|
||||
// If all groups appear in different disjunctions, report it.
|
||||
problemsToReport = problems;
|
||||
}
|
||||
|
||||
const [{ messageId, group }, ...other] = problemsToReport;
|
||||
let otherGroups = "";
|
||||
|
||||
if (other.length === 1) {
|
||||
otherGroups = " and another group";
|
||||
} else if (other.length > 1) {
|
||||
otherGroups = ` and other ${other.length} groups`;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
messageId,
|
||||
data: {
|
||||
bref: bref.raw,
|
||||
group: group.raw,
|
||||
otherGroups,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
"Literal[regex]"(node) {
|
||||
const { pattern, flags } = node.regex;
|
||||
|
||||
checkRegex(node, pattern, flags);
|
||||
},
|
||||
Program(node) {
|
||||
const scope = sourceCode.getScope(node),
|
||||
tracker = new ReferenceTracker(scope),
|
||||
traceMap = {
|
||||
RegExp: {
|
||||
[CALL]: true,
|
||||
[CONSTRUCT]: true,
|
||||
},
|
||||
};
|
||||
|
||||
for (const { node: refNode } of tracker.iterateGlobalReferences(
|
||||
traceMap,
|
||||
)) {
|
||||
const [patternNode, flagsNode] = refNode.arguments,
|
||||
pattern = getStringIfConstant(patternNode, scope),
|
||||
flags = getStringIfConstant(flagsNode, scope);
|
||||
|
||||
if (typeof pattern === "string") {
|
||||
checkRegex(refNode, pattern, flags || "");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.4
|
||||
- 0.6
|
||||
Reference in New Issue
Block a user