update
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"name": "ajv",
|
||||
"version": "6.12.6",
|
||||
"description": "Another JSON Schema Validator",
|
||||
"main": "lib/ajv.js",
|
||||
"typings": "lib/ajv.d.ts",
|
||||
"files": [
|
||||
"lib/",
|
||||
"dist/",
|
||||
"scripts/",
|
||||
"LICENSE",
|
||||
".tonic_example.js"
|
||||
],
|
||||
"scripts": {
|
||||
"eslint": "eslint lib/{compile/,}*.js spec/{**/,}*.js scripts --ignore-pattern spec/JSON-Schema-Test-Suite",
|
||||
"jshint": "jshint lib/{compile/,}*.js",
|
||||
"lint": "npm run jshint && npm run eslint",
|
||||
"test-spec": "mocha spec/{**/,}*.spec.js -R spec",
|
||||
"test-fast": "AJV_FAST_TEST=true npm run test-spec",
|
||||
"test-debug": "npm run test-spec -- --inspect-brk",
|
||||
"test-cov": "nyc npm run test-spec",
|
||||
"test-ts": "tsc --target ES5 --noImplicitAny --noEmit spec/typescript/index.ts",
|
||||
"bundle": "del-cli dist && node ./scripts/bundle.js . Ajv pure_getters",
|
||||
"bundle-beautify": "node ./scripts/bundle.js js-beautify",
|
||||
"build": "del-cli lib/dotjs/*.js \"!lib/dotjs/index.js\" && node scripts/compile-dots.js",
|
||||
"test-karma": "karma start",
|
||||
"test-browser": "del-cli .browser && npm run bundle && scripts/prepare-tests && npm run test-karma",
|
||||
"test-all": "npm run test-cov && if-node-version 10 npm run test-browser",
|
||||
"test": "npm run lint && npm run build && npm run test-all",
|
||||
"prepublish": "npm run build && npm run bundle",
|
||||
"watch": "watch \"npm run build\" ./lib/dot"
|
||||
},
|
||||
"nyc": {
|
||||
"exclude": [
|
||||
"**/spec/**",
|
||||
"node_modules"
|
||||
],
|
||||
"reporter": [
|
||||
"lcov",
|
||||
"text-summary"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ajv-validator/ajv.git"
|
||||
},
|
||||
"keywords": [
|
||||
"JSON",
|
||||
"schema",
|
||||
"validator",
|
||||
"validation",
|
||||
"jsonschema",
|
||||
"json-schema",
|
||||
"json-schema-validator",
|
||||
"json-schema-validation"
|
||||
],
|
||||
"author": "Evgeny Poberezkin",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ajv-validator/ajv/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ajv-validator/ajv",
|
||||
"tonicExampleFilename": ".tonic_example.js",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv-async": "^1.0.0",
|
||||
"bluebird": "^3.5.3",
|
||||
"brfs": "^2.0.0",
|
||||
"browserify": "^16.2.0",
|
||||
"chai": "^4.0.1",
|
||||
"coveralls": "^3.0.1",
|
||||
"del-cli": "^3.0.0",
|
||||
"dot": "^1.0.3",
|
||||
"eslint": "^7.3.1",
|
||||
"gh-pages-generator": "^0.2.3",
|
||||
"glob": "^7.0.0",
|
||||
"if-node-version": "^1.0.0",
|
||||
"js-beautify": "^1.7.3",
|
||||
"jshint": "^2.10.2",
|
||||
"json-schema-test": "^2.0.0",
|
||||
"karma": "^5.0.0",
|
||||
"karma-chrome-launcher": "^3.0.0",
|
||||
"karma-mocha": "^2.0.0",
|
||||
"karma-sauce-launcher": "^4.1.3",
|
||||
"mocha": "^8.0.1",
|
||||
"nyc": "^15.0.0",
|
||||
"pre-commit": "^1.1.1",
|
||||
"require-globify": "^1.3.0",
|
||||
"typescript": "^3.9.5",
|
||||
"uglify-js": "^3.6.9",
|
||||
"watch": "^1.0.0"
|
||||
},
|
||||
"collective": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ajv"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
var jsTokens = require('js-tokens').default;
|
||||
|
||||
var processEnvRe = /\bprocess\.env\.[_$a-zA-Z][$\w]+\b/;
|
||||
var spaceOrCommentRe = /^(?:\s|\/[/*])/;
|
||||
|
||||
function replace(src, envs) {
|
||||
if (!processEnvRe.test(src)) {
|
||||
return src;
|
||||
}
|
||||
|
||||
var out = [];
|
||||
var purge = envs.some(function(env) {
|
||||
return env._ && env._.indexOf('purge') !== -1;
|
||||
});
|
||||
|
||||
jsTokens.lastIndex = 0
|
||||
var parts = src.match(jsTokens);
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
if (parts[i ] === 'process' &&
|
||||
parts[i + 1] === '.' &&
|
||||
parts[i + 2] === 'env' &&
|
||||
parts[i + 3] === '.') {
|
||||
var prevCodeToken = getAdjacentCodeToken(-1, parts, i);
|
||||
var nextCodeToken = getAdjacentCodeToken(1, parts, i + 4);
|
||||
var replacement = getReplacementString(envs, parts[i + 4], purge);
|
||||
if (prevCodeToken !== '.' &&
|
||||
nextCodeToken !== '.' &&
|
||||
nextCodeToken !== '=' &&
|
||||
typeof replacement === 'string') {
|
||||
out.push(replacement);
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
out.push(parts[i]);
|
||||
}
|
||||
|
||||
return out.join('');
|
||||
}
|
||||
|
||||
function getAdjacentCodeToken(dir, parts, i) {
|
||||
while (true) {
|
||||
var part = parts[i += dir];
|
||||
if (!spaceOrCommentRe.test(part)) {
|
||||
return part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getReplacementString(envs, name, purge) {
|
||||
for (var j = 0; j < envs.length; j++) {
|
||||
var env = envs[j];
|
||||
if (typeof env[name] !== 'undefined') {
|
||||
return JSON.stringify(env[name]);
|
||||
}
|
||||
}
|
||||
if (purge) {
|
||||
return 'undefined';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = replace;
|
||||
@@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2018-2020, Andrea Giammarchi, @WebReflection
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,15 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
labels:
|
||||
- dependency
|
||||
versioning-strategy: increase-if-necessary
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
labels:
|
||||
- dependency
|
||||
@@ -0,0 +1,7 @@
|
||||
import { AsyncRouteComponent } from './route.js';
|
||||
import * as React from 'react';
|
||||
export declare function ClientOnly({ children, fallback, }: React.PropsWithChildren<{
|
||||
fallback?: React.ReactNode;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
export declare function useHydrated(): boolean;
|
||||
export declare function lazyRouteComponent<T extends Record<string, any>, TKey extends keyof T = 'default'>(importer: () => Promise<T>, exportName?: TKey, ssr?: () => boolean): T[TKey] extends (props: infer TProps) => any ? AsyncRouteComponent<TProps> : never;
|
||||
@@ -0,0 +1,17 @@
|
||||
sudo: false
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64le
|
||||
language: node_js
|
||||
node_js:
|
||||
- '6'
|
||||
- '8'
|
||||
- '10'
|
||||
- '12'
|
||||
- '14'
|
||||
- '15'
|
||||
- lts/*
|
||||
notifications:
|
||||
email:
|
||||
- rod@vagg.org
|
||||
- matteo.collina@gmail.com
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={C:{"115":0.01844,"135":0.00615,"136":0.02767,_:"2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 137 138 139 140 3.5 3.6"},D:{"25":0.00154,"46":0.00154,"61":0.03689,"64":0.00307,"68":0.00154,"76":0.00307,"77":0.00922,"79":0.00461,"81":0.00154,"83":0.00154,"87":0.00307,"89":0.03996,"93":0.03074,"98":0.02152,"103":0.06148,"105":0.00307,"108":0.02306,"109":1.04977,"111":0.03535,"114":0.00307,"119":0.0123,"120":0.04457,"122":0.08607,"123":0.03843,"124":0.00154,"125":0.00154,"126":0.02152,"127":0.0123,"128":0.00307,"129":0.01076,"130":0.05226,"131":0.15524,"132":0.05533,"133":1.3541,"134":2.56833,"135":0.00154,_:"4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 47 48 49 50 51 52 53 54 55 56 57 58 59 60 62 63 65 66 67 69 70 71 72 73 74 75 78 80 84 85 86 88 90 91 92 94 95 96 97 99 100 101 102 104 106 107 110 112 113 115 116 117 118 121 136 137 138"},F:{"42":0.00769,"79":0.00615,"86":0.00154,"95":0.04304,"104":0.00615,"117":0.03381,_:"9 11 12 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 80 81 82 83 84 85 87 88 89 90 91 92 93 94 96 97 98 99 100 101 102 103 105 106 107 108 109 110 111 112 113 114 115 116 9.5-9.6 10.0-10.1 10.5 10.6 11.1 11.5 11.6 12.1"},B:{"18":0.0123,"81":0.00615,"91":0.00615,"92":0.00615,"100":0.00307,"109":0.08915,"116":0.00461,"117":0.00307,"120":0.01691,"121":0.00154,"122":0.04611,"123":0.00307,"125":0.00307,"126":0.00461,"127":0.01383,"129":0.1122,"130":0.06455,"131":0.0292,"132":0.05226,"133":0.79156,"134":1.91971,_:"12 13 14 15 16 17 79 80 83 84 85 86 87 88 89 90 93 94 95 96 97 98 99 101 102 103 104 105 106 107 108 110 111 112 113 114 115 118 119 124 128"},E:{_:"0 4 5 6 7 8 9 10 11 12 13 14 15 3.1 3.2 5.1 6.1 7.1 9.1 10.1 11.1 12.1 13.1 15.1 15.2-15.3 15.4 15.5 16.0 16.1 16.3 16.4 16.5 17.1 17.2 17.3 17.4 18.4","14.1":0.00307,"15.6":0.03381,"16.2":0.00307,"16.6":0.00461,"17.0":0.00154,"17.5":0.01998,"17.6":0.02767,"18.0":0.02152,"18.1":0.00615,"18.2":0.00615,"18.3":0.03074},G:{"8":0,"3.2":0,"4.0-4.1":0,"4.2-4.3":0.0017,"5.0-5.1":0,"6.0-6.1":0.0051,"7.0-7.1":0.0034,"8.1-8.4":0,"9.0-9.2":0.00255,"9.3":0.01191,"10.0-10.2":0.00085,"10.3":0.01956,"11.0-11.2":0.09017,"11.3-11.4":0.00595,"12.0-12.1":0.0034,"12.2-12.5":0.08421,"13.0-13.1":0.0017,"13.2":0.00255,"13.3":0.0034,"13.4-13.7":0.01191,"14.0-14.4":0.02977,"14.5-14.8":0.03573,"15.0-15.1":0.01956,"15.2-15.3":0.01956,"15.4":0.02382,"15.5":0.02722,"15.6-15.8":0.33515,"16.0":0.04764,"16.1":0.09782,"16.2":0.05104,"16.3":0.08847,"16.4":0.01956,"16.5":0.03658,"16.6-16.7":0.39725,"17.0":0.02382,"17.1":0.04253,"17.2":0.03232,"17.3":0.04508,"17.4":0.09017,"17.5":0.20075,"17.6-17.7":0.58268,"18.0":0.16332,"18.1":0.5342,"18.2":0.23903,"18.3":4.99576,"18.4":0.074},P:{"4":0.30929,"20":0.01031,"22":0.07217,"23":0.02062,"24":0.09279,"25":0.05155,"26":0.1031,"27":0.26805,_:"21 5.0-5.4 6.2-6.4 9.2 10.1 11.1-11.2 12.0 13.0 14.0 18.0","7.2-7.4":0.04124,"8.2":0.01031,"15.0":0.01031,"16.0":0.03093,"17.0":0.04124,"19.0":0.30929},I:{"0":0,"3":0,"4":0,"2.1":0,"2.2":0,"2.3":0,"4.1":0,"4.2-4.3":0,"4.4":0,"4.4.3-4.4.4":0},K:{"0":0.27778,_:"10 11 12 11.1 11.5 12.1"},A:{_:"6 7 8 9 10 11 5.5"},S:{"2.5":0.27931,_:"3.0-3.1"},J:{_:"7 10"},N:{_:"10 11"},R:{_:"0"},M:{"0":0.0931},Q:{_:"14.9"},O:{"0":0.00846},H:{"0":0.01},L:{"0":80.02649}};
|
||||
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
type browserType = typeof import("./resolve-targets-browser");
|
||||
type nodeType = typeof import("./resolve-targets");
|
||||
|
||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||
({}) as any as browserType as nodeType;
|
||||
|
||||
import type { ValidatedOptions } from "./validation/options.ts";
|
||||
import path from "path";
|
||||
import getTargets, {
|
||||
type InputTargets,
|
||||
} from "@babel/helper-compilation-targets";
|
||||
|
||||
import type { Targets } from "@babel/helper-compilation-targets";
|
||||
|
||||
export function resolveBrowserslistConfigFile(
|
||||
browserslistConfigFile: string,
|
||||
configFileDir: string,
|
||||
): string | undefined {
|
||||
return path.resolve(configFileDir, browserslistConfigFile);
|
||||
}
|
||||
|
||||
export function resolveTargets(
|
||||
options: ValidatedOptions,
|
||||
root: string,
|
||||
): Targets {
|
||||
const optTargets = options.targets;
|
||||
let targets: InputTargets;
|
||||
|
||||
if (typeof optTargets === "string" || Array.isArray(optTargets)) {
|
||||
targets = { browsers: optTargets };
|
||||
} else if (optTargets) {
|
||||
if ("esmodules" in optTargets) {
|
||||
targets = { ...optTargets, esmodules: "intersect" };
|
||||
} else {
|
||||
// https://github.com/microsoft/TypeScript/issues/17002
|
||||
targets = optTargets as InputTargets;
|
||||
}
|
||||
}
|
||||
|
||||
const { browserslistConfigFile } = options;
|
||||
let configFile;
|
||||
let ignoreBrowserslistConfig = false;
|
||||
if (typeof browserslistConfigFile === "string") {
|
||||
configFile = browserslistConfigFile;
|
||||
} else {
|
||||
ignoreBrowserslistConfig = browserslistConfigFile === false;
|
||||
}
|
||||
|
||||
return getTargets(targets, {
|
||||
ignoreBrowserslistConfig,
|
||||
configFile,
|
||||
configPath: root,
|
||||
browserslistEnv: options.browserslistEnv,
|
||||
});
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,627 @@
|
||||
/**
|
||||
* @fileoverview Rule to enforce concise object methods and properties.
|
||||
* @author Jamund Ferguson
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const OPTIONS = {
|
||||
always: "always",
|
||||
never: "never",
|
||||
methods: "methods",
|
||||
properties: "properties",
|
||||
consistent: "consistent",
|
||||
consistentAsNeeded: "consistent-as-needed",
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Require or disallow method and property shorthand syntax for object literals",
|
||||
recommended: false,
|
||||
frozen: true,
|
||||
url: "https://eslint.org/docs/latest/rules/object-shorthand",
|
||||
},
|
||||
|
||||
fixable: "code",
|
||||
|
||||
schema: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "array",
|
||||
items: [
|
||||
{
|
||||
enum: [
|
||||
"always",
|
||||
"methods",
|
||||
"properties",
|
||||
"never",
|
||||
"consistent",
|
||||
"consistent-as-needed",
|
||||
],
|
||||
},
|
||||
],
|
||||
minItems: 0,
|
||||
maxItems: 1,
|
||||
},
|
||||
{
|
||||
type: "array",
|
||||
items: [
|
||||
{
|
||||
enum: ["always", "methods", "properties"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
avoidQuotes: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
minItems: 0,
|
||||
maxItems: 2,
|
||||
},
|
||||
{
|
||||
type: "array",
|
||||
items: [
|
||||
{
|
||||
enum: ["always", "methods"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignoreConstructors: {
|
||||
type: "boolean",
|
||||
},
|
||||
methodsIgnorePattern: {
|
||||
type: "string",
|
||||
},
|
||||
avoidQuotes: {
|
||||
type: "boolean",
|
||||
},
|
||||
avoidExplicitReturnArrows: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
minItems: 0,
|
||||
maxItems: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
messages: {
|
||||
expectedAllPropertiesShorthanded:
|
||||
"Expected shorthand for all properties.",
|
||||
expectedLiteralMethodLongform:
|
||||
"Expected longform method syntax for string literal keys.",
|
||||
expectedPropertyShorthand: "Expected property shorthand.",
|
||||
expectedPropertyLongform: "Expected longform property syntax.",
|
||||
expectedMethodShorthand: "Expected method shorthand.",
|
||||
expectedMethodLongform: "Expected longform method syntax.",
|
||||
unexpectedMix:
|
||||
"Unexpected mix of shorthand and non-shorthand properties.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const APPLY = context.options[0] || OPTIONS.always;
|
||||
const APPLY_TO_METHODS =
|
||||
APPLY === OPTIONS.methods || APPLY === OPTIONS.always;
|
||||
const APPLY_TO_PROPS =
|
||||
APPLY === OPTIONS.properties || APPLY === OPTIONS.always;
|
||||
const APPLY_NEVER = APPLY === OPTIONS.never;
|
||||
const APPLY_CONSISTENT = APPLY === OPTIONS.consistent;
|
||||
const APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded;
|
||||
|
||||
const PARAMS = context.options[1] || {};
|
||||
const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors;
|
||||
const METHODS_IGNORE_PATTERN = PARAMS.methodsIgnorePattern
|
||||
? new RegExp(PARAMS.methodsIgnorePattern, "u")
|
||||
: null;
|
||||
const AVOID_QUOTES = PARAMS.avoidQuotes;
|
||||
const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
const CTOR_PREFIX_REGEX = /[^_$0-9]/u;
|
||||
|
||||
/**
|
||||
* Determines if the first character of the name is a capital letter.
|
||||
* @param {string} name The name of the node to evaluate.
|
||||
* @returns {boolean} True if the first character of the property name is a capital letter, false if not.
|
||||
* @private
|
||||
*/
|
||||
function isConstructor(name) {
|
||||
const match = CTOR_PREFIX_REGEX.exec(name);
|
||||
|
||||
// Not a constructor if name has no characters apart from '_', '$' and digits e.g. '_', '$$', '_8'
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const firstChar = name.charAt(match.index);
|
||||
|
||||
return firstChar === firstChar.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the property can have a shorthand form.
|
||||
* @param {ASTNode} property Property AST node
|
||||
* @returns {boolean} True if the property can have a shorthand form
|
||||
* @private
|
||||
*/
|
||||
function canHaveShorthand(property) {
|
||||
return (
|
||||
property.kind !== "set" &&
|
||||
property.kind !== "get" &&
|
||||
property.type !== "SpreadElement" &&
|
||||
property.type !== "SpreadProperty" &&
|
||||
property.type !== "ExperimentalSpreadProperty"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a node is a string literal.
|
||||
* @param {ASTNode} node Any AST node.
|
||||
* @returns {boolean} `true` if it is a string literal.
|
||||
*/
|
||||
function isStringLiteral(node) {
|
||||
return node.type === "Literal" && typeof node.value === "string";
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the property is a shorthand or not.
|
||||
* @param {ASTNode} property Property AST node
|
||||
* @returns {boolean} True if the property is considered shorthand, false if not.
|
||||
* @private
|
||||
*/
|
||||
function isShorthand(property) {
|
||||
// property.method is true when `{a(){}}`.
|
||||
return property.shorthand || property.method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the property's key and method or value are named equally.
|
||||
* @param {ASTNode} property Property AST node
|
||||
* @returns {boolean} True if the key and value are named equally, false if not.
|
||||
* @private
|
||||
*/
|
||||
function isRedundant(property) {
|
||||
const value = property.value;
|
||||
|
||||
if (value.type === "FunctionExpression") {
|
||||
return !value.id; // Only anonymous should be shorthand method.
|
||||
}
|
||||
if (value.type === "Identifier") {
|
||||
return astUtils.getStaticPropertyName(property) === value.name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that an object's properties are consistently shorthand, or not shorthand at all.
|
||||
* @param {ASTNode} node Property AST node
|
||||
* @param {boolean} checkRedundancy Whether to check longform redundancy
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkConsistency(node, checkRedundancy) {
|
||||
// We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand.
|
||||
const properties = node.properties.filter(canHaveShorthand);
|
||||
|
||||
// Do we still have properties left after filtering the getters and setters?
|
||||
if (properties.length > 0) {
|
||||
const shorthandProperties = properties.filter(isShorthand);
|
||||
|
||||
/*
|
||||
* If we do not have an equal number of longform properties as
|
||||
* shorthand properties, we are using the annotations inconsistently
|
||||
*/
|
||||
if (shorthandProperties.length !== properties.length) {
|
||||
// We have at least 1 shorthand property
|
||||
if (shorthandProperties.length > 0) {
|
||||
context.report({ node, messageId: "unexpectedMix" });
|
||||
} else if (checkRedundancy) {
|
||||
/*
|
||||
* If all properties of the object contain a method or value with a name matching it's key,
|
||||
* all the keys are redundant.
|
||||
*/
|
||||
const canAlwaysUseShorthand =
|
||||
properties.every(isRedundant);
|
||||
|
||||
if (canAlwaysUseShorthand) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "expectedAllPropertiesShorthanded",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes a FunctionExpression node by making it into a shorthand property.
|
||||
* @param {SourceCodeFixer} fixer The fixer object
|
||||
* @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value
|
||||
* @returns {Object} A fix for this node
|
||||
*/
|
||||
function makeFunctionShorthand(fixer, node) {
|
||||
const firstKeyToken = node.computed
|
||||
? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken)
|
||||
: sourceCode.getFirstToken(node.key);
|
||||
const lastKeyToken = node.computed
|
||||
? sourceCode.getFirstTokenBetween(
|
||||
node.key,
|
||||
node.value,
|
||||
astUtils.isClosingBracketToken,
|
||||
)
|
||||
: sourceCode.getLastToken(node.key);
|
||||
const keyText = sourceCode.text.slice(
|
||||
firstKeyToken.range[0],
|
||||
lastKeyToken.range[1],
|
||||
);
|
||||
let keyPrefix = "";
|
||||
|
||||
// key: /* */ () => {}
|
||||
if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (node.value.async) {
|
||||
keyPrefix += "async ";
|
||||
}
|
||||
if (node.value.generator) {
|
||||
keyPrefix += "*";
|
||||
}
|
||||
|
||||
const fixRange = [firstKeyToken.range[0], node.range[1]];
|
||||
const methodPrefix = keyPrefix + keyText;
|
||||
|
||||
if (node.value.type === "FunctionExpression") {
|
||||
const functionToken = sourceCode
|
||||
.getTokens(node.value)
|
||||
.find(
|
||||
token =>
|
||||
token.type === "Keyword" &&
|
||||
token.value === "function",
|
||||
);
|
||||
const tokenBeforeParams = node.value.generator
|
||||
? sourceCode.getTokenAfter(functionToken)
|
||||
: functionToken;
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
fixRange,
|
||||
methodPrefix +
|
||||
sourceCode.text.slice(
|
||||
tokenBeforeParams.range[1],
|
||||
node.value.range[1],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const arrowToken = sourceCode.getTokenBefore(
|
||||
node.value.body,
|
||||
astUtils.isArrowToken,
|
||||
);
|
||||
const fnBody = sourceCode.text.slice(
|
||||
arrowToken.range[1],
|
||||
node.value.range[1],
|
||||
);
|
||||
|
||||
// First token should not be `async`
|
||||
const firstValueToken = sourceCode.getFirstToken(node.value, {
|
||||
skip: node.value.async ? 1 : 0,
|
||||
});
|
||||
|
||||
const sliceStart = firstValueToken.range[0];
|
||||
const sliceEnd = sourceCode.getTokenBefore(arrowToken).range[1];
|
||||
const shouldAddParens =
|
||||
node.value.params.length === 1 &&
|
||||
node.value.params[0].range[0] === sliceStart;
|
||||
|
||||
const oldParamText = sourceCode.text.slice(sliceStart, sliceEnd);
|
||||
const newParamText = shouldAddParens
|
||||
? `(${oldParamText})`
|
||||
: oldParamText;
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
fixRange,
|
||||
methodPrefix + newParamText + fnBody,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes a FunctionExpression node by making it into a longform property.
|
||||
* @param {SourceCodeFixer} fixer The fixer object
|
||||
* @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value
|
||||
* @returns {Object} A fix for this node
|
||||
*/
|
||||
function makeFunctionLongform(fixer, node) {
|
||||
const firstKeyToken = node.computed
|
||||
? sourceCode.getTokens(node).find(token => token.value === "[")
|
||||
: sourceCode.getFirstToken(node.key);
|
||||
const lastKeyToken = node.computed
|
||||
? sourceCode
|
||||
.getTokensBetween(node.key, node.value)
|
||||
.find(token => token.value === "]")
|
||||
: sourceCode.getLastToken(node.key);
|
||||
const keyText = sourceCode.text.slice(
|
||||
firstKeyToken.range[0],
|
||||
lastKeyToken.range[1],
|
||||
);
|
||||
let functionHeader = "function";
|
||||
|
||||
if (node.value.async) {
|
||||
functionHeader = `async ${functionHeader}`;
|
||||
}
|
||||
if (node.value.generator) {
|
||||
functionHeader = `${functionHeader}*`;
|
||||
}
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
[node.range[0], lastKeyToken.range[1]],
|
||||
`${keyText}: ${functionHeader}`,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`),
|
||||
* create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is
|
||||
* traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical
|
||||
* scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered,
|
||||
* keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited.
|
||||
* When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them
|
||||
* to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule,
|
||||
* because converting it into a method would change the value of one of the lexical identifiers.
|
||||
*/
|
||||
const lexicalScopeStack = [];
|
||||
const arrowsWithLexicalIdentifiers = new WeakSet();
|
||||
const argumentsIdentifiers = new WeakSet();
|
||||
|
||||
/**
|
||||
* Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack.
|
||||
* Also, this marks all `arguments` identifiers so that they can be detected later.
|
||||
* @param {ASTNode} node The node representing the function.
|
||||
* @returns {void}
|
||||
*/
|
||||
function enterFunction(node) {
|
||||
lexicalScopeStack.unshift(new Set());
|
||||
sourceCode
|
||||
.getScope(node)
|
||||
.variables.filter(variable => variable.name === "arguments")
|
||||
.forEach(variable => {
|
||||
variable.references
|
||||
.map(ref => ref.identifier)
|
||||
.forEach(identifier =>
|
||||
argumentsIdentifiers.add(identifier),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits a function. This pops the current set of arrow functions off the lexical scope stack.
|
||||
* @returns {void}
|
||||
*/
|
||||
function exitFunction() {
|
||||
lexicalScopeStack.shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the current function as having a lexical keyword. This implies that all arrow functions
|
||||
* in the current lexical scope contain a reference to this lexical keyword.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportLexicalIdentifier() {
|
||||
lexicalScopeStack[0].forEach(arrowFunction =>
|
||||
arrowsWithLexicalIdentifiers.add(arrowFunction),
|
||||
);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
Program: enterFunction,
|
||||
FunctionDeclaration: enterFunction,
|
||||
FunctionExpression: enterFunction,
|
||||
"Program:exit": exitFunction,
|
||||
"FunctionDeclaration:exit": exitFunction,
|
||||
"FunctionExpression:exit": exitFunction,
|
||||
|
||||
ArrowFunctionExpression(node) {
|
||||
lexicalScopeStack[0].add(node);
|
||||
},
|
||||
"ArrowFunctionExpression:exit"(node) {
|
||||
lexicalScopeStack[0].delete(node);
|
||||
},
|
||||
|
||||
ThisExpression: reportLexicalIdentifier,
|
||||
Super: reportLexicalIdentifier,
|
||||
MetaProperty(node) {
|
||||
if (
|
||||
node.meta.name === "new" &&
|
||||
node.property.name === "target"
|
||||
) {
|
||||
reportLexicalIdentifier();
|
||||
}
|
||||
},
|
||||
Identifier(node) {
|
||||
if (argumentsIdentifiers.has(node)) {
|
||||
reportLexicalIdentifier();
|
||||
}
|
||||
},
|
||||
|
||||
ObjectExpression(node) {
|
||||
if (APPLY_CONSISTENT) {
|
||||
checkConsistency(node, false);
|
||||
} else if (APPLY_CONSISTENT_AS_NEEDED) {
|
||||
checkConsistency(node, true);
|
||||
}
|
||||
},
|
||||
|
||||
"Property:exit"(node) {
|
||||
const isConciseProperty = node.method || node.shorthand;
|
||||
|
||||
// Ignore destructuring assignment
|
||||
if (node.parent.type === "ObjectPattern") {
|
||||
return;
|
||||
}
|
||||
|
||||
// getters and setters are ignored
|
||||
if (node.kind === "get" || node.kind === "set") {
|
||||
return;
|
||||
}
|
||||
|
||||
// only computed methods can fail the following checks
|
||||
if (
|
||||
node.computed &&
|
||||
node.value.type !== "FunctionExpression" &&
|
||||
node.value.type !== "ArrowFunctionExpression"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Checks for property/method shorthand.
|
||||
if (isConciseProperty) {
|
||||
if (
|
||||
node.method &&
|
||||
(APPLY_NEVER ||
|
||||
(AVOID_QUOTES && isStringLiteral(node.key)))
|
||||
) {
|
||||
const messageId = APPLY_NEVER
|
||||
? "expectedMethodLongform"
|
||||
: "expectedLiteralMethodLongform";
|
||||
|
||||
// { x() {} } should be written as { x: function() {} }
|
||||
context.report({
|
||||
node,
|
||||
messageId,
|
||||
fix: fixer => makeFunctionLongform(fixer, node),
|
||||
});
|
||||
} else if (APPLY_NEVER) {
|
||||
// { x } should be written as { x: x }
|
||||
context.report({
|
||||
node,
|
||||
messageId: "expectedPropertyLongform",
|
||||
fix: fixer =>
|
||||
fixer.insertTextAfter(
|
||||
node.key,
|
||||
`: ${node.key.name}`,
|
||||
),
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
APPLY_TO_METHODS &&
|
||||
!node.value.id &&
|
||||
(node.value.type === "FunctionExpression" ||
|
||||
node.value.type === "ArrowFunctionExpression")
|
||||
) {
|
||||
if (
|
||||
IGNORE_CONSTRUCTORS &&
|
||||
node.key.type === "Identifier" &&
|
||||
isConstructor(node.key.name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (METHODS_IGNORE_PATTERN) {
|
||||
const propertyName =
|
||||
astUtils.getStaticPropertyName(node);
|
||||
|
||||
if (
|
||||
propertyName !== null &&
|
||||
METHODS_IGNORE_PATTERN.test(propertyName)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (AVOID_QUOTES && isStringLiteral(node.key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// {[x]: function(){}} should be written as {[x]() {}}
|
||||
if (
|
||||
node.value.type === "FunctionExpression" ||
|
||||
(node.value.type === "ArrowFunctionExpression" &&
|
||||
node.value.body.type === "BlockStatement" &&
|
||||
AVOID_EXPLICIT_RETURN_ARROWS &&
|
||||
!arrowsWithLexicalIdentifiers.has(node.value))
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "expectedMethodShorthand",
|
||||
fix: fixer => makeFunctionShorthand(fixer, node),
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
node.value.type === "Identifier" &&
|
||||
node.key.name === node.value.name &&
|
||||
APPLY_TO_PROPS
|
||||
) {
|
||||
// {x: x} should be written as {x}
|
||||
context.report({
|
||||
node,
|
||||
messageId: "expectedPropertyShorthand",
|
||||
fix(fixer) {
|
||||
// x: /* */ x
|
||||
// x: (/* */ x)
|
||||
if (sourceCode.getCommentsInside(node).length > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fixer.replaceText(node, node.value.name);
|
||||
},
|
||||
});
|
||||
} else if (
|
||||
node.value.type === "Identifier" &&
|
||||
node.key.type === "Literal" &&
|
||||
node.key.value === node.value.name &&
|
||||
APPLY_TO_PROPS
|
||||
) {
|
||||
if (AVOID_QUOTES) {
|
||||
return;
|
||||
}
|
||||
|
||||
// {"x": x} should be written as {x}
|
||||
context.report({
|
||||
node,
|
||||
messageId: "expectedPropertyShorthand",
|
||||
fix(fixer) {
|
||||
// "x": /* */ x
|
||||
// "x": (/* */ x)
|
||||
if (sourceCode.getCommentsInside(node).length > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fixer.replaceText(node, node.value.name);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* @fileoverview Rule to disallow async functions which have no `await` expression.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Capitalize the 1st letter of the given text.
|
||||
* @param {string} text The text to capitalize.
|
||||
* @returns {string} The text that the 1st letter was capitalized.
|
||||
*/
|
||||
function capitalizeFirstLetter(text) {
|
||||
return text[0].toUpperCase() + text.slice(1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow async functions which have no `await` expression",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/require-await",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
missingAwait: "{{name}} has no 'await' expression.",
|
||||
removeAsync: "Remove 'async'.",
|
||||
},
|
||||
|
||||
hasSuggestions: true,
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
let scopeInfo = null;
|
||||
|
||||
/**
|
||||
* Push the scope info object to the stack.
|
||||
* @returns {void}
|
||||
*/
|
||||
function enterFunction() {
|
||||
scopeInfo = {
|
||||
upper: scopeInfo,
|
||||
hasAwait: false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the top scope info object from the stack.
|
||||
* Also, it reports the function if needed.
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function exitFunction(node) {
|
||||
if (
|
||||
!node.generator &&
|
||||
node.async &&
|
||||
!scopeInfo.hasAwait &&
|
||||
!astUtils.isEmptyFunction(node)
|
||||
) {
|
||||
/*
|
||||
* If the function belongs to a method definition or
|
||||
* property, then the function's range may not include the
|
||||
* `async` keyword and we should look at the parent instead.
|
||||
*/
|
||||
const nodeWithAsyncKeyword =
|
||||
(node.parent.type === "MethodDefinition" &&
|
||||
node.parent.value === node) ||
|
||||
(node.parent.type === "Property" &&
|
||||
node.parent.method &&
|
||||
node.parent.value === node)
|
||||
? node.parent
|
||||
: node;
|
||||
|
||||
const asyncToken = sourceCode.getFirstToken(
|
||||
nodeWithAsyncKeyword,
|
||||
token => token.value === "async",
|
||||
);
|
||||
const asyncRange = [
|
||||
asyncToken.range[0],
|
||||
sourceCode.getTokenAfter(asyncToken, {
|
||||
includeComments: true,
|
||||
}).range[0],
|
||||
];
|
||||
|
||||
/*
|
||||
* Removing the `async` keyword can cause parsing errors if the current
|
||||
* statement is relying on automatic semicolon insertion. If ASI is currently
|
||||
* being used, then we should replace the `async` keyword with a semicolon.
|
||||
*/
|
||||
const nextToken = sourceCode.getTokenAfter(asyncToken);
|
||||
const addSemiColon =
|
||||
nextToken.type === "Punctuator" &&
|
||||
(nextToken.value === "[" || nextToken.value === "(") &&
|
||||
(nodeWithAsyncKeyword.type === "MethodDefinition" ||
|
||||
astUtils.isStartOfExpressionStatement(
|
||||
nodeWithAsyncKeyword,
|
||||
)) &&
|
||||
astUtils.needsPrecedingSemicolon(
|
||||
sourceCode,
|
||||
nodeWithAsyncKeyword,
|
||||
);
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
||||
messageId: "missingAwait",
|
||||
data: {
|
||||
name: capitalizeFirstLetter(
|
||||
astUtils.getFunctionNameWithKind(node),
|
||||
),
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "removeAsync",
|
||||
fix: fixer =>
|
||||
fixer.replaceTextRange(
|
||||
asyncRange,
|
||||
addSemiColon ? ";" : "",
|
||||
),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
scopeInfo = scopeInfo.upper;
|
||||
}
|
||||
|
||||
return {
|
||||
FunctionDeclaration: enterFunction,
|
||||
FunctionExpression: enterFunction,
|
||||
ArrowFunctionExpression: enterFunction,
|
||||
"FunctionDeclaration:exit": exitFunction,
|
||||
"FunctionExpression:exit": exitFunction,
|
||||
"ArrowFunctionExpression:exit": exitFunction,
|
||||
|
||||
AwaitExpression() {
|
||||
if (!scopeInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
scopeInfo.hasAwait = true;
|
||||
},
|
||||
ForOfStatement(node) {
|
||||
if (!scopeInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.await) {
|
||||
scopeInfo.hasAwait = true;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const useRouterState = require("./useRouterState.cjs");
|
||||
function useLocation(opts) {
|
||||
return useRouterState.useRouterState({
|
||||
select: (state) => (opts == null ? void 0 : opts.select) ? opts.select(state.location) : state.location
|
||||
});
|
||||
}
|
||||
exports.useLocation = useLocation;
|
||||
//# sourceMappingURL=useLocation.cjs.map
|
||||
@@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
|
||||
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
|
||||
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
|
||||
const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi;
|
||||
|
||||
const ESCAPES = new Map([
|
||||
['n', '\n'],
|
||||
['r', '\r'],
|
||||
['t', '\t'],
|
||||
['b', '\b'],
|
||||
['f', '\f'],
|
||||
['v', '\v'],
|
||||
['0', '\0'],
|
||||
['\\', '\\'],
|
||||
['e', '\u001B'],
|
||||
['a', '\u0007']
|
||||
]);
|
||||
|
||||
function unescape(c) {
|
||||
const u = c[0] === 'u';
|
||||
const bracket = c[1] === '{';
|
||||
|
||||
if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
|
||||
return String.fromCharCode(parseInt(c.slice(1), 16));
|
||||
}
|
||||
|
||||
if (u && bracket) {
|
||||
return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
|
||||
}
|
||||
|
||||
return ESCAPES.get(c) || c;
|
||||
}
|
||||
|
||||
function parseArguments(name, arguments_) {
|
||||
const results = [];
|
||||
const chunks = arguments_.trim().split(/\s*,\s*/g);
|
||||
let matches;
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const number = Number(chunk);
|
||||
if (!Number.isNaN(number)) {
|
||||
results.push(number);
|
||||
} else if ((matches = chunk.match(STRING_REGEX))) {
|
||||
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character));
|
||||
} else {
|
||||
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function parseStyle(style) {
|
||||
STYLE_REGEX.lastIndex = 0;
|
||||
|
||||
const results = [];
|
||||
let matches;
|
||||
|
||||
while ((matches = STYLE_REGEX.exec(style)) !== null) {
|
||||
const name = matches[1];
|
||||
|
||||
if (matches[2]) {
|
||||
const args = parseArguments(name, matches[2]);
|
||||
results.push([name].concat(args));
|
||||
} else {
|
||||
results.push([name]);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function buildStyle(chalk, styles) {
|
||||
const enabled = {};
|
||||
|
||||
for (const layer of styles) {
|
||||
for (const style of layer.styles) {
|
||||
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
let current = chalk;
|
||||
for (const [styleName, styles] of Object.entries(enabled)) {
|
||||
if (!Array.isArray(styles)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(styleName in current)) {
|
||||
throw new Error(`Unknown Chalk style: ${styleName}`);
|
||||
}
|
||||
|
||||
current = styles.length > 0 ? current[styleName](...styles) : current[styleName];
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
module.exports = (chalk, temporary) => {
|
||||
const styles = [];
|
||||
const chunks = [];
|
||||
let chunk = [];
|
||||
|
||||
// eslint-disable-next-line max-params
|
||||
temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => {
|
||||
if (escapeCharacter) {
|
||||
chunk.push(unescape(escapeCharacter));
|
||||
} else if (style) {
|
||||
const string = chunk.join('');
|
||||
chunk = [];
|
||||
chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string));
|
||||
styles.push({inverse, styles: parseStyle(style)});
|
||||
} else if (close) {
|
||||
if (styles.length === 0) {
|
||||
throw new Error('Found extraneous } in Chalk template literal');
|
||||
}
|
||||
|
||||
chunks.push(buildStyle(chalk, styles)(chunk.join('')));
|
||||
chunk = [];
|
||||
styles.pop();
|
||||
} else {
|
||||
chunk.push(character);
|
||||
}
|
||||
});
|
||||
|
||||
chunks.push(chunk.join(''));
|
||||
|
||||
if (styles.length > 0) {
|
||||
const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
|
||||
throw new Error(errMessage);
|
||||
}
|
||||
|
||||
return chunks.join('');
|
||||
};
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag use of parseInt without a radix argument
|
||||
* @author James Allardice
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const MODE_ALWAYS = "always",
|
||||
MODE_AS_NEEDED = "as-needed";
|
||||
|
||||
const validRadixValues = new Set(
|
||||
Array.from({ length: 37 - 2 }, (_, index) => index + 2),
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks whether a given variable is shadowed or not.
|
||||
* @param {eslint-scope.Variable} variable A variable to check.
|
||||
* @returns {boolean} `true` if the variable is shadowed.
|
||||
*/
|
||||
function isShadowed(variable) {
|
||||
return variable.defs.length >= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given node is a MemberExpression of `parseInt` method or not.
|
||||
* @param {ASTNode} node A node to check.
|
||||
* @returns {boolean} `true` if the node is a MemberExpression of `parseInt`
|
||||
* method.
|
||||
*/
|
||||
function isParseIntMethod(node) {
|
||||
return (
|
||||
node.type === "MemberExpression" &&
|
||||
!node.computed &&
|
||||
node.property.type === "Identifier" &&
|
||||
node.property.name === "parseInt"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given node is a valid value of radix or not.
|
||||
*
|
||||
* The following values are invalid.
|
||||
*
|
||||
* - A literal except integers between 2 and 36.
|
||||
* - undefined.
|
||||
* @param {ASTNode} radix A node of radix to check.
|
||||
* @returns {boolean} `true` if the node is valid.
|
||||
*/
|
||||
function isValidRadix(radix) {
|
||||
return !(
|
||||
(radix.type === "Literal" && !validRadixValues.has(radix.value)) ||
|
||||
(radix.type === "Identifier" && radix.name === "undefined")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given node is a default value of radix or not.
|
||||
* @param {ASTNode} radix A node of radix to check.
|
||||
* @returns {boolean} `true` if the node is the literal node of `10`.
|
||||
*/
|
||||
function isDefaultRadix(radix) {
|
||||
return radix.type === "Literal" && radix.value === 10;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [MODE_ALWAYS],
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Enforce the consistent use of the radix argument when using `parseInt()`",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/radix",
|
||||
},
|
||||
|
||||
hasSuggestions: true,
|
||||
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "as-needed"],
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
missingParameters: "Missing parameters.",
|
||||
redundantRadix: "Redundant radix parameter.",
|
||||
missingRadix: "Missing radix parameter.",
|
||||
invalidRadix:
|
||||
"Invalid radix parameter, must be an integer between 2 and 36.",
|
||||
addRadixParameter10:
|
||||
"Add radix parameter `10` for parsing decimal numbers.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const [mode] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Checks the arguments of a given CallExpression node and reports it if it
|
||||
* offends this rule.
|
||||
* @param {ASTNode} node A CallExpression node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkArguments(node) {
|
||||
const args = node.arguments;
|
||||
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
context.report({
|
||||
node,
|
||||
messageId: "missingParameters",
|
||||
});
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (mode === MODE_ALWAYS) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "missingRadix",
|
||||
suggest: [
|
||||
{
|
||||
messageId: "addRadixParameter10",
|
||||
fix(fixer) {
|
||||
const tokens =
|
||||
sourceCode.getTokens(node);
|
||||
const lastToken = tokens.at(-1); // Parenthesis.
|
||||
const secondToLastToken = tokens.at(-2); // May or may not be a comma.
|
||||
const hasTrailingComma =
|
||||
secondToLastToken.type ===
|
||||
"Punctuator" &&
|
||||
secondToLastToken.value === ",";
|
||||
|
||||
return fixer.insertTextBefore(
|
||||
lastToken,
|
||||
hasTrailingComma ? " 10," : ", 10",
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "redundantRadix",
|
||||
});
|
||||
} else if (!isValidRadix(args[1])) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "invalidRadix",
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"Program:exit"(node) {
|
||||
const scope = sourceCode.getScope(node);
|
||||
let variable;
|
||||
|
||||
// Check `parseInt()`
|
||||
variable = astUtils.getVariableByName(scope, "parseInt");
|
||||
if (variable && !isShadowed(variable)) {
|
||||
variable.references.forEach(reference => {
|
||||
const idNode = reference.identifier;
|
||||
|
||||
if (astUtils.isCallee(idNode)) {
|
||||
checkArguments(idNode.parent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check `Number.parseInt()`
|
||||
variable = astUtils.getVariableByName(scope, "Number");
|
||||
if (variable && !isShadowed(variable)) {
|
||||
variable.references.forEach(reference => {
|
||||
const parentNode = reference.identifier.parent;
|
||||
const maybeCallee =
|
||||
parentNode.parent.type === "ChainExpression"
|
||||
? parentNode.parent
|
||||
: parentNode;
|
||||
|
||||
if (
|
||||
isParseIntMethod(parentNode) &&
|
||||
astUtils.isCallee(maybeCallee)
|
||||
) {
|
||||
checkArguments(maybeCallee.parent);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @fileoverview Rule to disallow an empty pattern
|
||||
* @author Alberto Rodríguez
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
defaultOptions: [
|
||||
{
|
||||
allowObjectPatternsAsParameters: false,
|
||||
},
|
||||
],
|
||||
|
||||
docs: {
|
||||
description: "Disallow empty destructuring patterns",
|
||||
recommended: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-empty-pattern",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allowObjectPatternsAsParameters: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
unexpected: "Unexpected empty {{type}} pattern.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const [{ allowObjectPatternsAsParameters }] = context.options;
|
||||
|
||||
return {
|
||||
ObjectPattern(node) {
|
||||
if (node.properties.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow {} and {} = {} empty object patterns as parameters when allowObjectPatternsAsParameters is true
|
||||
if (
|
||||
allowObjectPatternsAsParameters &&
|
||||
(astUtils.isFunction(node.parent) ||
|
||||
(node.parent.type === "AssignmentPattern" &&
|
||||
astUtils.isFunction(node.parent.parent) &&
|
||||
node.parent.right.type === "ObjectExpression" &&
|
||||
node.parent.right.properties.length === 0))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpected",
|
||||
data: { type: "object" },
|
||||
});
|
||||
},
|
||||
ArrayPattern(node) {
|
||||
if (node.elements.length === 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unexpected",
|
||||
data: { type: "array" },
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
module.exports = function generate_propertyNames(it, $keyword, $ruleType) {
|
||||
var out = ' ';
|
||||
var $lvl = it.level;
|
||||
var $dataLvl = it.dataLevel;
|
||||
var $schema = it.schema[$keyword];
|
||||
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
|
||||
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
|
||||
var $breakOnError = !it.opts.allErrors;
|
||||
var $data = 'data' + ($dataLvl || '');
|
||||
var $errs = 'errs__' + $lvl;
|
||||
var $it = it.util.copy(it);
|
||||
var $closingBraces = '';
|
||||
$it.level++;
|
||||
var $nextValid = 'valid' + $it.level;
|
||||
out += 'var ' + ($errs) + ' = errors;';
|
||||
if ((it.opts.strictKeywords ? (typeof $schema == 'object' && Object.keys($schema).length > 0) || $schema === false : it.util.schemaHasRules($schema, it.RULES.all))) {
|
||||
$it.schema = $schema;
|
||||
$it.schemaPath = $schemaPath;
|
||||
$it.errSchemaPath = $errSchemaPath;
|
||||
var $key = 'key' + $lvl,
|
||||
$idx = 'idx' + $lvl,
|
||||
$i = 'i' + $lvl,
|
||||
$invalidName = '\' + ' + $key + ' + \'',
|
||||
$dataNxt = $it.dataLevel = it.dataLevel + 1,
|
||||
$nextData = 'data' + $dataNxt,
|
||||
$dataProperties = 'dataProperties' + $lvl,
|
||||
$ownProperties = it.opts.ownProperties,
|
||||
$currentBaseId = it.baseId;
|
||||
if ($ownProperties) {
|
||||
out += ' var ' + ($dataProperties) + ' = undefined; ';
|
||||
}
|
||||
if ($ownProperties) {
|
||||
out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; ';
|
||||
} else {
|
||||
out += ' for (var ' + ($key) + ' in ' + ($data) + ') { ';
|
||||
}
|
||||
out += ' var startErrs' + ($lvl) + ' = errors; ';
|
||||
var $passData = $key;
|
||||
var $wasComposite = it.compositeRule;
|
||||
it.compositeRule = $it.compositeRule = true;
|
||||
var $code = it.validate($it);
|
||||
$it.baseId = $currentBaseId;
|
||||
if (it.util.varOccurences($code, $nextData) < 2) {
|
||||
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
|
||||
} else {
|
||||
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
|
||||
}
|
||||
it.compositeRule = $it.compositeRule = $wasComposite;
|
||||
out += ' if (!' + ($nextValid) + ') { for (var ' + ($i) + '=startErrs' + ($lvl) + '; ' + ($i) + '<errors; ' + ($i) + '++) { vErrors[' + ($i) + '].propertyName = ' + ($key) + '; } var err = '; /* istanbul ignore else */
|
||||
if (it.createErrors !== false) {
|
||||
out += ' { keyword: \'' + ('propertyNames') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { propertyName: \'' + ($invalidName) + '\' } ';
|
||||
if (it.opts.messages !== false) {
|
||||
out += ' , message: \'property name \\\'' + ($invalidName) + '\\\' is invalid\' ';
|
||||
}
|
||||
if (it.opts.verbose) {
|
||||
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
|
||||
}
|
||||
out += ' } ';
|
||||
} else {
|
||||
out += ' {} ';
|
||||
}
|
||||
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
|
||||
if (!it.compositeRule && $breakOnError) {
|
||||
/* istanbul ignore if */
|
||||
if (it.async) {
|
||||
out += ' throw new ValidationError(vErrors); ';
|
||||
} else {
|
||||
out += ' validate.errors = vErrors; return false; ';
|
||||
}
|
||||
}
|
||||
if ($breakOnError) {
|
||||
out += ' break; ';
|
||||
}
|
||||
out += ' } }';
|
||||
}
|
||||
if ($breakOnError) {
|
||||
out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "js-tokens",
|
||||
"version": "4.0.0",
|
||||
"author": "Simon Lydell",
|
||||
"license": "MIT",
|
||||
"description": "A regex that tokenizes JavaScript.",
|
||||
"keywords": [
|
||||
"JavaScript",
|
||||
"js",
|
||||
"token",
|
||||
"tokenize",
|
||||
"regex"
|
||||
],
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"repository": "lydell/js-tokens",
|
||||
"scripts": {
|
||||
"test": "mocha --ui tdd",
|
||||
"esprima-compare": "node esprima-compare ./index.js everything.js/es5.js",
|
||||
"build": "node generate-index.js",
|
||||
"dev": "npm run build && npm test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coffeescript": "2.1.1",
|
||||
"esprima": "4.0.0",
|
||||
"everything.js": "1.0.3",
|
||||
"mocha": "5.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <napi.h>
|
||||
|
||||
struct InstanceData {
|
||||
Napi::FunctionReference ImageBackendCtor;
|
||||
Napi::FunctionReference PdfBackendCtor;
|
||||
Napi::FunctionReference SvgBackendCtor;
|
||||
Napi::FunctionReference CanvasCtor;
|
||||
Napi::FunctionReference CanvasGradientCtor;
|
||||
Napi::FunctionReference DOMMatrixCtor;
|
||||
Napi::FunctionReference ImageCtor;
|
||||
Napi::FunctionReference parseFont;
|
||||
Napi::FunctionReference Context2dCtor;
|
||||
Napi::FunctionReference ImageDataCtor;
|
||||
Napi::FunctionReference CanvasPatternCtor;
|
||||
};
|
||||
Reference in New Issue
Block a user