update
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,43 @@
|
||||
import { UseParamsRoute } from './useParams.js';
|
||||
import { UseMatchRoute } from './useMatch.js';
|
||||
import { UseSearchRoute } from './useSearch.js';
|
||||
import { AnyContext, AnyRoute, AnyRouter, Constrain, ConstrainLiteral, FileBaseRouteOptions, FileRoutesByPath, LazyRouteOptions, RegisteredRouter, ResolveParams, Route, RouteById, RouteConstraints, RouteIds, RouteLoaderFn, UpdatableRouteOptions } from '@tanstack/router-core';
|
||||
import { UseLoaderDepsRoute } from './useLoaderDeps.js';
|
||||
import { UseLoaderDataRoute } from './useLoaderData.js';
|
||||
import { UseRouteContextRoute } from './useRouteContext.js';
|
||||
export declare function createFileRoute<TFilePath extends keyof FileRoutesByPath, TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'], TId extends RouteConstraints['TId'] = FileRoutesByPath[TFilePath]['id'], TPath extends RouteConstraints['TPath'] = FileRoutesByPath[TFilePath]['path'], TFullPath extends RouteConstraints['TFullPath'] = FileRoutesByPath[TFilePath]['fullPath']>(path: TFilePath): FileRoute<TFilePath, TParentRoute, TId, TPath, TFullPath>['createRoute'];
|
||||
/**
|
||||
@deprecated It's no longer recommended to use the `FileRoute` class directly.
|
||||
Instead, use `createFileRoute('/path/to/file')(options)` to create a file route.
|
||||
*/
|
||||
export declare class FileRoute<TFilePath extends keyof FileRoutesByPath, TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'], TId extends RouteConstraints['TId'] = FileRoutesByPath[TFilePath]['id'], TPath extends RouteConstraints['TPath'] = FileRoutesByPath[TFilePath]['path'], TFullPath extends RouteConstraints['TFullPath'] = FileRoutesByPath[TFilePath]['fullPath']> {
|
||||
path: TFilePath;
|
||||
silent?: boolean;
|
||||
constructor(path: TFilePath, _opts?: {
|
||||
silent: boolean;
|
||||
});
|
||||
createRoute: <TSearchValidator = undefined, TParams = ResolveParams<TPath>, TRouteContextFn = AnyContext, TBeforeLoadFn = AnyContext, TLoaderDeps extends Record<string, any> = {}, TLoaderFn = undefined, TChildren = unknown>(options?: FileBaseRouteOptions<TParentRoute, TId, TPath, TSearchValidator, TParams, TLoaderDeps, TLoaderFn, AnyContext, TRouteContextFn, TBeforeLoadFn> & UpdatableRouteOptions<TParentRoute, TId, TFullPath, TParams, TSearchValidator, TLoaderFn, TLoaderDeps, AnyContext, TRouteContextFn, TBeforeLoadFn>) => Route<TParentRoute, TPath, TFullPath, TFilePath, TId, TSearchValidator, TParams, AnyContext, TRouteContextFn, TBeforeLoadFn, TLoaderDeps, TLoaderFn, TChildren, unknown>;
|
||||
}
|
||||
/**
|
||||
@deprecated It's recommended not to split loaders into separate files.
|
||||
Instead, place the loader function in the the main route file, inside the
|
||||
`createFileRoute('/path/to/file)(options)` options.
|
||||
*/
|
||||
export declare function FileRouteLoader<TFilePath extends keyof FileRoutesByPath, TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute']>(_path: TFilePath): <TLoaderFn>(loaderFn: Constrain<TLoaderFn, RouteLoaderFn<TRoute['parentRoute'], TRoute['types']['id'], TRoute['types']['params'], TRoute['types']['loaderDeps'], TRoute['types']['routerContext'], TRoute['types']['routeContextFn'], TRoute['types']['beforeLoadFn']>>) => TLoaderFn;
|
||||
export declare class LazyRoute<TRoute extends AnyRoute> {
|
||||
options: {
|
||||
id: string;
|
||||
} & LazyRouteOptions;
|
||||
constructor(opts: {
|
||||
id: string;
|
||||
} & LazyRouteOptions);
|
||||
useMatch: UseMatchRoute<TRoute['id']>;
|
||||
useRouteContext: UseRouteContextRoute<TRoute['id']>;
|
||||
useSearch: UseSearchRoute<TRoute['id']>;
|
||||
useParams: UseParamsRoute<TRoute['id']>;
|
||||
useLoaderDeps: UseLoaderDepsRoute<TRoute['id']>;
|
||||
useLoaderData: UseLoaderDataRoute<TRoute['id']>;
|
||||
useNavigate: () => import('@tanstack/router-core').UseNavigateResult<any>;
|
||||
}
|
||||
export declare function createLazyRoute<TRouter extends AnyRouter = RegisteredRouter, TId extends string = string, TRoute extends AnyRoute = RouteById<TRouter['routeTree'], TId>>(id: ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>): (opts: LazyRouteOptions) => LazyRoute<TRoute>;
|
||||
export declare function createLazyFileRoute<TFilePath extends keyof FileRoutesByPath, TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute']>(id: TFilePath): (opts: LazyRouteOptions) => LazyRoute<TRoute>;
|
||||
@@ -0,0 +1,71 @@
|
||||
let crypto = require('crypto')
|
||||
|
||||
let { urlAlphabet } = require('../url-alphabet/index.cjs')
|
||||
|
||||
// `crypto.randomFill()` is a little faster than `crypto.randomBytes()`,
|
||||
// because it is possible to use in combination with `Buffer.allocUnsafe()`.
|
||||
let random = bytes =>
|
||||
new Promise((resolve, reject) => {
|
||||
// `Buffer.allocUnsafe()` is faster because it doesn’t flush the memory.
|
||||
// Memory flushing is unnecessary since the buffer allocation itself resets
|
||||
// the memory with the new bytes.
|
||||
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(buf)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let customAlphabet = (alphabet, defaultSize = 21) => {
|
||||
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
||||
// values closer to the alphabet size. The bitmask calculates the closest
|
||||
// `2^31 - 1` number, which exceeds the alphabet size.
|
||||
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
||||
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
||||
// Though, the bitmask solution is not perfect since the bytes exceeding
|
||||
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
||||
// the random bytes redundancy has to be satisfied.
|
||||
|
||||
// Note: every hardware random generator call is performance expensive,
|
||||
// because the system call for entropy collection takes a lot of time.
|
||||
// So, to avoid additional system calls, extra bytes are requested in advance.
|
||||
|
||||
// Next, a step determines how many random bytes to generate.
|
||||
// The number of random bytes gets decided upon the ID size, mask,
|
||||
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
||||
// according to benchmarks).
|
||||
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
||||
|
||||
let tick = (id, size = defaultSize) =>
|
||||
random(step).then(bytes => {
|
||||
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
||||
let i = step
|
||||
while (i--) {
|
||||
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
||||
id += alphabet[bytes[i] & mask] || ''
|
||||
if (id.length >= size) return id
|
||||
}
|
||||
return tick(id, size)
|
||||
})
|
||||
|
||||
return size => tick('', size)
|
||||
}
|
||||
|
||||
let nanoid = (size = 21) =>
|
||||
random((size |= 0)).then(bytes => {
|
||||
let id = ''
|
||||
// A compact alternative for `for (var i = 0; i < step; i++)`.
|
||||
while (size--) {
|
||||
// It is incorrect to use bytes exceeding the alphabet size.
|
||||
// The following mask reduces the random byte in the 0-255 value
|
||||
// range to the 0-63 value range. Therefore, adding hacks, such
|
||||
// as empty string fallback or magic numbers, is unneccessary because
|
||||
// the bitmask trims bytes down to the alphabet size.
|
||||
id += urlAlphabet[bytes[size] & 63]
|
||||
}
|
||||
return id
|
||||
})
|
||||
|
||||
module.exports = { nanoid, customAlphabet, random }
|
||||
@@ -0,0 +1,5 @@
|
||||
# react-refresh
|
||||
|
||||
This package implements the wiring necessary to integrate Fast Refresh into bundlers. Fast Refresh is a feature that lets you edit React components in a running application without losing their state. It is similar to an old feature known as "hot reloading", but Fast Refresh is more reliable and officially supported by React.
|
||||
|
||||
This package is primarily aimed at developers of bundler plugins. If you’re working on one, here is a [rough guide](https://github.com/facebook/react/issues/16604#issuecomment-528663101) for Fast Refresh integration using this package.
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M11 3H13.6C14 3 14.3 3.3 14.3 3.6C14.3 3.9 14 4.2 13.7 4.2H13.3V14C13.3 15.1 12.4 16 11.3 16H4.80005C3.70005 16 2.80005 15.1 2.80005 14V4.2H2.40005C2.00005 4.2 1.80005 4 1.80005 3.6C1.80005 3.2 2.00005 3 2.40005 3H5.00005V2C5.00005 0.9 5.90005 0 7.00005 0H9.00005C10.1 0 11 0.9 11 2V3ZM6.90005 1.2L6.30005 1.8V3H9.80005V1.8L9.20005 1.2H6.90005ZM11.4 14.7L12 14.1V4.2H4.00005V14.1L4.60005 14.7H11.4ZM7.00005 12.4C7.00005 12.7 6.70005 13 6.40005 13C6.10005 13 5.80005 12.7 5.80005 12.4V7.6C5.70005 7.3 6.00005 7 6.40005 7C6.80005 7 7.00005 7.3 7.00005 7.6V12.4ZM10.2001 12.4C10.2001 12.7 9.90006 13 9.60006 13C9.30006 13 9.00006 12.7 9.00006 12.4V7.6C9.00006 7.3 9.30006 7 9.60006 7C9.90006 7 10.2001 7.3 10.2001 7.6V12.4Z"
|
||||
fill="black" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 909 B |
@@ -0,0 +1,104 @@
|
||||
# fast-levenshtein - Levenshtein algorithm in Javascript
|
||||
|
||||
[](http://travis-ci.org/hiddentao/fast-levenshtein)
|
||||
[](https://badge.fury.io/js/fast-levenshtein)
|
||||
[](https://www.npmjs.com/package/fast-levenshtein)
|
||||
[](https://twitter.com/hiddentao)
|
||||
|
||||
An efficient Javascript implementation of the [Levenshtein algorithm](http://en.wikipedia.org/wiki/Levenshtein_distance) with locale-specific collator support.
|
||||
|
||||
## Features
|
||||
|
||||
* Works in node.js and in the browser.
|
||||
* Better performance than other implementations by not needing to store the whole matrix ([more info](http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm)).
|
||||
* Locale-sensitive string comparisions if needed.
|
||||
* Comprehensive test suite and performance benchmark.
|
||||
* Small: <1 KB minified and gzipped
|
||||
|
||||
## Installation
|
||||
|
||||
### node.js
|
||||
|
||||
Install using [npm](http://npmjs.org/):
|
||||
|
||||
```bash
|
||||
$ npm install fast-levenshtein
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
Using bower:
|
||||
|
||||
```bash
|
||||
$ bower install fast-levenshtein
|
||||
```
|
||||
|
||||
If you are not using any module loader system then the API will then be accessible via the `window.Levenshtein` object.
|
||||
|
||||
## Examples
|
||||
|
||||
**Default usage**
|
||||
|
||||
```javascript
|
||||
var levenshtein = require('fast-levenshtein');
|
||||
|
||||
var distance = levenshtein.get('back', 'book'); // 2
|
||||
var distance = levenshtein.get('我愛你', '我叫你'); // 1
|
||||
```
|
||||
|
||||
**Locale-sensitive string comparisons**
|
||||
|
||||
It supports using [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) for locale-sensitive string comparisons:
|
||||
|
||||
```javascript
|
||||
var levenshtein = require('fast-levenshtein');
|
||||
|
||||
levenshtein.get('mikailovitch', 'Mikhaïlovitch', { useCollator: true});
|
||||
// 1
|
||||
```
|
||||
|
||||
## Building and Testing
|
||||
|
||||
To build the code and run the tests:
|
||||
|
||||
```bash
|
||||
$ npm install -g grunt-cli
|
||||
$ npm install
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
_Thanks to [Titus Wormer](https://github.com/wooorm) for [encouraging me](https://github.com/hiddentao/fast-levenshtein/issues/1) to do this._
|
||||
|
||||
Benchmarked against other node.js levenshtein distance modules (on Macbook Air 2012, Core i7, 8GB RAM):
|
||||
|
||||
```bash
|
||||
Running suite Implementation comparison [benchmark/speed.js]...
|
||||
>> levenshtein-edit-distance x 234 ops/sec ±3.02% (73 runs sampled)
|
||||
>> levenshtein-component x 422 ops/sec ±4.38% (83 runs sampled)
|
||||
>> levenshtein-deltas x 283 ops/sec ±3.83% (78 runs sampled)
|
||||
>> natural x 255 ops/sec ±0.76% (88 runs sampled)
|
||||
>> levenshtein x 180 ops/sec ±3.55% (86 runs sampled)
|
||||
>> fast-levenshtein x 1,792 ops/sec ±2.72% (95 runs sampled)
|
||||
Benchmark done.
|
||||
Fastest test is fast-levenshtein at 4.2x faster than levenshtein-component
|
||||
```
|
||||
|
||||
You can run this benchmark yourself by doing:
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
$ npm run build
|
||||
$ npm run benchmark
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
If you wish to submit a pull request please update and/or create new tests for any changes you make and ensure the grunt build passes.
|
||||
|
||||
See [CONTRIBUTING.md](https://github.com/hiddentao/fast-levenshtein/blob/master/CONTRIBUTING.md) for details.
|
||||
|
||||
## License
|
||||
|
||||
MIT - see [LICENSE.md](https://github.com/hiddentao/fast-levenshtein/blob/master/LICENSE.md)
|
||||
@@ -0,0 +1,2 @@
|
||||
.nyc_output/
|
||||
coverage/
|
||||
@@ -0,0 +1,14 @@
|
||||
{{# def.definitions }}
|
||||
{{# def.errors }}
|
||||
{{# def.setupKeyword }}
|
||||
{{# def.$data }}
|
||||
|
||||
{{
|
||||
var $regexp = $isData
|
||||
? '(new RegExp(' + $schemaValue + '))'
|
||||
: it.usePattern($schema);
|
||||
}}
|
||||
|
||||
if ({{# def.$dataNotType:'string' }} !{{=$regexp}}.test({{=$data}}) ) {
|
||||
{{# def.error:'pattern' }}
|
||||
} {{? $breakOnError }} else { {{?}}
|
||||
@@ -0,0 +1,203 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.flatten = void 0;
|
||||
const utils_js_1 = require("./utils.js");
|
||||
function flatten(input) {
|
||||
const { indices } = this;
|
||||
const existing = indices.get(input);
|
||||
if (existing)
|
||||
return [existing];
|
||||
if (input === undefined)
|
||||
return utils_js_1.UNDEFINED;
|
||||
if (input === null)
|
||||
return utils_js_1.NULL;
|
||||
if (Number.isNaN(input))
|
||||
return utils_js_1.NAN;
|
||||
if (input === Number.POSITIVE_INFINITY)
|
||||
return utils_js_1.POSITIVE_INFINITY;
|
||||
if (input === Number.NEGATIVE_INFINITY)
|
||||
return utils_js_1.NEGATIVE_INFINITY;
|
||||
if (input === 0 && 1 / input < 0)
|
||||
return utils_js_1.NEGATIVE_ZERO;
|
||||
const index = this.index++;
|
||||
indices.set(input, index);
|
||||
stringify.call(this, input, index);
|
||||
return index;
|
||||
}
|
||||
exports.flatten = flatten;
|
||||
function stringify(input, index) {
|
||||
const { deferred, plugins, postPlugins } = this;
|
||||
const str = this.stringified;
|
||||
const stack = [[input, index]];
|
||||
while (stack.length > 0) {
|
||||
const [input, index] = stack.pop();
|
||||
const partsForObj = (obj) => Object.keys(obj)
|
||||
.map((k) => `"_${flatten.call(this, k)}":${flatten.call(this, obj[k])}`)
|
||||
.join(",");
|
||||
let error = null;
|
||||
switch (typeof input) {
|
||||
case "boolean":
|
||||
case "number":
|
||||
case "string":
|
||||
str[index] = JSON.stringify(input);
|
||||
break;
|
||||
case "bigint":
|
||||
str[index] = `["${utils_js_1.TYPE_BIGINT}","${input}"]`;
|
||||
break;
|
||||
case "symbol": {
|
||||
const keyFor = Symbol.keyFor(input);
|
||||
if (!keyFor) {
|
||||
error = new Error("Cannot encode symbol unless created with Symbol.for()");
|
||||
}
|
||||
else {
|
||||
str[index] = `["${utils_js_1.TYPE_SYMBOL}",${JSON.stringify(keyFor)}]`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "object": {
|
||||
if (!input) {
|
||||
str[index] = `${utils_js_1.NULL}`;
|
||||
break;
|
||||
}
|
||||
const isArray = Array.isArray(input);
|
||||
let pluginHandled = false;
|
||||
if (!isArray && plugins) {
|
||||
for (const plugin of plugins) {
|
||||
const pluginResult = plugin(input);
|
||||
if (Array.isArray(pluginResult)) {
|
||||
pluginHandled = true;
|
||||
const [pluginIdentifier, ...rest] = pluginResult;
|
||||
str[index] = `[${JSON.stringify(pluginIdentifier)}`;
|
||||
if (rest.length > 0) {
|
||||
str[index] += `,${rest
|
||||
.map((v) => flatten.call(this, v))
|
||||
.join(",")}`;
|
||||
}
|
||||
str[index] += "]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pluginHandled) {
|
||||
let result = isArray ? "[" : "{";
|
||||
if (isArray) {
|
||||
for (let i = 0; i < input.length; i++)
|
||||
result +=
|
||||
(i ? "," : "") +
|
||||
(i in input ? flatten.call(this, input[i]) : utils_js_1.HOLE);
|
||||
str[index] = `${result}]`;
|
||||
}
|
||||
else if (input instanceof Date) {
|
||||
str[index] = `["${utils_js_1.TYPE_DATE}",${input.getTime()}]`;
|
||||
}
|
||||
else if (input instanceof URL) {
|
||||
str[index] = `["${utils_js_1.TYPE_URL}",${JSON.stringify(input.href)}]`;
|
||||
}
|
||||
else if (input instanceof RegExp) {
|
||||
str[index] = `["${utils_js_1.TYPE_REGEXP}",${JSON.stringify(input.source)},${JSON.stringify(input.flags)}]`;
|
||||
}
|
||||
else if (input instanceof Set) {
|
||||
if (input.size > 0) {
|
||||
str[index] = `["${utils_js_1.TYPE_SET}",${[...input]
|
||||
.map((val) => flatten.call(this, val))
|
||||
.join(",")}]`;
|
||||
}
|
||||
else {
|
||||
str[index] = `["${utils_js_1.TYPE_SET}"]`;
|
||||
}
|
||||
}
|
||||
else if (input instanceof Map) {
|
||||
if (input.size > 0) {
|
||||
str[index] = `["${utils_js_1.TYPE_MAP}",${[...input]
|
||||
.flatMap(([k, v]) => [
|
||||
flatten.call(this, k),
|
||||
flatten.call(this, v),
|
||||
])
|
||||
.join(",")}]`;
|
||||
}
|
||||
else {
|
||||
str[index] = `["${utils_js_1.TYPE_MAP}"]`;
|
||||
}
|
||||
}
|
||||
else if (input instanceof Promise) {
|
||||
str[index] = `["${utils_js_1.TYPE_PROMISE}",${index}]`;
|
||||
deferred[index] = input;
|
||||
}
|
||||
else if (input instanceof Error) {
|
||||
str[index] = `["${utils_js_1.TYPE_ERROR}",${JSON.stringify(input.message)}`;
|
||||
if (input.name !== "Error") {
|
||||
str[index] += `,${JSON.stringify(input.name)}`;
|
||||
}
|
||||
str[index] += "]";
|
||||
}
|
||||
else if (Object.getPrototypeOf(input) === null) {
|
||||
str[index] = `["${utils_js_1.TYPE_NULL_OBJECT}",{${partsForObj(input)}}]`;
|
||||
}
|
||||
else if (isPlainObject(input)) {
|
||||
str[index] = `{${partsForObj(input)}}`;
|
||||
}
|
||||
else {
|
||||
error = new Error("Cannot encode object with prototype");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const isArray = Array.isArray(input);
|
||||
let pluginHandled = false;
|
||||
if (!isArray && plugins) {
|
||||
for (const plugin of plugins) {
|
||||
const pluginResult = plugin(input);
|
||||
if (Array.isArray(pluginResult)) {
|
||||
pluginHandled = true;
|
||||
const [pluginIdentifier, ...rest] = pluginResult;
|
||||
str[index] = `[${JSON.stringify(pluginIdentifier)}`;
|
||||
if (rest.length > 0) {
|
||||
str[index] += `,${rest
|
||||
.map((v) => flatten.call(this, v))
|
||||
.join(",")}`;
|
||||
}
|
||||
str[index] += "]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pluginHandled) {
|
||||
error = new Error("Cannot encode function or unexpected type");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
let pluginHandled = false;
|
||||
if (postPlugins) {
|
||||
for (const plugin of postPlugins) {
|
||||
const pluginResult = plugin(input);
|
||||
if (Array.isArray(pluginResult)) {
|
||||
pluginHandled = true;
|
||||
const [pluginIdentifier, ...rest] = pluginResult;
|
||||
str[index] = `[${JSON.stringify(pluginIdentifier)}`;
|
||||
if (rest.length > 0) {
|
||||
str[index] += `,${rest
|
||||
.map((v) => flatten.call(this, v))
|
||||
.join(",")}`;
|
||||
}
|
||||
str[index] += "]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pluginHandled) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const objectProtoNames = Object.getOwnPropertyNames(Object.prototype)
|
||||
.sort()
|
||||
.join("\0");
|
||||
function isPlainObject(thing) {
|
||||
const proto = Object.getPrototypeOf(thing);
|
||||
return (proto === Object.prototype ||
|
||||
proto === null ||
|
||||
Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames);
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* @fileoverview HTML reporter
|
||||
* @author Julian Laval
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const encodeHTML = (function () {
|
||||
const encodeHTMLRules = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'",
|
||||
};
|
||||
const matchHTML = /[&<>"']/gu;
|
||||
|
||||
return function (code) {
|
||||
return code
|
||||
? code.toString().replace(matchHTML, m => encodeHTMLRules[m] || m)
|
||||
: "";
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the final HTML document.
|
||||
* @param {Object} it data for the document.
|
||||
* @returns {string} HTML document.
|
||||
*/
|
||||
function pageTemplate(it) {
|
||||
const { reportColor, reportSummary, date, results } = it;
|
||||
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ESLint Report</title>
|
||||
<link rel="icon" type="image/png" sizes="any" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAHaAAAB2gGFomX7AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABD1JREFUWMPFl11sk2UUx3/nbYtjxS1MF7MLMTECMgSTtSSyrQkLhAj7UBPnDSEGoxegGzMwojhXVpmTAA5iYpSoMQa8GBhFOrMFk03buei6yRAlcmOM0SEmU9d90b19jxcM1o5+sGnsc/e+z/l6ztf/HFFVMnns6QieeOCHBePGsHM+wrOtvLG2C4WRVDSSygNV7sCjlspxwDnPB44aols/DXk+mbMBmx/6OseITF1CuOtfevkPh2Uu+/jbdX8lujSScRlT5r7/QDlAfsRmfzmpnkQ/H3H13gf6bBrBn1uqK8WylgEnU8eZmk1repbfchJG1TyKyIKEwuBHFd3lD3naY3O1siiwXsVoBV2VgM1ht/QQUJk2ByqKghsQziYQ8ifKgexIXmuyzC4r67Y7R+xPAfuB/Nn3Cpva+0s7khpQVtZtd4bt51BWxtBYAiciprG7c7D4SixzU9PYalDL6110Ifb/w8W9eY7JqFeFHbO8fPGyLHwwFHJNJTSgwtVTB9oaw9BlQ+tO93vOxypoaQnfEYlI43SeCHDC4TDq9+51/h5fxr33q0ZfV9g04wat9Q943rjJgCp3952W2i8Bi6eDvdsfKj0cK/DYMRyXL4/sUJUmIHd2zYMezsvLaamp4WpcWN3BXSiHpuMwbGbZlnZ8tXY4rgosy+G7oRwQ0cAsd28YGgqfU5UjCZQDLALxDg+Hv/P5Rqvj4hwrS8izXzWb4spwc1GgENFnkpWRzxeuB+ssUHgLdb9UVdt8vpGdKQpze7n7y1U3DBChNRUuqOo9c+0+qpKKxyZqtAIYla7gY4JszAAQri93BSsMRZoyBcUC+w3Q3AyOA4sNhAOZ0q7Iq0b2vUNvK5zPgP+/H8+Zetdoa6uOikhdGurxebwvJY8Iz3V1rTMNAH+opEuQj5KTT/qA1yC+wyUjBm12OidaUtCcPNNX2h0Hx2JG69VulANZAJZJwfU7rzd/FHixuXniTdM0m4GtSQT7bTartqEh9yfImUEzkwKZmTwmo5a5JwkYBfcDL01/RkR5y8iWhtPBknB8ZxwtU9UjwOrrKCeizzc25nTGg1F/turEHoU9wMLpDvWKf8DTmNCAKnd/tqUTF4ElMXJ+A5rWDJS+41WsGWzALhJ+ErBWrLj9g+pqojHxlXJX8HGUg0BsR/x1yhxf3jm4cSzpQFLp6tmi6PEE7g1ZhtZ91ufpSZUAFa6gC+UoQslNaSmypT1U8mHKiUgEKS8KfgF4EpYunFI16tsHin+OG0LcgQK7yj7g6cSzpva2D3hKVNG0Y3mVO1BkqfSlmJrHBQ4uvM12gJHc6ETW8HZVfMRmXvyxxNC1Z/o839zyXlDuCr4nsC11J+MXueaVJWn6yPv+/pJtc9oLTNN4AeTvNGByd3rlhE2x9s5pLwDoHCy+grDzWmOZ95lUtLYj5Bma126Y8eX0/zj/ADxGyViSg4BXAAAAAElFTkSuQmCC">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PScwIDAgMjk0LjgyNSAyNTguOTgyJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPg0KPHBhdGggZmlsbD0nIzgwODBGMicgZD0nTTk3LjAyMSw5OS4wMTZsNDguNDMyLTI3Ljk2MmMxLjIxMi0wLjcsMi43MDYtMC43LDMuOTE4LDBsNDguNDMzLDI3Ljk2MiBjMS4yMTEsMC43LDEuOTU5LDEuOTkzLDEuOTU5LDMuMzkzdjU1LjkyNGMwLDEuMzk5LTAuNzQ4LDIuNjkzLTEuOTU5LDMuMzk0bC00OC40MzMsMjcuOTYyYy0xLjIxMiwwLjctMi43MDYsMC43LTMuOTE4LDAgbC00OC40MzItMjcuOTYyYy0xLjIxMi0wLjctMS45NTktMS45OTQtMS45NTktMy4zOTR2LTU1LjkyNEM5NS4wNjMsMTAxLjAwOSw5NS44MSw5OS43MTYsOTcuMDIxLDk5LjAxNicvPg0KPHBhdGggZmlsbD0nIzRCMzJDMycgZD0nTTI3My4zMzYsMTI0LjQ4OEwyMTUuNDY5LDIzLjgxNmMtMi4xMDItMy42NC01Ljk4NS02LjMyNS0xMC4xODgtNi4zMjVIODkuNTQ1IGMtNC4yMDQsMC04LjA4OCwyLjY4NS0xMC4xOSw2LjMyNWwtNTcuODY3LDEwMC40NWMtMi4xMDIsMy42NDEtMi4xMDIsOC4yMzYsMCwxMS44NzdsNTcuODY3LDk5Ljg0NyBjMi4xMDIsMy42NCw1Ljk4Niw1LjUwMSwxMC4xOSw1LjUwMWgxMTUuNzM1YzQuMjAzLDAsOC4wODctMS44MDUsMTAuMTg4LTUuNDQ2bDU3Ljg2Ny0xMDAuMDEgQzI3NS40MzksMTMyLjM5NiwyNzUuNDM5LDEyOC4xMjgsMjczLjMzNiwxMjQuNDg4IE0yMjUuNDE5LDE3Mi44OThjMCwxLjQ4LTAuODkxLDIuODQ5LTIuMTc0LDMuNTlsLTczLjcxLDQyLjUyNyBjLTEuMjgyLDAuNzQtMi44ODgsMC43NC00LjE3LDBsLTczLjc2Ny00Mi41MjdjLTEuMjgyLTAuNzQxLTIuMTc5LTIuMTA5LTIuMTc5LTMuNTlWODcuODQzYzAtMS40ODEsMC44ODQtMi44NDksMi4xNjctMy41OSBsNzMuNzA3LTQyLjUyN2MxLjI4Mi0wLjc0MSwyLjg4Ni0wLjc0MSw0LjE2OCwwbDczLjc3Miw0Mi41MjdjMS4yODMsMC43NDEsMi4xODYsMi4xMDksMi4xODYsMy41OVYxNzIuODk4eicvPg0KPC9zdmc+">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#overview {
|
||||
padding: 20px 30px;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 30px;
|
||||
width: calc(100% - 60px);
|
||||
max-width: 1000px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 400;
|
||||
font-size: medium;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
td.clr-1,
|
||||
td.clr-2,
|
||||
th span {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
th span {
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
th span::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
tr td:first-child,
|
||||
tr td:last-child {
|
||||
color: #9da0a4;
|
||||
}
|
||||
|
||||
#overview.bg-0,
|
||||
tr.bg-0 th {
|
||||
color: #468847;
|
||||
background: #dff0d8;
|
||||
border-bottom: 1px solid #d6e9c6;
|
||||
}
|
||||
|
||||
#overview.bg-1,
|
||||
tr.bg-1 th {
|
||||
color: #f0ad4e;
|
||||
background: #fcf8e3;
|
||||
border-bottom: 1px solid #fbeed5;
|
||||
}
|
||||
|
||||
#overview.bg-2,
|
||||
tr.bg-2 th {
|
||||
color: #b94a48;
|
||||
background: #f2dede;
|
||||
border-bottom: 1px solid #eed3d7;
|
||||
}
|
||||
|
||||
td {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
td.clr-1 {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
td.clr-2 {
|
||||
color: #b94a48;
|
||||
}
|
||||
|
||||
td a {
|
||||
color: #3a33d1;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td a:hover {
|
||||
color: #272296;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="overview" class="bg-${reportColor}">
|
||||
<h1>ESLint Report</h1>
|
||||
<div>
|
||||
<span>${reportSummary}</span> - Generated on ${date}
|
||||
</div>
|
||||
</div>
|
||||
<table>
|
||||
<tbody>
|
||||
${results}
|
||||
</tbody>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
var groups = document.querySelectorAll("tr[data-group]");
|
||||
for (i = 0; i < groups.length; i++) {
|
||||
groups[i].addEventListener("click", function() {
|
||||
var inGroup = document.getElementsByClassName(this.getAttribute("data-group"));
|
||||
this.innerHTML = (this.innerHTML.indexOf("+") > -1) ? this.innerHTML.replace("+", "-") : this.innerHTML.replace("-", "+");
|
||||
for (var j = 0; j < inGroup.length; j++) {
|
||||
inGroup[j].style.display = (inGroup[j].style.display !== "none") ? "none" : "table-row";
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`.trimStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a word and a count, append an s if count is not one.
|
||||
* @param {string} word A word in its singular form.
|
||||
* @param {int} count A number controlling whether word should be pluralized.
|
||||
* @returns {string} The original word with an s on the end if count is not one.
|
||||
*/
|
||||
function pluralize(word, count) {
|
||||
return count === 1 ? word : `${word}s`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders text along the template of x problems (x errors, x warnings)
|
||||
* @param {string} totalErrors Total errors
|
||||
* @param {string} totalWarnings Total warnings
|
||||
* @returns {string} The formatted string, pluralized where necessary
|
||||
*/
|
||||
function renderSummary(totalErrors, totalWarnings) {
|
||||
const totalProblems = totalErrors + totalWarnings;
|
||||
let renderedText = `${totalProblems} ${pluralize("problem", totalProblems)}`;
|
||||
|
||||
if (totalProblems !== 0) {
|
||||
renderedText += ` (${totalErrors} ${pluralize("error", totalErrors)}, ${totalWarnings} ${pluralize("warning", totalWarnings)})`;
|
||||
}
|
||||
return renderedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color based on whether there are errors/warnings...
|
||||
* @param {string} totalErrors Total errors
|
||||
* @param {string} totalWarnings Total warnings
|
||||
* @returns {int} The color code (0 = green, 1 = yellow, 2 = red)
|
||||
*/
|
||||
function renderColor(totalErrors, totalWarnings) {
|
||||
if (totalErrors !== 0) {
|
||||
return 2;
|
||||
}
|
||||
if (totalWarnings !== 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML (table row) describing a single message.
|
||||
* @param {Object} it data for the message.
|
||||
* @returns {string} HTML (table row) describing the message.
|
||||
*/
|
||||
function messageTemplate(it) {
|
||||
const {
|
||||
parentIndex,
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
severityNumber,
|
||||
severityName,
|
||||
message,
|
||||
ruleUrl,
|
||||
ruleId,
|
||||
} = it;
|
||||
|
||||
return `
|
||||
<tr style="display: none;" class="f-${parentIndex}">
|
||||
<td>${lineNumber}:${columnNumber}</td>
|
||||
<td class="clr-${severityNumber}">${severityName}</td>
|
||||
<td>${encodeHTML(message)}</td>
|
||||
<td>
|
||||
<a href="${ruleUrl ? ruleUrl : ""}" target="_blank" rel="noopener noreferrer">${ruleId ? ruleId : ""}</a>
|
||||
</td>
|
||||
</tr>
|
||||
`.trimStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML (table rows) describing the messages.
|
||||
* @param {Array} messages Messages.
|
||||
* @param {int} parentIndex Index of the parent HTML row.
|
||||
* @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
|
||||
* @returns {string} HTML (table rows) describing the messages.
|
||||
*/
|
||||
function renderMessages(messages, parentIndex, rulesMeta) {
|
||||
/**
|
||||
* Get HTML (table row) describing a message.
|
||||
* @param {Object} message Message.
|
||||
* @returns {string} HTML (table row) describing a message.
|
||||
*/
|
||||
return messages
|
||||
.map(message => {
|
||||
const lineNumber = message.line || 0;
|
||||
const columnNumber = message.column || 0;
|
||||
let ruleUrl;
|
||||
|
||||
if (rulesMeta) {
|
||||
const meta = rulesMeta[message.ruleId];
|
||||
|
||||
if (meta && meta.docs && meta.docs.url) {
|
||||
ruleUrl = meta.docs.url;
|
||||
}
|
||||
}
|
||||
|
||||
return messageTemplate({
|
||||
parentIndex,
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
severityNumber: message.severity,
|
||||
severityName: message.severity === 1 ? "Warning" : "Error",
|
||||
message: message.message,
|
||||
ruleId: message.ruleId,
|
||||
ruleUrl,
|
||||
});
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML (table row) describing the result for a single file.
|
||||
* @param {Object} it data for the file.
|
||||
* @returns {string} HTML (table row) describing the result for the file.
|
||||
*/
|
||||
function resultTemplate(it) {
|
||||
const { color, index, filePath, summary } = it;
|
||||
|
||||
return `
|
||||
<tr class="bg-${color}" data-group="f-${index}">
|
||||
<th colspan="4">
|
||||
[+] ${encodeHTML(filePath)}
|
||||
<span>${encodeHTML(summary)}</span>
|
||||
</th>
|
||||
</tr>
|
||||
`.trimStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the results.
|
||||
* @param {Array} results Test results.
|
||||
* @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
|
||||
* @returns {string} HTML string describing the results.
|
||||
*/
|
||||
function renderResults(results, rulesMeta) {
|
||||
return results
|
||||
.map(
|
||||
(result, index) =>
|
||||
resultTemplate({
|
||||
index,
|
||||
color: renderColor(result.errorCount, result.warningCount),
|
||||
filePath: result.filePath,
|
||||
summary: renderSummary(
|
||||
result.errorCount,
|
||||
result.warningCount,
|
||||
),
|
||||
}) + renderMessages(result.messages, index, rulesMeta),
|
||||
)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = function (results, data) {
|
||||
let totalErrors, totalWarnings;
|
||||
|
||||
const metaData = data ? data.rulesMeta : {};
|
||||
|
||||
totalErrors = 0;
|
||||
totalWarnings = 0;
|
||||
|
||||
// Iterate over results to get totals
|
||||
results.forEach(result => {
|
||||
totalErrors += result.errorCount;
|
||||
totalWarnings += result.warningCount;
|
||||
});
|
||||
|
||||
return pageTemplate({
|
||||
date: new Date(),
|
||||
reportColor: renderColor(totalErrors, totalWarnings),
|
||||
reportSummary: renderSummary(totalErrors, totalWarnings),
|
||||
results: renderResults(results, metaData),
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = _identity;
|
||||
function _identity(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=identity.js.map
|
||||
@@ -0,0 +1,40 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.TaggedTemplateExpression = TaggedTemplateExpression;
|
||||
exports.TemplateElement = TemplateElement;
|
||||
exports.TemplateLiteral = TemplateLiteral;
|
||||
exports._printTemplate = _printTemplate;
|
||||
function TaggedTemplateExpression(node) {
|
||||
this.print(node.tag);
|
||||
{
|
||||
this.print(node.typeParameters);
|
||||
}
|
||||
this.print(node.quasi);
|
||||
}
|
||||
function TemplateElement() {
|
||||
throw new Error("TemplateElement printing is handled in TemplateLiteral");
|
||||
}
|
||||
function _printTemplate(node, substitutions) {
|
||||
const quasis = node.quasis;
|
||||
let partRaw = "`";
|
||||
for (let i = 0; i < quasis.length - 1; i++) {
|
||||
partRaw += quasis[i].value.raw;
|
||||
this.token(partRaw + "${", true);
|
||||
this.print(substitutions[i]);
|
||||
partRaw = "}";
|
||||
if (this.tokenMap) {
|
||||
const token = this.tokenMap.findMatching(node, "}", i);
|
||||
if (token) this._catchUpTo(token.loc.start);
|
||||
}
|
||||
}
|
||||
partRaw += quasis[quasis.length - 1].value.raw;
|
||||
this.token(partRaw + "`", true);
|
||||
}
|
||||
function TemplateLiteral(node) {
|
||||
this._printTemplate(node, node.expressions);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=template-literals.js.map
|
||||
@@ -0,0 +1,375 @@
|
||||
/**
|
||||
* @fileoverview Disallows or enforces spaces inside of object literals.
|
||||
* @author Jamund Ferguson
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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: "object-curly-spacing",
|
||||
url: "https://eslint.style/rules/js/object-curly-spacing",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description: "Enforce consistent spacing inside braces",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/object-curly-spacing",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
arraysInObjects: {
|
||||
type: "boolean",
|
||||
},
|
||||
objectsInObjects: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
requireSpaceBefore: "A space is required before '{{token}}'.",
|
||||
requireSpaceAfter: "A space is required after '{{token}}'.",
|
||||
unexpectedSpaceBefore:
|
||||
"There should be no space before '{{token}}'.",
|
||||
unexpectedSpaceAfter: "There should be no space after '{{token}}'.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const spaced = context.options[0] === "always",
|
||||
sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Determines whether an option is set, relative to the spacing option.
|
||||
* If spaced is "always", then check whether option is set to false.
|
||||
* If spaced is "never", then check whether option is set to true.
|
||||
* @param {Object} option The option to exclude.
|
||||
* @returns {boolean} Whether or not the property is excluded.
|
||||
*/
|
||||
function isOptionSet(option) {
|
||||
return context.options[1]
|
||||
? context.options[1][option] === !spaced
|
||||
: false;
|
||||
}
|
||||
|
||||
const options = {
|
||||
spaced,
|
||||
arraysInObjectsException: isOptionSet("arraysInObjects"),
|
||||
objectsInObjectsException: isOptionSet("objectsInObjects"),
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Reports that there shouldn't be a space after the first token
|
||||
* @param {ASTNode} node The node to report in the event of an error.
|
||||
* @param {Token} token The token to use for the report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportNoBeginningSpace(node, token) {
|
||||
const nextToken = context.sourceCode.getTokenAfter(token, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc: { start: token.loc.end, end: nextToken.loc.start },
|
||||
messageId: "unexpectedSpaceAfter",
|
||||
data: {
|
||||
token: token.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
token.range[1],
|
||||
nextToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that there shouldn't be a space before the last token
|
||||
* @param {ASTNode} node The node to report in the event of an error.
|
||||
* @param {Token} token The token to use for the report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportNoEndingSpace(node, token) {
|
||||
const previousToken = context.sourceCode.getTokenBefore(token, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc: { start: previousToken.loc.end, end: token.loc.start },
|
||||
messageId: "unexpectedSpaceBefore",
|
||||
data: {
|
||||
token: token.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
previousToken.range[1],
|
||||
token.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that there should be a space after the first token
|
||||
* @param {ASTNode} node The node to report in the event of an error.
|
||||
* @param {Token} token The token to use for the report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportRequiredBeginningSpace(node, token) {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
messageId: "requireSpaceAfter",
|
||||
data: {
|
||||
token: token.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(token, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that there should be a space before the last token
|
||||
* @param {ASTNode} node The node to report in the event of an error.
|
||||
* @param {Token} token The token to use for the report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function reportRequiredEndingSpace(node, token) {
|
||||
context.report({
|
||||
node,
|
||||
loc: token.loc,
|
||||
messageId: "requireSpaceBefore",
|
||||
data: {
|
||||
token: token.value,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(token, " ");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if spacing in curly braces is valid.
|
||||
* @param {ASTNode} node The AST node to check.
|
||||
* @param {Token} first The first token to check (should be the opening brace)
|
||||
* @param {Token} second The second token to check (should be first after the opening brace)
|
||||
* @param {Token} penultimate The penultimate token to check (should be last before closing brace)
|
||||
* @param {Token} last The last token to check (should be closing brace)
|
||||
* @returns {void}
|
||||
*/
|
||||
function validateBraceSpacing(node, first, second, penultimate, last) {
|
||||
if (astUtils.isTokenOnSameLine(first, second)) {
|
||||
const firstSpaced = sourceCode.isSpaceBetweenTokens(
|
||||
first,
|
||||
second,
|
||||
);
|
||||
|
||||
if (options.spaced && !firstSpaced) {
|
||||
reportRequiredBeginningSpace(node, first);
|
||||
}
|
||||
if (!options.spaced && firstSpaced && second.type !== "Line") {
|
||||
reportNoBeginningSpace(node, first);
|
||||
}
|
||||
}
|
||||
|
||||
if (astUtils.isTokenOnSameLine(penultimate, last)) {
|
||||
const shouldCheckPenultimate =
|
||||
(options.arraysInObjectsException &&
|
||||
astUtils.isClosingBracketToken(penultimate)) ||
|
||||
(options.objectsInObjectsException &&
|
||||
astUtils.isClosingBraceToken(penultimate));
|
||||
const penultimateType =
|
||||
shouldCheckPenultimate &&
|
||||
sourceCode.getNodeByRangeIndex(penultimate.range[0]).type;
|
||||
|
||||
const closingCurlyBraceMustBeSpaced =
|
||||
(options.arraysInObjectsException &&
|
||||
penultimateType === "ArrayExpression") ||
|
||||
(options.objectsInObjectsException &&
|
||||
(penultimateType === "ObjectExpression" ||
|
||||
penultimateType === "ObjectPattern"))
|
||||
? !options.spaced
|
||||
: options.spaced;
|
||||
|
||||
const lastSpaced = sourceCode.isSpaceBetweenTokens(
|
||||
penultimate,
|
||||
last,
|
||||
);
|
||||
|
||||
if (closingCurlyBraceMustBeSpaced && !lastSpaced) {
|
||||
reportRequiredEndingSpace(node, last);
|
||||
}
|
||||
if (!closingCurlyBraceMustBeSpaced && lastSpaced) {
|
||||
reportNoEndingSpace(node, last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets '}' token of an object node.
|
||||
*
|
||||
* Because the last token of object patterns might be a type annotation,
|
||||
* this traverses tokens preceded by the last property, then returns the
|
||||
* first '}' token.
|
||||
* @param {ASTNode} node The node to get. This node is an
|
||||
* ObjectExpression or an ObjectPattern. And this node has one or
|
||||
* more properties.
|
||||
* @returns {Token} '}' token.
|
||||
*/
|
||||
function getClosingBraceOfObject(node) {
|
||||
const lastProperty = node.properties.at(-1);
|
||||
|
||||
return sourceCode.getTokenAfter(
|
||||
lastProperty,
|
||||
astUtils.isClosingBraceToken,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a given object node if spacing in curly braces is invalid.
|
||||
* @param {ASTNode} node An ObjectExpression or ObjectPattern node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForObject(node) {
|
||||
if (node.properties.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const first = sourceCode.getFirstToken(node),
|
||||
last = getClosingBraceOfObject(node),
|
||||
second = sourceCode.getTokenAfter(first, {
|
||||
includeComments: true,
|
||||
}),
|
||||
penultimate = sourceCode.getTokenBefore(last, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
validateBraceSpacing(node, first, second, penultimate, last);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a given import node if spacing in curly braces is invalid.
|
||||
* @param {ASTNode} node An ImportDeclaration node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForImport(node) {
|
||||
if (node.specifiers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let firstSpecifier = node.specifiers[0];
|
||||
const lastSpecifier = node.specifiers.at(-1);
|
||||
|
||||
if (lastSpecifier.type !== "ImportSpecifier") {
|
||||
return;
|
||||
}
|
||||
if (firstSpecifier.type !== "ImportSpecifier") {
|
||||
firstSpecifier = node.specifiers[1];
|
||||
}
|
||||
|
||||
const first = sourceCode.getTokenBefore(firstSpecifier),
|
||||
last = sourceCode.getTokenAfter(
|
||||
lastSpecifier,
|
||||
astUtils.isNotCommaToken,
|
||||
),
|
||||
second = sourceCode.getTokenAfter(first, {
|
||||
includeComments: true,
|
||||
}),
|
||||
penultimate = sourceCode.getTokenBefore(last, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
validateBraceSpacing(node, first, second, penultimate, last);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a given export node if spacing in curly braces is invalid.
|
||||
* @param {ASTNode} node An ExportNamedDeclaration node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForExport(node) {
|
||||
if (node.specifiers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const firstSpecifier = node.specifiers[0],
|
||||
lastSpecifier = node.specifiers.at(-1),
|
||||
first = sourceCode.getTokenBefore(firstSpecifier),
|
||||
last = sourceCode.getTokenAfter(
|
||||
lastSpecifier,
|
||||
astUtils.isNotCommaToken,
|
||||
),
|
||||
second = sourceCode.getTokenAfter(first, {
|
||||
includeComments: true,
|
||||
}),
|
||||
penultimate = sourceCode.getTokenBefore(last, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
validateBraceSpacing(node, first, second, penultimate, last);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
// var {x} = y;
|
||||
ObjectPattern: checkForObject,
|
||||
|
||||
// var y = {x: 'y'}
|
||||
ObjectExpression: checkForObject,
|
||||
|
||||
// import {y} from 'x';
|
||||
ImportDeclaration: checkForImport,
|
||||
|
||||
// export {name} from 'yo';
|
||||
ExportNamedDeclaration: checkForExport,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = _arrayLikeToArray;
|
||||
function _arrayLikeToArray(arr, len) {
|
||||
if (len == null || len > arr.length) len = arr.length;
|
||||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
||||
return arr2;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=arrayLikeToArray.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["isCompatTag","tagName","test"],"sources":["../../../src/validators/react/isCompatTag.ts"],"sourcesContent":["export default function isCompatTag(tagName?: string): boolean {\n // Must start with a lowercase ASCII letter\n return !!tagName && /^[a-z]/.test(tagName);\n}\n"],"mappings":";;;;;;AAAe,SAASA,WAAWA,CAACC,OAAgB,EAAW;EAE7D,OAAO,CAAC,CAACA,OAAO,IAAI,QAAQ,CAACC,IAAI,CAACD,OAAO,CAAC;AAC5C","ignoreList":[]}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user