WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
|
||||
export default _default;
|
||||
/**
|
||||
* A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint.
|
||||
* We don't recommend using this directly; instead, extend from an earlier recommended rule.
|
||||
* @see {@link https://typescript-eslint.io/users/configs#base}
|
||||
*/
|
||||
declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.Config;
|
||||
@@ -0,0 +1,8 @@
|
||||
var regeneratorAsyncGen = require("./regeneratorAsyncGen.js");
|
||||
function _regeneratorAsync(n, e, r, t, o) {
|
||||
var a = regeneratorAsyncGen(n, e, r, t, o);
|
||||
return a.next().then(function (n) {
|
||||
return n.done ? n.value : a.next();
|
||||
});
|
||||
}
|
||||
module.exports = _regeneratorAsync, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,21 @@
|
||||
import createWebSocketStream from './lib/stream.js';
|
||||
import extension from './lib/extension.js';
|
||||
import PerMessageDeflate from './lib/permessage-deflate.js';
|
||||
import Receiver from './lib/receiver.js';
|
||||
import Sender from './lib/sender.js';
|
||||
import subprotocol from './lib/subprotocol.js';
|
||||
import WebSocket from './lib/websocket.js';
|
||||
import WebSocketServer from './lib/websocket-server.js';
|
||||
|
||||
export {
|
||||
createWebSocketStream,
|
||||
extension,
|
||||
PerMessageDeflate,
|
||||
Receiver,
|
||||
Sender,
|
||||
subprotocol,
|
||||
WebSocket,
|
||||
WebSocketServer
|
||||
};
|
||||
|
||||
export default WebSocket;
|
||||
@@ -0,0 +1,3 @@
|
||||
// This is an empty module that is served up when outside of a workerd environment
|
||||
// See the `exports` field in package.json
|
||||
export default {}
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { CustomEventName, InferCustomEventPayload } from './customEvent.js'
|
||||
|
||||
export type ModuleNamespace = Record<string, any> & {
|
||||
[Symbol.toStringTag]: 'Module'
|
||||
}
|
||||
|
||||
export interface ViteHotContext {
|
||||
readonly data: any
|
||||
|
||||
accept(): void
|
||||
accept(cb: (mod: ModuleNamespace | undefined) => void): void
|
||||
accept(dep: string, cb: (mod: ModuleNamespace | undefined) => void): void
|
||||
accept(
|
||||
deps: readonly string[],
|
||||
cb: (mods: Array<ModuleNamespace | undefined>) => void,
|
||||
): void
|
||||
|
||||
acceptExports(
|
||||
exportNames: string | readonly string[],
|
||||
cb?: (mod: ModuleNamespace | undefined) => void,
|
||||
): void
|
||||
|
||||
dispose(cb: (data: any) => void): void
|
||||
prune(cb: (data: any) => void): void
|
||||
invalidate(message?: string): void
|
||||
|
||||
on<T extends CustomEventName>(
|
||||
event: T,
|
||||
cb: (payload: InferCustomEventPayload<T>) => void,
|
||||
): void
|
||||
off<T extends CustomEventName>(
|
||||
event: T,
|
||||
cb: (payload: InferCustomEventPayload<T>) => void,
|
||||
): void
|
||||
send<T extends CustomEventName>(
|
||||
event: T,
|
||||
data?: InferCustomEventPayload<T>,
|
||||
): void
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
'use strict';
|
||||
|
||||
const { EMPTY_BUFFER } = require('./constants');
|
||||
|
||||
/**
|
||||
* Merges an array of buffers into a new buffer.
|
||||
*
|
||||
* @param {Buffer[]} list The array of buffers to concat
|
||||
* @param {Number} totalLength The total length of buffers in the list
|
||||
* @return {Buffer} The resulting buffer
|
||||
* @public
|
||||
*/
|
||||
function concat(list, totalLength) {
|
||||
if (list.length === 0) return EMPTY_BUFFER;
|
||||
if (list.length === 1) return list[0];
|
||||
|
||||
const target = Buffer.allocUnsafe(totalLength);
|
||||
let offset = 0;
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const buf = list[i];
|
||||
target.set(buf, offset);
|
||||
offset += buf.length;
|
||||
}
|
||||
|
||||
if (offset < totalLength) return target.slice(0, offset);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks a buffer using the given mask.
|
||||
*
|
||||
* @param {Buffer} source The buffer to mask
|
||||
* @param {Buffer} mask The mask to use
|
||||
* @param {Buffer} output The buffer where to store the result
|
||||
* @param {Number} offset The offset at which to start writing
|
||||
* @param {Number} length The number of bytes to mask.
|
||||
* @public
|
||||
*/
|
||||
function _mask(source, mask, output, offset, length) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
output[offset + i] = source[i] ^ mask[i & 3];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmasks a buffer using the given mask.
|
||||
*
|
||||
* @param {Buffer} buffer The buffer to unmask
|
||||
* @param {Buffer} mask The mask to use
|
||||
* @public
|
||||
*/
|
||||
function _unmask(buffer, mask) {
|
||||
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
|
||||
const length = buffer.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
buffer[i] ^= mask[i & 3];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a buffer to an `ArrayBuffer`.
|
||||
*
|
||||
* @param {Buffer} buf The buffer to convert
|
||||
* @return {ArrayBuffer} Converted buffer
|
||||
* @public
|
||||
*/
|
||||
function toArrayBuffer(buf) {
|
||||
if (buf.byteLength === buf.buffer.byteLength) {
|
||||
return buf.buffer;
|
||||
}
|
||||
|
||||
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts `data` to a `Buffer`.
|
||||
*
|
||||
* @param {*} data The data to convert
|
||||
* @return {Buffer} The buffer
|
||||
* @throws {TypeError}
|
||||
* @public
|
||||
*/
|
||||
function toBuffer(data) {
|
||||
toBuffer.readOnly = true;
|
||||
|
||||
if (Buffer.isBuffer(data)) return data;
|
||||
|
||||
let buf;
|
||||
|
||||
if (data instanceof ArrayBuffer) {
|
||||
buf = Buffer.from(data);
|
||||
} else if (ArrayBuffer.isView(data)) {
|
||||
buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
||||
} else {
|
||||
buf = Buffer.from(data);
|
||||
toBuffer.readOnly = false;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
try {
|
||||
const bufferUtil = require('bufferutil');
|
||||
const bu = bufferUtil.BufferUtil || bufferUtil;
|
||||
|
||||
module.exports = {
|
||||
concat,
|
||||
mask(source, mask, output, offset, length) {
|
||||
if (length < 48) _mask(source, mask, output, offset, length);
|
||||
else bu.mask(source, mask, output, offset, length);
|
||||
},
|
||||
toArrayBuffer,
|
||||
toBuffer,
|
||||
unmask(buffer, mask) {
|
||||
if (buffer.length < 32) _unmask(buffer, mask);
|
||||
else bu.unmask(buffer, mask);
|
||||
}
|
||||
};
|
||||
} catch (e) /* istanbul ignore next */ {
|
||||
module.exports = {
|
||||
concat,
|
||||
mask: _mask,
|
||||
toArrayBuffer,
|
||||
toBuffer,
|
||||
unmask: _unmask
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
var _typeof = require("./typeof.js")["default"];
|
||||
function _checkInRHS(e) {
|
||||
if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? _typeof(e) : "null"));
|
||||
return e;
|
||||
}
|
||||
module.exports = _checkInRHS, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defaultErrorMap = void 0;
|
||||
exports.setErrorMap = setErrorMap;
|
||||
exports.getErrorMap = getErrorMap;
|
||||
const en_js_1 = __importDefault(require("./locales/en.cjs"));
|
||||
exports.defaultErrorMap = en_js_1.default;
|
||||
let overrideErrorMap = en_js_1.default;
|
||||
function setErrorMap(map) {
|
||||
overrideErrorMap = map;
|
||||
}
|
||||
function getErrorMap() {
|
||||
return overrideErrorMap;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
.idea
|
||||
.zuulrc
|
||||
*~
|
||||
@@ -0,0 +1,39 @@
|
||||
import { w as workerInit } from '../chunks/init-forks.H5ZuobOQ.js';
|
||||
import { r as runVmTests, s as setupVmWorker } from '../chunks/vm.CXMd5FHa.js';
|
||||
import '../chunks/init.k9zZ9sLh.js';
|
||||
import 'node:fs';
|
||||
import 'node:module';
|
||||
import 'node:url';
|
||||
import 'pathe';
|
||||
import 'vite/module-runner';
|
||||
import '../chunks/startVitestModuleRunner.DB-7oCpn.js';
|
||||
import '@vitest/utils/helpers';
|
||||
import '../chunks/modules.BJuCwlRJ.js';
|
||||
import '../chunks/utils.BX5Fg8C4.js';
|
||||
import '@vitest/utils/timers';
|
||||
import '../path.js';
|
||||
import 'node:path';
|
||||
import '../module-evaluator.js';
|
||||
import 'node:vm';
|
||||
import '../chunks/traces.DT5aQ62U.js';
|
||||
import '@vitest/mocker';
|
||||
import '@vitest/mocker/redirect';
|
||||
import '../chunks/index.DC7d2Pf8.js';
|
||||
import 'node:console';
|
||||
import '@vitest/utils/serialize';
|
||||
import '@vitest/utils/error';
|
||||
import 'tinyrainbow';
|
||||
import '../chunks/rpc.MzXet3jl.js';
|
||||
import '../chunks/index.Chj8NDwU.js';
|
||||
import '@vitest/utils/source-map';
|
||||
import '../chunks/inspector.CvyFGlXm.js';
|
||||
import '../chunks/evaluatedModules.Dg1zASAC.js';
|
||||
import '../chunks/console.3WNpx0tS.js';
|
||||
import 'node:stream';
|
||||
import '@vitest/utils/resolver';
|
||||
import '@vitest/utils/constants';
|
||||
|
||||
workerInit({
|
||||
runTests: runVmTests,
|
||||
setup: setupVmWorker
|
||||
});
|
||||
@@ -0,0 +1,328 @@
|
||||
import { Codec, Decoder, Encoder, Offset } from './codec';
|
||||
import { ReadonlyUint8Array } from './readonly-uint8array';
|
||||
type AnyEncoder = Encoder<any>;
|
||||
type AnyDecoder = Decoder<any>;
|
||||
type AnyCodec = Codec<any>;
|
||||
/**
|
||||
* Configuration object for modifying the offset of an encoder, decoder, or codec.
|
||||
*
|
||||
* This type defines optional functions for adjusting the **pre-offset** (before encoding/decoding)
|
||||
* and the **post-offset** (after encoding/decoding). These functions allow precise control
|
||||
* over where data is written or read within a byte array.
|
||||
*
|
||||
* @property preOffset - A function that modifies the offset before encoding or decoding.
|
||||
* @property postOffset - A function that modifies the offset after encoding or decoding.
|
||||
*
|
||||
* @example
|
||||
* Moving the pre-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const config: OffsetConfig = {
|
||||
* preOffset: ({ preOffset }) => preOffset + 2,
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Moving the post-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const config: OffsetConfig = {
|
||||
* postOffset: ({ postOffset }) => postOffset + 2,
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using both pre-offset and post-offset together.
|
||||
* ```ts
|
||||
* const config: OffsetConfig = {
|
||||
* preOffset: ({ preOffset }) => preOffset + 2,
|
||||
* postOffset: ({ postOffset }) => postOffset + 4,
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @see {@link offsetEncoder}
|
||||
* @see {@link offsetDecoder}
|
||||
* @see {@link offsetCodec}
|
||||
*/
|
||||
type OffsetConfig = {
|
||||
postOffset?: PostOffsetFunction;
|
||||
preOffset?: PreOffsetFunction;
|
||||
};
|
||||
/**
|
||||
* Scope provided to the `preOffset` and `postOffset` functions,
|
||||
* containing contextual information about the current encoding or decoding process.
|
||||
*
|
||||
* The pre-offset function modifies where encoding or decoding begins,
|
||||
* while the post-offset function modifies where the next operation continues.
|
||||
*
|
||||
* @property bytes - The entire byte array being encoded or decoded.
|
||||
* @property preOffset - The original offset before encoding or decoding starts.
|
||||
* @property wrapBytes - A helper function that wraps offsets around the byte array length.
|
||||
*
|
||||
* @example
|
||||
* Using `wrapBytes` to wrap a negative offset to the end of the byte array.
|
||||
* ```ts
|
||||
* const config: OffsetConfig = {
|
||||
* preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves to last 4 bytes
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Adjusting the offset dynamically based on the byte array size.
|
||||
* ```ts
|
||||
* const config: OffsetConfig = {
|
||||
* preOffset: ({ bytes }) => bytes.length > 10 ? 4 : 2,
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @see {@link PreOffsetFunction}
|
||||
* @see {@link PostOffsetFunction}
|
||||
*/
|
||||
type PreOffsetFunctionScope = {
|
||||
/** The entire byte array. */
|
||||
bytes: ReadonlyUint8Array | Uint8Array;
|
||||
/** The original offset prior to encode or decode. */
|
||||
preOffset: Offset;
|
||||
/** Wraps the offset to the byte array length. */
|
||||
wrapBytes: (offset: Offset) => Offset;
|
||||
};
|
||||
/**
|
||||
* A function that modifies the pre-offset before encoding or decoding.
|
||||
*
|
||||
* This function is used to adjust the starting position before writing
|
||||
* or reading data in a byte array.
|
||||
*
|
||||
* @param scope - The current encoding or decoding context.
|
||||
* @returns The new offset at which encoding or decoding should start.
|
||||
*
|
||||
* @example
|
||||
* Skipping the first 2 bytes before writing or reading.
|
||||
* ```ts
|
||||
* const preOffset: PreOffsetFunction = ({ preOffset }) => preOffset + 2;
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Wrapping the offset to ensure it stays within bounds.
|
||||
* ```ts
|
||||
* const preOffset: PreOffsetFunction = ({ wrapBytes, preOffset }) => wrapBytes(preOffset + 10);
|
||||
* ```
|
||||
*
|
||||
* @see {@link OffsetConfig}
|
||||
* @see {@link PreOffsetFunctionScope}
|
||||
*/
|
||||
type PreOffsetFunction = (scope: PreOffsetFunctionScope) => Offset;
|
||||
/**
|
||||
* A function that modifies the post-offset after encoding or decoding.
|
||||
*
|
||||
* This function adjusts where the next encoder or decoder should start
|
||||
* after the current operation has completed.
|
||||
*
|
||||
* @param scope - The current encoding or decoding context, including the modified pre-offset
|
||||
* and the original post-offset.
|
||||
* @returns The new offset at which the next operation should begin.
|
||||
*
|
||||
* @example
|
||||
* Moving the post-offset forward by 4 bytes.
|
||||
* ```ts
|
||||
* const postOffset: PostOffsetFunction = ({ postOffset }) => postOffset + 4;
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Wrapping the post-offset within the byte array length.
|
||||
* ```ts
|
||||
* const postOffset: PostOffsetFunction = ({ wrapBytes, postOffset }) => wrapBytes(postOffset);
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Ensuring a minimum spacing of 8 bytes between values.
|
||||
* ```ts
|
||||
* const postOffset: PostOffsetFunction = ({ postOffset, newPreOffset }) =>
|
||||
* Math.max(postOffset, newPreOffset + 8);
|
||||
* ```
|
||||
*
|
||||
* @see {@link OffsetConfig}
|
||||
* @see {@link PreOffsetFunctionScope}
|
||||
*/
|
||||
type PostOffsetFunction = (scope: PreOffsetFunctionScope & {
|
||||
/** The modified offset used to encode or decode. */
|
||||
newPreOffset: Offset;
|
||||
/** The original offset returned by the encoder or decoder. */
|
||||
postOffset: Offset;
|
||||
}) => Offset;
|
||||
/**
|
||||
* Moves the offset of a given encoder before and/or after encoding.
|
||||
*
|
||||
* This function allows an encoder to write its encoded value at a different offset
|
||||
* than the one originally provided. It supports both pre-offset adjustments
|
||||
* (before encoding) and post-offset adjustments (after encoding).
|
||||
*
|
||||
* The pre-offset function determines where encoding should start, while the
|
||||
* post-offset function adjusts where the next encoder should continue writing.
|
||||
*
|
||||
* For more details, see {@link offsetCodec}.
|
||||
*
|
||||
* @typeParam TFrom - The type of the value to encode.
|
||||
*
|
||||
* @param encoder - The encoder to adjust.
|
||||
* @param config - An object specifying how the offset should be modified.
|
||||
* @returns A new encoder with adjusted offsets.
|
||||
*
|
||||
* @example
|
||||
* Moving the pre-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const encoder = offsetEncoder(getU32Encoder(), {
|
||||
* preOffset: ({ preOffset }) => preOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* encoder.write(42, bytes, 0); // Actually written at offset 2
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Moving the post-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const encoder = offsetEncoder(getU32Encoder(), {
|
||||
* postOffset: ({ postOffset }) => postOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* const nextOffset = encoder.write(42, bytes, 0); // Next encoder starts at offset 6 instead of 4
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using `wrapBytes` to ensure an offset wraps around the byte array length.
|
||||
* ```ts
|
||||
* const encoder = offsetEncoder(getU32Encoder(), {
|
||||
* preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes of the array
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* encoder.write(42, bytes, 0); // Writes at bytes.length - 4
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* If you need both encoding and decoding offsets to be adjusted, use {@link offsetCodec}.
|
||||
*
|
||||
* @see {@link offsetCodec}
|
||||
* @see {@link offsetDecoder}
|
||||
*/
|
||||
export declare function offsetEncoder<TEncoder extends AnyEncoder>(encoder: TEncoder, config: OffsetConfig): TEncoder;
|
||||
/**
|
||||
* Moves the offset of a given decoder before and/or after decoding.
|
||||
*
|
||||
* This function allows a decoder to read its input from a different offset
|
||||
* than the one originally provided. It supports both pre-offset adjustments
|
||||
* (before decoding) and post-offset adjustments (after decoding).
|
||||
*
|
||||
* The pre-offset function determines where decoding should start, while the
|
||||
* post-offset function adjusts where the next decoder should continue reading.
|
||||
*
|
||||
* For more details, see {@link offsetCodec}.
|
||||
*
|
||||
* @typeParam TTo - The type of the decoded value.
|
||||
*
|
||||
* @param decoder - The decoder to adjust.
|
||||
* @param config - An object specifying how the offset should be modified.
|
||||
* @returns A new decoder with adjusted offsets.
|
||||
*
|
||||
* @example
|
||||
* Moving the pre-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const decoder = offsetDecoder(getU32Decoder(), {
|
||||
* preOffset: ({ preOffset }) => preOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array([0, 0, 42, 0]); // Value starts at offset 2
|
||||
* decoder.read(bytes, 0); // Actually reads from offset 2
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Moving the post-offset forward by 2 bytes.
|
||||
* ```ts
|
||||
* const decoder = offsetDecoder(getU32Decoder(), {
|
||||
* postOffset: ({ postOffset }) => postOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array([42, 0, 0, 0]);
|
||||
* const [value, nextOffset] = decoder.read(bytes, 0); // Next decoder starts at offset 6 instead of 4
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using `wrapBytes` to read from the last 4 bytes of an array.
|
||||
* ```ts
|
||||
* const decoder = offsetDecoder(getU32Decoder(), {
|
||||
* preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes of the array
|
||||
* });
|
||||
* const bytes = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 42]); // Value stored at the last 4 bytes
|
||||
* decoder.read(bytes, 0); // Reads from bytes.length - 4
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* If you need both encoding and decoding offsets to be adjusted, use {@link offsetCodec}.
|
||||
*
|
||||
* @see {@link offsetCodec}
|
||||
* @see {@link offsetEncoder}
|
||||
*/
|
||||
export declare function offsetDecoder<TDecoder extends AnyDecoder>(decoder: TDecoder, config: OffsetConfig): TDecoder;
|
||||
/**
|
||||
* Moves the offset of a given codec before and/or after encoding and decoding.
|
||||
*
|
||||
* This function allows a codec to encode and decode values at custom offsets
|
||||
* within a byte array. It modifies both the **pre-offset** (where encoding/decoding starts)
|
||||
* and the **post-offset** (where the next operation should continue).
|
||||
*
|
||||
* This is particularly useful when working with structured binary formats
|
||||
* that require skipping reserved bytes, inserting padding, or aligning fields at
|
||||
* specific locations.
|
||||
*
|
||||
* @typeParam TFrom - The type of the value to encode.
|
||||
* @typeParam TTo - The type of the decoded value.
|
||||
*
|
||||
* @param codec - The codec to adjust.
|
||||
* @param config - An object specifying how the offset should be modified.
|
||||
* @returns A new codec with adjusted offsets.
|
||||
*
|
||||
* @example
|
||||
* Moving the pre-offset forward by 2 bytes when encoding and decoding.
|
||||
* ```ts
|
||||
* const codec = offsetCodec(getU32Codec(), {
|
||||
* preOffset: ({ preOffset }) => preOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* codec.write(42, bytes, 0); // Actually written at offset 2
|
||||
* codec.read(bytes, 0); // Actually read from offset 2
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Moving the post-offset forward by 2 bytes when encoding and decoding.
|
||||
* ```ts
|
||||
* const codec = offsetCodec(getU32Codec(), {
|
||||
* postOffset: ({ postOffset }) => postOffset + 2,
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* codec.write(42, bytes, 0);
|
||||
* // Next encoding starts at offset 6 instead of 4
|
||||
* codec.read(bytes, 0);
|
||||
* // Next decoding starts at offset 6 instead of 4
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using `wrapBytes` to loop around negative offsets.
|
||||
* ```ts
|
||||
* const codec = offsetCodec(getU32Codec(), {
|
||||
* preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes
|
||||
* });
|
||||
* const bytes = new Uint8Array(10);
|
||||
* codec.write(42, bytes, 0); // Writes at bytes.length - 4
|
||||
* codec.read(bytes, 0); // Reads from bytes.length - 4
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* If you only need to adjust offsets for encoding, use {@link offsetEncoder}.
|
||||
* If you only need to adjust offsets for decoding, use {@link offsetDecoder}.
|
||||
*
|
||||
* ```ts
|
||||
* const bytes = new Uint8Array(10);
|
||||
* offsetEncoder(getU32Encoder(), { preOffset: ({ preOffset }) => preOffset + 2 }).write(42, bytes, 0);
|
||||
* const [value] = offsetDecoder(getU32Decoder(), { preOffset: ({ preOffset }) => preOffset + 2 }).read(bytes, 0);
|
||||
* ```
|
||||
*
|
||||
* @see {@link offsetEncoder}
|
||||
* @see {@link offsetDecoder}
|
||||
*/
|
||||
export declare function offsetCodec<TCodec extends AnyCodec>(codec: TCodec, config: OffsetConfig): TCodec;
|
||||
export {};
|
||||
//# sourceMappingURL=offset-codec.d.ts.map
|
||||
@@ -0,0 +1,7 @@
|
||||
export { parse, parseForESLint, type ParserOptions } from './parser';
|
||||
export { clearCaches, createProgram, type ParserServices, type ParserServicesWithoutTypeInformation, type ParserServicesWithTypeInformation, withoutProjectParserOptions, } from '@typescript-eslint/typescript-estree';
|
||||
export declare const version: string;
|
||||
export declare const meta: {
|
||||
name: string;
|
||||
version: string;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
import type { LibDefinition } from '../variable';
|
||||
export declare const es2018_intl: LibDefinition;
|
||||
@@ -0,0 +1,329 @@
|
||||
export type VisitTraversalStep = $eslintcore.VisitTraversalStep;
|
||||
export type CallTraversalStep = $eslintcore.CallTraversalStep;
|
||||
export type TraversalStep = $eslintcore.TraversalStep;
|
||||
export type SourceLocation = $eslintcore.SourceLocation;
|
||||
export type SourceLocationWithOffset = $eslintcore.SourceLocationWithOffset;
|
||||
export type SourceRange = $eslintcore.SourceRange;
|
||||
export type IDirective = $eslintcore.Directive;
|
||||
export type DirectiveType = $eslintcore.DirectiveType;
|
||||
export type SourceCodeBaseTypeOptions = $eslintcore.SourceCodeBaseTypeOptions;
|
||||
export type TextSourceCode<Options extends SourceCodeBaseTypeOptions = $eslintcore.SourceCodeBaseTypeOptions> = import("@eslint/core").TextSourceCode<Options>;
|
||||
export type RuleVisitor = $eslintcore.RuleVisitor;
|
||||
export type CustomRuleVisitorWithExit<RuleVisitorType extends RuleVisitor> = import("./types.ts").CustomRuleVisitorWithExit<RuleVisitorType>;
|
||||
export type CustomRuleTypeDefinitions = $typests.CustomRuleTypeDefinitions;
|
||||
export type CustomRuleDefinitionType<LanguageSpecificOptions extends Omit<import("@eslint/core").RuleDefinitionTypeOptions, keyof CustomRuleTypeDefinitions>, Options extends Partial<CustomRuleTypeDefinitions>> = import("./types.ts").CustomRuleDefinitionType<LanguageSpecificOptions, Options>;
|
||||
export type RuleConfig = $eslintcore.RuleConfig;
|
||||
export type RulesConfig = $eslintcore.RulesConfig;
|
||||
export type StringConfig = $typests.StringConfig;
|
||||
export type BooleanConfig = $typests.BooleanConfig;
|
||||
/**
|
||||
* A class to represent a step in the traversal process where a
|
||||
* method is called.
|
||||
* @implements {CallTraversalStep}
|
||||
*/
|
||||
export class CallMethodStep implements CallTraversalStep {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options The options for the step.
|
||||
* @param {string} options.target The target of the step.
|
||||
* @param {Array<any>} options.args The arguments of the step.
|
||||
*/
|
||||
constructor({ target, args }: {
|
||||
target: string;
|
||||
args: Array<any>;
|
||||
});
|
||||
/**
|
||||
* The type of the step.
|
||||
* @type {"call"}
|
||||
* @readonly
|
||||
*/
|
||||
readonly type: "call";
|
||||
/**
|
||||
* The kind of the step. Represents the same data as the `type` property
|
||||
* but it's a number for performance.
|
||||
* @type {2}
|
||||
* @readonly
|
||||
*/
|
||||
readonly kind: 2;
|
||||
/**
|
||||
* The name of the method to call.
|
||||
* @type {string}
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* The arguments to pass to the method.
|
||||
* @type {Array<any>}
|
||||
*/
|
||||
args: Array<any>;
|
||||
}
|
||||
/**
|
||||
* Object to parse ESLint configuration comments.
|
||||
*/
|
||||
export class ConfigCommentParser {
|
||||
/**
|
||||
* Parses a list of "name:string_value" or/and "name" options divided by comma or
|
||||
* whitespace. Used for "global" comments.
|
||||
* @param {string} string The string to parse.
|
||||
* @returns {StringConfig} Result map object of names and string values, or null values if no value was provided.
|
||||
*/
|
||||
parseStringConfig(string: string): StringConfig;
|
||||
/**
|
||||
* Parses a JSON-like config.
|
||||
* @param {string} string The string to parse.
|
||||
* @returns {({ok: true, config: RulesConfig}|{ok: false, error: {message: string}})} Result map object
|
||||
*/
|
||||
parseJSONLikeConfig(string: string): ({
|
||||
ok: true;
|
||||
config: RulesConfig;
|
||||
} | {
|
||||
ok: false;
|
||||
error: {
|
||||
message: string;
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Parses a config of values separated by comma.
|
||||
* @param {string} string The string to parse.
|
||||
* @returns {BooleanConfig} Result map of values and true values
|
||||
*/
|
||||
parseListConfig(string: string): BooleanConfig;
|
||||
/**
|
||||
* Parses a directive comment into directive text and value.
|
||||
* @param {string} string The string with the directive to be parsed.
|
||||
* @returns {DirectiveComment|undefined} The parsed directive or `undefined` if the directive is invalid.
|
||||
*/
|
||||
parseDirective(string: string): DirectiveComment | undefined;
|
||||
#private;
|
||||
}
|
||||
/**
|
||||
* A class to represent a directive comment.
|
||||
* @implements {IDirective}
|
||||
*/
|
||||
export class Directive implements IDirective {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options The options for the directive.
|
||||
* @param {"disable"|"enable"|"disable-next-line"|"disable-line"} options.type The type of directive.
|
||||
* @param {unknown} options.node The node representing the directive.
|
||||
* @param {string} options.value The value of the directive.
|
||||
* @param {string} options.justification The justification for the directive.
|
||||
*/
|
||||
constructor({ type, node, value, justification }: {
|
||||
type: "disable" | "enable" | "disable-next-line" | "disable-line";
|
||||
node: unknown;
|
||||
value: string;
|
||||
justification: string;
|
||||
});
|
||||
/**
|
||||
* The type of directive.
|
||||
* @type {DirectiveType}
|
||||
* @readonly
|
||||
*/
|
||||
readonly type: DirectiveType;
|
||||
/**
|
||||
* The node representing the directive.
|
||||
* @type {unknown}
|
||||
* @readonly
|
||||
*/
|
||||
readonly node: unknown;
|
||||
/**
|
||||
* Everything after the "eslint-disable" portion of the directive,
|
||||
* but before the "--" that indicates the justification.
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
readonly value: string;
|
||||
/**
|
||||
* The justification for the directive.
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
readonly justification: string;
|
||||
}
|
||||
/**
|
||||
* Source Code Base Object
|
||||
* @template {SourceCodeBaseTypeOptions & {RootNode: object, SyntaxElementWithLoc: object}} [Options=SourceCodeBaseTypeOptions & {RootNode: object, SyntaxElementWithLoc: object}]
|
||||
* @implements {TextSourceCode<Options>}
|
||||
*/
|
||||
export class TextSourceCodeBase<Options extends SourceCodeBaseTypeOptions & {
|
||||
RootNode: object;
|
||||
SyntaxElementWithLoc: object;
|
||||
} = $eslintcore.SourceCodeBaseTypeOptions & {
|
||||
RootNode: object;
|
||||
SyntaxElementWithLoc: object;
|
||||
}> implements TextSourceCode<Options> {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options The options for the instance.
|
||||
* @param {string} options.text The source code text.
|
||||
* @param {Options['RootNode']} options.ast The root AST node.
|
||||
* @param {RegExp} [options.lineEndingPattern] The pattern to match lineEndings in the source code. Defaults to `/\r?\n/u`.
|
||||
*/
|
||||
constructor({ text, ast, lineEndingPattern }: {
|
||||
text: string;
|
||||
ast: Options["RootNode"];
|
||||
lineEndingPattern?: RegExp;
|
||||
});
|
||||
/**
|
||||
* The AST of the source code.
|
||||
* @type {Options['RootNode']}
|
||||
*/
|
||||
ast: Options["RootNode"];
|
||||
/**
|
||||
* The text of the source code.
|
||||
* @type {string}
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* Returns the loc information for the given node or token.
|
||||
* @param {Options['SyntaxElementWithLoc']} nodeOrToken The node or token to get the loc information for.
|
||||
* @returns {SourceLocation} The loc information for the node or token.
|
||||
* @throws {Error} If the node or token does not have loc information.
|
||||
*/
|
||||
getLoc(nodeOrToken: Options["SyntaxElementWithLoc"]): SourceLocation;
|
||||
/**
|
||||
* Converts a source text index into a `{ line: number, column: number }` pair.
|
||||
* @param {number} index The index of a character in a file.
|
||||
* @throws {TypeError|RangeError} If non-numeric index or index out of range.
|
||||
* @returns {{line: number, column: number}} A `{ line: number, column: number }` location object with 0 or 1-indexed line and 0 or 1-indexed column based on language.
|
||||
* @public
|
||||
*/
|
||||
public getLocFromIndex(index: number): {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
/**
|
||||
* Converts a `{ line: number, column: number }` pair into a source text index.
|
||||
* @param {Object} loc A line/column location.
|
||||
* @param {number} loc.line The line number of the location. (0 or 1-indexed based on language.)
|
||||
* @param {number} loc.column The column number of the location. (0 or 1-indexed based on language.)
|
||||
* @throws {TypeError|RangeError} If `loc` is not an object with a numeric
|
||||
* `line` and `column`, if the `line` is less than or equal to zero or
|
||||
* the `line` or `column` is out of the expected range.
|
||||
* @returns {number} The index of the line/column location in a file.
|
||||
* @public
|
||||
*/
|
||||
public getIndexFromLoc(loc: {
|
||||
line: number;
|
||||
column: number;
|
||||
}): number;
|
||||
/**
|
||||
* Returns the range information for the given node or token.
|
||||
* @param {Options['SyntaxElementWithLoc']} nodeOrToken The node or token to get the range information for.
|
||||
* @returns {SourceRange} The range information for the node or token.
|
||||
* @throws {Error} If the node or token does not have range information.
|
||||
*/
|
||||
getRange(nodeOrToken: Options["SyntaxElementWithLoc"]): SourceRange;
|
||||
/**
|
||||
* Returns the parent of the given node.
|
||||
* @param {Options['SyntaxElementWithLoc']} node The node to get the parent of.
|
||||
* @returns {Options['SyntaxElementWithLoc']|undefined} The parent of the node.
|
||||
* @throws {Error} If the method is not implemented in the subclass.
|
||||
*/
|
||||
getParent(node: Options["SyntaxElementWithLoc"]): Options["SyntaxElementWithLoc"] | undefined;
|
||||
/**
|
||||
* Gets all the ancestors of a given node
|
||||
* @param {Options['SyntaxElementWithLoc']} node The node
|
||||
* @returns {Array<Options['SyntaxElementWithLoc']>} All the ancestor nodes in the AST, not including the provided node, starting
|
||||
* from the root node at index 0 and going inwards to the parent node.
|
||||
* @throws {TypeError} When `node` is missing.
|
||||
*/
|
||||
getAncestors(node: Options["SyntaxElementWithLoc"]): Array<Options["SyntaxElementWithLoc"]>;
|
||||
/**
|
||||
* Gets the source code for the given node.
|
||||
* @param {Options['SyntaxElementWithLoc']} [node] The AST node to get the text for.
|
||||
* @param {number} [beforeCount] The number of characters before the node to retrieve.
|
||||
* @param {number} [afterCount] The number of characters after the node to retrieve.
|
||||
* @returns {string} The text representing the AST node.
|
||||
* @public
|
||||
*/
|
||||
public getText(node?: Options["SyntaxElementWithLoc"], beforeCount?: number, afterCount?: number): string;
|
||||
/**
|
||||
* Gets the entire source text split into an array of lines.
|
||||
* @returns {Array<string>} The source text as an array of lines.
|
||||
* @public
|
||||
*/
|
||||
public get lines(): Array<string>;
|
||||
/**
|
||||
* Traverse the source code and return the steps that were taken.
|
||||
* @returns {Iterable<TraversalStep>} The steps that were taken while traversing the source code.
|
||||
*/
|
||||
traverse(): Iterable<TraversalStep>;
|
||||
#private;
|
||||
}
|
||||
/**
|
||||
* A class to represent a step in the traversal process where a node is visited.
|
||||
* @implements {VisitTraversalStep}
|
||||
*/
|
||||
export class VisitNodeStep implements VisitTraversalStep {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options The options for the step.
|
||||
* @param {object} options.target The target of the step.
|
||||
* @param {1|2} options.phase The phase of the step.
|
||||
* @param {Array<any>} options.args The arguments of the step.
|
||||
*/
|
||||
constructor({ target, phase, args }: {
|
||||
target: object;
|
||||
phase: 1 | 2;
|
||||
args: Array<any>;
|
||||
});
|
||||
/**
|
||||
* The type of the step.
|
||||
* @type {"visit"}
|
||||
* @readonly
|
||||
*/
|
||||
readonly type: "visit";
|
||||
/**
|
||||
* The kind of the step. Represents the same data as the `type` property
|
||||
* but it's a number for performance.
|
||||
* @type {1}
|
||||
* @readonly
|
||||
*/
|
||||
readonly kind: 1;
|
||||
/**
|
||||
* The target of the step.
|
||||
* @type {object}
|
||||
*/
|
||||
target: object;
|
||||
/**
|
||||
* The phase of the step.
|
||||
* @type {1|2}
|
||||
*/
|
||||
phase: 1 | 2;
|
||||
/**
|
||||
* The arguments of the step.
|
||||
* @type {Array<any>}
|
||||
*/
|
||||
args: Array<any>;
|
||||
}
|
||||
import type * as $eslintcore from "@eslint/core";
|
||||
import type * as $typests from "./types.ts";
|
||||
/**
|
||||
* Represents a directive comment.
|
||||
*/
|
||||
declare class DirectiveComment {
|
||||
/**
|
||||
* Creates a new directive comment.
|
||||
* @param {string} label The label of the directive.
|
||||
* @param {string} value The value of the directive.
|
||||
* @param {string} justification The justification of the directive.
|
||||
*/
|
||||
constructor(label: string, value: string, justification: string);
|
||||
/**
|
||||
* The label of the directive, such as "eslint", "eslint-disable", etc.
|
||||
* @type {string}
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* The value of the directive (the string after the label).
|
||||
* @type {string}
|
||||
*/
|
||||
value: string;
|
||||
/**
|
||||
* The justification of the directive (the string after the --).
|
||||
* @type {string}
|
||||
*/
|
||||
justification: string;
|
||||
}
|
||||
export {};
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { TSESTree } from '@typescript-eslint/utils';
|
||||
/**
|
||||
* Returns the result of the string conversion applied to the evaluated value of the given expression node,
|
||||
* if it can be determined statically.
|
||||
*
|
||||
* This function returns a `string` value for all `Literal` nodes and simple `TemplateLiteral` nodes only.
|
||||
* In all other cases, this function returns `null`.
|
||||
* @param node Expression node.
|
||||
* @returns String value if it can be determined. Otherwise, `null`.
|
||||
*/
|
||||
export declare function getStaticStringValue(node: TSESTree.Node): string | null;
|
||||
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
// adapted from https://github.com/eslint/eslint/blob/5bdaae205c3a0089ea338b382df59e21d5b06436/lib/rules/utils/ast-utils.js#L191-L230
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getStaticStringValue = getStaticStringValue;
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const isNullLiteral_1 = require("./isNullLiteral");
|
||||
/**
|
||||
* Returns the result of the string conversion applied to the evaluated value of the given expression node,
|
||||
* if it can be determined statically.
|
||||
*
|
||||
* This function returns a `string` value for all `Literal` nodes and simple `TemplateLiteral` nodes only.
|
||||
* In all other cases, this function returns `null`.
|
||||
* @param node Expression node.
|
||||
* @returns String value if it can be determined. Otherwise, `null`.
|
||||
*/
|
||||
function getStaticStringValue(node) {
|
||||
switch (node.type) {
|
||||
case utils_1.AST_NODE_TYPES.Literal:
|
||||
// eslint-disable-next-line eqeqeq, @typescript-eslint/internal/eqeq-nullish -- intentional strict comparison for literal value
|
||||
if (node.value === null) {
|
||||
if ((0, isNullLiteral_1.isNullLiteral)(node)) {
|
||||
return String(node.value); // "null"
|
||||
}
|
||||
if ('regex' in node) {
|
||||
return `/${node.regex.pattern}/${node.regex.flags}`;
|
||||
}
|
||||
if ('bigint' in node) {
|
||||
return node.bigint;
|
||||
}
|
||||
// Otherwise, this is an unknown literal. The function will return null.
|
||||
}
|
||||
else {
|
||||
return String(node.value);
|
||||
}
|
||||
break;
|
||||
case utils_1.AST_NODE_TYPES.TemplateLiteral:
|
||||
if (node.expressions.length === 0 && node.quasis.length === 1) {
|
||||
return node.quasis[0].value.cooked;
|
||||
}
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag `else` after a `return` in `if`
|
||||
* @author Ian Christian Myers
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
const FixTracker = require("./utils/fix-tracker");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("eslint-scope").Scope} Scope */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [{ allowElseIf: true }],
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow `else` blocks after `return` statements in `if` statements",
|
||||
recommended: false,
|
||||
frozen: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-else-return",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allowElseIf: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unexpected: "Unnecessary 'else' after 'return'.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const [{ allowElseIf }] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks whether the given names can be safely used to declare block-scoped variables
|
||||
* in the given scope. Name collisions can produce redeclaration syntax errors,
|
||||
* or silently change references and modify behavior of the original code.
|
||||
*
|
||||
* This is not a generic function. In particular, it is assumed that the scope is a function scope or
|
||||
* a function's inner scope, and that the names can be valid identifiers in the given scope.
|
||||
* @param {string[]} names Array of variable names.
|
||||
* @param {Scope} scope Function scope or a function's inner scope.
|
||||
* @returns {boolean} True if all names can be safely declared, false otherwise.
|
||||
*/
|
||||
function isSafeToDeclare(names, scope) {
|
||||
if (names.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const functionScope = scope.variableScope;
|
||||
|
||||
/*
|
||||
* If this is a function scope, scope.variables will contain parameters, implicit variables such as "arguments",
|
||||
* all function-scoped variables ('var'), and block-scoped variables defined in the scope.
|
||||
* If this is an inner scope, scope.variables will contain block-scoped variables defined in the scope.
|
||||
*
|
||||
* Redeclaring any of these would cause a syntax error, except for the implicit variables.
|
||||
*/
|
||||
const declaredVariables = scope.variables.filter(
|
||||
({ defs }) => defs.length > 0,
|
||||
);
|
||||
|
||||
if (declaredVariables.some(({ name }) => names.includes(name))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Redeclaring a catch variable would also cause a syntax error.
|
||||
if (scope !== functionScope && scope.upper.type === "catch") {
|
||||
if (
|
||||
scope.upper.variables.some(({ name }) =>
|
||||
names.includes(name),
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Redeclaring an implicit variable, such as "arguments", would not cause a syntax error.
|
||||
* However, if the variable was used, declaring a new one with the same name would change references
|
||||
* and modify behavior.
|
||||
*/
|
||||
const usedImplicitVariables = scope.variables.filter(
|
||||
({ defs, references }) =>
|
||||
defs.length === 0 && references.length > 0,
|
||||
);
|
||||
|
||||
if (
|
||||
usedImplicitVariables.some(({ name }) => names.includes(name))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Declaring a variable with a name that was already used to reference a variable from an upper scope
|
||||
* would change references and modify behavior.
|
||||
*/
|
||||
if (scope.through.some(t => names.includes(t.identifier.name))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the scope is an inner scope (not the function scope), an uninitialized `var` variable declared inside
|
||||
* the scope node (directly or in one of its descendants) is neither declared nor 'through' in the scope.
|
||||
*
|
||||
* For example, this would be a syntax error "Identifier 'a' has already been declared":
|
||||
* function foo() { if (bar) { let a; if (baz) { var a; } } }
|
||||
*/
|
||||
if (scope !== functionScope) {
|
||||
const scopeNodeRange = scope.block.range;
|
||||
const variablesToCheck = functionScope.variables.filter(
|
||||
({ name }) => names.includes(name),
|
||||
);
|
||||
|
||||
if (
|
||||
variablesToCheck.some(v =>
|
||||
v.defs.some(
|
||||
({ node: { range } }) =>
|
||||
scopeNodeRange[0] <= range[0] &&
|
||||
range[1] <= scopeNodeRange[1],
|
||||
),
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the removal of `else` and its braces is safe from variable name collisions.
|
||||
* @param {Node} node The 'else' node.
|
||||
* @param {Scope} scope The scope in which the node and the whole 'if' statement is.
|
||||
* @returns {boolean} True if it is safe, false otherwise.
|
||||
*/
|
||||
function isSafeFromNameCollisions(node, scope) {
|
||||
if (node.type === "FunctionDeclaration") {
|
||||
// Conditional function declaration. Scope and hoisting are unpredictable, different engines work differently.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.type !== "BlockStatement") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const elseBlockScope = scope.childScopes.find(
|
||||
({ block }) => block === node,
|
||||
);
|
||||
|
||||
if (!elseBlockScope) {
|
||||
// ecmaVersion < 6, `else` block statement cannot have its own scope, no possible collisions.
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* elseBlockScope is supposed to merge into its upper scope. elseBlockScope.variables array contains
|
||||
* only block-scoped variables (such as let and const variables or class and function declarations)
|
||||
* defined directly in the elseBlockScope. These are exactly the only names that could cause collisions.
|
||||
*/
|
||||
const namesToCheck = elseBlockScope.variables.map(
|
||||
({ name }) => name,
|
||||
);
|
||||
|
||||
return isSafeToDeclare(namesToCheck, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the context report if rule is violated
|
||||
* @param {Node} elseNode The 'else' node
|
||||
* @returns {void}
|
||||
*/
|
||||
function displayReport(elseNode) {
|
||||
const currentScope = sourceCode.getScope(elseNode.parent);
|
||||
|
||||
context.report({
|
||||
node: elseNode,
|
||||
messageId: "unexpected",
|
||||
fix(fixer) {
|
||||
if (!isSafeFromNameCollisions(elseNode, currentScope)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const startToken = sourceCode.getFirstToken(elseNode);
|
||||
const elseToken = sourceCode.getTokenBefore(startToken);
|
||||
const source = sourceCode.getText(elseNode);
|
||||
const lastIfToken = sourceCode.getTokenBefore(elseToken);
|
||||
let fixedSource, firstTokenOfElseBlock;
|
||||
|
||||
if (
|
||||
startToken.type === "Punctuator" &&
|
||||
startToken.value === "{"
|
||||
) {
|
||||
firstTokenOfElseBlock =
|
||||
sourceCode.getTokenAfter(startToken);
|
||||
} else {
|
||||
firstTokenOfElseBlock = startToken;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the if block does not have curly braces and does not end in a semicolon
|
||||
* and the else block starts with (, [, /, +, ` or -, then it is not
|
||||
* safe to remove the else keyword, because ASI will not add a semicolon
|
||||
* after the if block
|
||||
*/
|
||||
const ifBlockMaybeUnsafe =
|
||||
elseNode.parent.consequent.type !== "BlockStatement" &&
|
||||
lastIfToken.value !== ";";
|
||||
const elseBlockUnsafe = /^[([/+`-]/u.test(
|
||||
firstTokenOfElseBlock.value,
|
||||
);
|
||||
|
||||
if (ifBlockMaybeUnsafe && elseBlockUnsafe) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const endToken = sourceCode.getLastToken(elseNode);
|
||||
const lastTokenOfElseBlock =
|
||||
sourceCode.getTokenBefore(endToken);
|
||||
|
||||
if (lastTokenOfElseBlock.value !== ";") {
|
||||
const nextToken = sourceCode.getTokenAfter(endToken);
|
||||
|
||||
const nextTokenUnsafe =
|
||||
nextToken && /^[([/+`-]/u.test(nextToken.value);
|
||||
const nextTokenOnSameLine =
|
||||
nextToken &&
|
||||
nextToken.loc.start.line ===
|
||||
lastTokenOfElseBlock.loc.start.line;
|
||||
|
||||
/*
|
||||
* If the else block contents does not end in a semicolon,
|
||||
* and the else block starts with (, [, /, +, ` or -, then it is not
|
||||
* safe to remove the else block, because ASI will not add a semicolon
|
||||
* after the remaining else block contents
|
||||
*/
|
||||
if (
|
||||
nextTokenUnsafe ||
|
||||
(nextTokenOnSameLine && nextToken.value !== "}")
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
startToken.type === "Punctuator" &&
|
||||
startToken.value === "{"
|
||||
) {
|
||||
fixedSource = source.slice(1, -1);
|
||||
} else {
|
||||
fixedSource = source;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extend the replacement range to include the entire
|
||||
* function to avoid conflicting with no-useless-return.
|
||||
* https://github.com/eslint/eslint/issues/8026
|
||||
*
|
||||
* Also, to avoid name collisions between two else blocks.
|
||||
*/
|
||||
return new FixTracker(fixer, sourceCode)
|
||||
.retainEnclosingFunction(elseNode)
|
||||
.replaceTextRange(
|
||||
[elseToken.range[0], elseNode.range[1]],
|
||||
fixedSource,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the node is a ReturnStatement
|
||||
* @param {Node} node The node being evaluated
|
||||
* @returns {boolean} True if node is a return
|
||||
*/
|
||||
function checkForReturn(node) {
|
||||
return node.type === "ReturnStatement";
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive return checking, does not iterate through the whole
|
||||
* BlockStatement because we make the assumption that the ReturnStatement
|
||||
* will be the last node in the body of the BlockStatement.
|
||||
* @param {Node} node The consequent/alternate node
|
||||
* @returns {boolean} True if it has a return
|
||||
*/
|
||||
function naiveHasReturn(node) {
|
||||
if (node.type === "BlockStatement") {
|
||||
const body = node.body,
|
||||
lastChildNode = body.at(-1);
|
||||
|
||||
return lastChildNode && checkForReturn(lastChildNode);
|
||||
}
|
||||
return checkForReturn(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the node is valid for evaluation,
|
||||
* meaning it has an else.
|
||||
* @param {Node} node The node being evaluated
|
||||
* @returns {boolean} True if the node is valid
|
||||
*/
|
||||
function hasElse(node) {
|
||||
return node.alternate && node.consequent;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the consequent is an IfStatement, check to see if it has an else
|
||||
* and both its consequent and alternate path return, meaning this is
|
||||
* a nested case of rule violation. If-Else not considered currently.
|
||||
* @param {Node} node The consequent node
|
||||
* @returns {boolean} True if this is a nested rule violation
|
||||
*/
|
||||
function checkForIf(node) {
|
||||
return (
|
||||
node.type === "IfStatement" &&
|
||||
hasElse(node) &&
|
||||
naiveHasReturn(node.alternate) &&
|
||||
naiveHasReturn(node.consequent)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the consequent/body node to make sure it is not
|
||||
* a ReturnStatement or an IfStatement that returns on both
|
||||
* code paths.
|
||||
* @param {Node} node The consequent or body node
|
||||
* @returns {boolean} `true` if it is a Return/If node that always returns.
|
||||
*/
|
||||
function checkForReturnOrIf(node) {
|
||||
return checkForReturn(node) || checkForIf(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a node returns in every codepath.
|
||||
* @param {Node} node The node to be checked
|
||||
* @returns {boolean} `true` if it returns on every codepath.
|
||||
*/
|
||||
function alwaysReturns(node) {
|
||||
if (node.type === "BlockStatement") {
|
||||
// If we have a BlockStatement, check each consequent body node.
|
||||
return node.body.some(checkForReturnOrIf);
|
||||
}
|
||||
|
||||
/*
|
||||
* If not a block statement, make sure the consequent isn't a
|
||||
* ReturnStatement or an IfStatement with returns on both paths.
|
||||
*/
|
||||
return checkForReturnOrIf(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the if statement, but don't catch else-if blocks.
|
||||
* @returns {void}
|
||||
* @param {Node} node The node for the if statement to check
|
||||
* @private
|
||||
*/
|
||||
function checkIfWithoutElse(node) {
|
||||
const parent = node.parent;
|
||||
|
||||
/*
|
||||
* Fixing this would require splitting one statement into two, so no error should
|
||||
* be reported if this node is in a position where only one statement is allowed.
|
||||
*/
|
||||
if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const consequents = [];
|
||||
let alternate;
|
||||
|
||||
for (
|
||||
let currentNode = node;
|
||||
currentNode.type === "IfStatement";
|
||||
currentNode = currentNode.alternate
|
||||
) {
|
||||
if (!currentNode.alternate) {
|
||||
return;
|
||||
}
|
||||
consequents.push(currentNode.consequent);
|
||||
alternate = currentNode.alternate;
|
||||
}
|
||||
|
||||
if (consequents.every(alwaysReturns)) {
|
||||
displayReport(alternate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the if statement
|
||||
* @returns {void}
|
||||
* @param {Node} node The node for the if statement to check
|
||||
* @private
|
||||
*/
|
||||
function checkIfWithElse(node) {
|
||||
const parent = node.parent;
|
||||
|
||||
/*
|
||||
* Fixing this would require splitting one statement into two, so no error should
|
||||
* be reported if this node is in a position where only one statement is allowed.
|
||||
*/
|
||||
if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const alternate = node.alternate;
|
||||
|
||||
if (alternate && alwaysReturns(node.consequent)) {
|
||||
displayReport(alternate);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public API
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"IfStatement:exit": allowElseIf
|
||||
? checkIfWithoutElse
|
||||
: checkIfWithElse,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "false" && $TRAVIS_JOB_NUMBER =~ ".3" ]]; then
|
||||
git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qE '\.md$|^LICENSE$|travis-gh-pages$' && {
|
||||
rm -rf ../gh-pages
|
||||
git clone -b gh-pages --single-branch https://${GITHUB_TOKEN}@github.com/ajv-validator/ajv.git ../gh-pages
|
||||
mkdir -p ../gh-pages/_source
|
||||
cp *.md ../gh-pages/_source
|
||||
cp LICENSE ../gh-pages/_source
|
||||
currentDir=$(pwd)
|
||||
cd ../gh-pages
|
||||
$currentDir/node_modules/.bin/gh-pages-generator
|
||||
# remove logo from README
|
||||
sed -i -E "s/<img[^>]+ajv_logo[^>]+>//" index.md
|
||||
git config user.email "$GIT_USER_EMAIL"
|
||||
git config user.name "$GIT_USER_NAME"
|
||||
git add .
|
||||
git commit -am "updated by travis build #$TRAVIS_BUILD_NUMBER"
|
||||
git push --quiet origin gh-pages > /dev/null 2>&1
|
||||
}
|
||||
fi
|
||||
@@ -0,0 +1,70 @@
|
||||
import tslib from '../tslib.js';
|
||||
const {
|
||||
__extends,
|
||||
__assign,
|
||||
__rest,
|
||||
__decorate,
|
||||
__param,
|
||||
__esDecorate,
|
||||
__runInitializers,
|
||||
__propKey,
|
||||
__setFunctionName,
|
||||
__metadata,
|
||||
__awaiter,
|
||||
__generator,
|
||||
__exportStar,
|
||||
__createBinding,
|
||||
__values,
|
||||
__read,
|
||||
__spread,
|
||||
__spreadArrays,
|
||||
__spreadArray,
|
||||
__await,
|
||||
__asyncGenerator,
|
||||
__asyncDelegator,
|
||||
__asyncValues,
|
||||
__makeTemplateObject,
|
||||
__importStar,
|
||||
__importDefault,
|
||||
__classPrivateFieldGet,
|
||||
__classPrivateFieldSet,
|
||||
__classPrivateFieldIn,
|
||||
__addDisposableResource,
|
||||
__disposeResources,
|
||||
__rewriteRelativeImportExtension,
|
||||
} = tslib;
|
||||
export {
|
||||
__extends,
|
||||
__assign,
|
||||
__rest,
|
||||
__decorate,
|
||||
__param,
|
||||
__esDecorate,
|
||||
__runInitializers,
|
||||
__propKey,
|
||||
__setFunctionName,
|
||||
__metadata,
|
||||
__awaiter,
|
||||
__generator,
|
||||
__exportStar,
|
||||
__createBinding,
|
||||
__values,
|
||||
__read,
|
||||
__spread,
|
||||
__spreadArrays,
|
||||
__spreadArray,
|
||||
__await,
|
||||
__asyncGenerator,
|
||||
__asyncDelegator,
|
||||
__asyncValues,
|
||||
__makeTemplateObject,
|
||||
__importStar,
|
||||
__importDefault,
|
||||
__classPrivateFieldGet,
|
||||
__classPrivateFieldSet,
|
||||
__classPrivateFieldIn,
|
||||
__addDisposableResource,
|
||||
__disposeResources,
|
||||
__rewriteRelativeImportExtension,
|
||||
};
|
||||
export default tslib;
|
||||
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const util_1 = require("../util");
|
||||
const classScopeAnalyzer_1 = require("../util/class-scope-analyzer/classScopeAnalyzer");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-unused-private-class-members',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow unused private class members',
|
||||
extendsBaseRule: true,
|
||||
requiresTypeChecking: false,
|
||||
},
|
||||
messages: {
|
||||
unusedPrivateClassMember: "Private class member '{{classMemberName}}' is defined but never used.",
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
return {
|
||||
'Program:exit'(node) {
|
||||
const result = (0, classScopeAnalyzer_1.analyzeClassMemberUsage)(node, utils_1.ESLintUtils.nullThrows(context.sourceCode.scopeManager, 'Missing required scope manager'));
|
||||
for (const classScope of result.values()) {
|
||||
for (const member of [
|
||||
...classScope.members.instance.values(),
|
||||
...classScope.members.static.values(),
|
||||
]) {
|
||||
if ((!member.isPrivate() && !member.isHashPrivate()) ||
|
||||
member.isUsed()) {
|
||||
continue;
|
||||
}
|
||||
context.report({
|
||||
node: member.nameNode,
|
||||
messageId: 'unusedPrivateClassMember',
|
||||
data: { classMemberName: member.name },
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
var test = require('tape');
|
||||
var stringify = require('../');
|
||||
|
||||
test('toJSON function', function (t) {
|
||||
t.plan(1);
|
||||
var obj = { one: 1, two: 2, toJSON: function() { return { one: 1 }; } };
|
||||
t.equal(stringify(obj), '{"one":1}' );
|
||||
});
|
||||
|
||||
test('toJSON returns string', function (t) {
|
||||
t.plan(1);
|
||||
var obj = { one: 1, two: 2, toJSON: function() { return 'one'; } };
|
||||
t.equal(stringify(obj), '"one"');
|
||||
});
|
||||
|
||||
test('toJSON returns array', function (t) {
|
||||
t.plan(1);
|
||||
var obj = { one: 1, two: 2, toJSON: function() { return ['one']; } };
|
||||
t.equal(stringify(obj), '["one"]');
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
{{## def.assignDefault:
|
||||
{{? it.compositeRule }}
|
||||
{{
|
||||
if (it.opts.strictDefaults) {
|
||||
var $defaultMsg = 'default is ignored for: ' + $passData;
|
||||
if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg);
|
||||
else throw new Error($defaultMsg);
|
||||
}
|
||||
}}
|
||||
{{??}}
|
||||
if ({{=$passData}} === undefined
|
||||
{{? it.opts.useDefaults == 'empty' }}
|
||||
|| {{=$passData}} === null
|
||||
|| {{=$passData}} === ''
|
||||
{{?}}
|
||||
)
|
||||
{{=$passData}} = {{? it.opts.useDefaults == 'shared' }}
|
||||
{{= it.useDefault($sch.default) }}
|
||||
{{??}}
|
||||
{{= JSON.stringify($sch.default) }}
|
||||
{{?}};
|
||||
{{?}}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.defaultProperties:
|
||||
{{
|
||||
var $schema = it.schema.properties
|
||||
, $schemaKeys = Object.keys($schema); }}
|
||||
{{~ $schemaKeys:$propertyKey }}
|
||||
{{ var $sch = $schema[$propertyKey]; }}
|
||||
{{? $sch.default !== undefined }}
|
||||
{{ var $passData = $data + it.util.getProperty($propertyKey); }}
|
||||
{{# def.assignDefault }}
|
||||
{{?}}
|
||||
{{~}}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.defaultItems:
|
||||
{{~ it.schema.items:$sch:$i }}
|
||||
{{? $sch.default !== undefined }}
|
||||
{{ var $passData = $data + '[' + $i + ']'; }}
|
||||
{{# def.assignDefault }}
|
||||
{{?}}
|
||||
{{~}}
|
||||
#}}
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.encodeToCurve = exports.hashToCurve = exports.secp521r1 = exports.p521 = void 0;
|
||||
const nist_ts_1 = require("./nist.js");
|
||||
/** @deprecated use `import { p521 } from '@noble/curves/nist.js';` */
|
||||
exports.p521 = nist_ts_1.p521;
|
||||
/** @deprecated use `import { p521 } from '@noble/curves/nist.js';` */
|
||||
exports.secp521r1 = nist_ts_1.p521;
|
||||
/** @deprecated use `import { p521_hasher } from '@noble/curves/nist.js';` */
|
||||
exports.hashToCurve = (() => nist_ts_1.p521_hasher.hashToCurve)();
|
||||
/** @deprecated use `import { p521_hasher } from '@noble/curves/nist.js';` */
|
||||
exports.encodeToCurve = (() => nist_ts_1.p521_hasher.encodeToCurve)();
|
||||
//# sourceMappingURL=p521.js.map
|
||||
@@ -0,0 +1,215 @@
|
||||
var array = require('postgres-array')
|
||||
var arrayParser = require('./arrayParser');
|
||||
var parseDate = require('postgres-date');
|
||||
var parseInterval = require('postgres-interval');
|
||||
var parseByteA = require('postgres-bytea');
|
||||
|
||||
function allowNull (fn) {
|
||||
return function nullAllowed (value) {
|
||||
if (value === null) return value
|
||||
return fn(value)
|
||||
}
|
||||
}
|
||||
|
||||
function parseBool (value) {
|
||||
if (value === null) return value
|
||||
return value === 'TRUE' ||
|
||||
value === 't' ||
|
||||
value === 'true' ||
|
||||
value === 'y' ||
|
||||
value === 'yes' ||
|
||||
value === 'on' ||
|
||||
value === '1';
|
||||
}
|
||||
|
||||
function parseBoolArray (value) {
|
||||
if (!value) return null
|
||||
return array.parse(value, parseBool)
|
||||
}
|
||||
|
||||
function parseBaseTenInt (string) {
|
||||
return parseInt(string, 10)
|
||||
}
|
||||
|
||||
function parseIntegerArray (value) {
|
||||
if (!value) return null
|
||||
return array.parse(value, allowNull(parseBaseTenInt))
|
||||
}
|
||||
|
||||
function parseBigIntegerArray (value) {
|
||||
if (!value) return null
|
||||
return array.parse(value, allowNull(function (entry) {
|
||||
return parseBigInteger(entry).trim()
|
||||
}))
|
||||
}
|
||||
|
||||
var parsePointArray = function(value) {
|
||||
if(!value) { return null; }
|
||||
var p = arrayParser.create(value, function(entry) {
|
||||
if(entry !== null) {
|
||||
entry = parsePoint(entry);
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
|
||||
return p.parse();
|
||||
};
|
||||
|
||||
var parseFloatArray = function(value) {
|
||||
if(!value) { return null; }
|
||||
var p = arrayParser.create(value, function(entry) {
|
||||
if(entry !== null) {
|
||||
entry = parseFloat(entry);
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
|
||||
return p.parse();
|
||||
};
|
||||
|
||||
var parseStringArray = function(value) {
|
||||
if(!value) { return null; }
|
||||
|
||||
var p = arrayParser.create(value);
|
||||
return p.parse();
|
||||
};
|
||||
|
||||
var parseDateArray = function(value) {
|
||||
if (!value) { return null; }
|
||||
|
||||
var p = arrayParser.create(value, function(entry) {
|
||||
if (entry !== null) {
|
||||
entry = parseDate(entry);
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
|
||||
return p.parse();
|
||||
};
|
||||
|
||||
var parseIntervalArray = function(value) {
|
||||
if (!value) { return null; }
|
||||
|
||||
var p = arrayParser.create(value, function(entry) {
|
||||
if (entry !== null) {
|
||||
entry = parseInterval(entry);
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
|
||||
return p.parse();
|
||||
};
|
||||
|
||||
var parseByteAArray = function(value) {
|
||||
if (!value) { return null; }
|
||||
|
||||
return array.parse(value, allowNull(parseByteA));
|
||||
};
|
||||
|
||||
var parseInteger = function(value) {
|
||||
return parseInt(value, 10);
|
||||
};
|
||||
|
||||
var parseBigInteger = function(value) {
|
||||
var valStr = String(value);
|
||||
if (/^\d+$/.test(valStr)) { return valStr; }
|
||||
return value;
|
||||
};
|
||||
|
||||
var parseJsonArray = function(value) {
|
||||
if (!value) { return null; }
|
||||
|
||||
return array.parse(value, allowNull(JSON.parse));
|
||||
};
|
||||
|
||||
var parsePoint = function(value) {
|
||||
if (value[0] !== '(') { return null; }
|
||||
|
||||
value = value.substring( 1, value.length - 1 ).split(',');
|
||||
|
||||
return {
|
||||
x: parseFloat(value[0])
|
||||
, y: parseFloat(value[1])
|
||||
};
|
||||
};
|
||||
|
||||
var parseCircle = function(value) {
|
||||
if (value[0] !== '<' && value[1] !== '(') { return null; }
|
||||
|
||||
var point = '(';
|
||||
var radius = '';
|
||||
var pointParsed = false;
|
||||
for (var i = 2; i < value.length - 1; i++){
|
||||
if (!pointParsed) {
|
||||
point += value[i];
|
||||
}
|
||||
|
||||
if (value[i] === ')') {
|
||||
pointParsed = true;
|
||||
continue;
|
||||
} else if (!pointParsed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value[i] === ','){
|
||||
continue;
|
||||
}
|
||||
|
||||
radius += value[i];
|
||||
}
|
||||
var result = parsePoint(point);
|
||||
result.radius = parseFloat(radius);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var init = function(register) {
|
||||
register(20, parseBigInteger); // int8
|
||||
register(21, parseInteger); // int2
|
||||
register(23, parseInteger); // int4
|
||||
register(26, parseInteger); // oid
|
||||
register(700, parseFloat); // float4/real
|
||||
register(701, parseFloat); // float8/double
|
||||
register(16, parseBool);
|
||||
register(1082, parseDate); // date
|
||||
register(1114, parseDate); // timestamp without timezone
|
||||
register(1184, parseDate); // timestamp
|
||||
register(600, parsePoint); // point
|
||||
register(651, parseStringArray); // cidr[]
|
||||
register(718, parseCircle); // circle
|
||||
register(1000, parseBoolArray);
|
||||
register(1001, parseByteAArray);
|
||||
register(1005, parseIntegerArray); // _int2
|
||||
register(1007, parseIntegerArray); // _int4
|
||||
register(1028, parseIntegerArray); // oid[]
|
||||
register(1016, parseBigIntegerArray); // _int8
|
||||
register(1017, parsePointArray); // point[]
|
||||
register(1021, parseFloatArray); // _float4
|
||||
register(1022, parseFloatArray); // _float8
|
||||
register(1231, parseFloatArray); // _numeric
|
||||
register(1014, parseStringArray); //char
|
||||
register(1015, parseStringArray); //varchar
|
||||
register(1008, parseStringArray);
|
||||
register(1009, parseStringArray);
|
||||
register(1040, parseStringArray); // macaddr[]
|
||||
register(1041, parseStringArray); // inet[]
|
||||
register(1115, parseDateArray); // timestamp without time zone[]
|
||||
register(1182, parseDateArray); // _date
|
||||
register(1185, parseDateArray); // timestamp with time zone[]
|
||||
register(1186, parseInterval);
|
||||
register(1187, parseIntervalArray);
|
||||
register(17, parseByteA);
|
||||
register(114, JSON.parse.bind(JSON)); // json
|
||||
register(3802, JSON.parse.bind(JSON)); // jsonb
|
||||
register(199, parseJsonArray); // json[]
|
||||
register(3807, parseJsonArray); // jsonb[]
|
||||
register(3907, parseStringArray); // numrange[]
|
||||
register(2951, parseStringArray); // uuid[]
|
||||
register(791, parseStringArray); // money[]
|
||||
register(1183, parseStringArray); // time[]
|
||||
register(1270, parseStringArray); // timetz[]
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
init: init
|
||||
};
|
||||
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
* @fileoverview A rule to ensure blank lines within blocks.
|
||||
* @author Mathias Schreck <https://github.com/lo1tuma>
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
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: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin",
|
||||
url: "https://eslint.style",
|
||||
},
|
||||
rule: {
|
||||
name: "padded-blocks",
|
||||
url: "https://eslint.style/rules/padded-blocks",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description: "Require or disallow padding within blocks",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/padded-blocks",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
blocks: {
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
switches: {
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
classes: {
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
minProperties: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allowSingleLineBlocks: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
alwaysPadBlock: "Block must be padded by blank lines.",
|
||||
neverPadBlock: "Block must not be padded by blank lines.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = {};
|
||||
const typeOptions = context.options[0] || "always";
|
||||
const exceptOptions = context.options[1] || {};
|
||||
|
||||
if (typeof typeOptions === "string") {
|
||||
const shouldHavePadding = typeOptions === "always";
|
||||
|
||||
options.blocks = shouldHavePadding;
|
||||
options.switches = shouldHavePadding;
|
||||
options.classes = shouldHavePadding;
|
||||
} else {
|
||||
if (Object.hasOwn(typeOptions, "blocks")) {
|
||||
options.blocks = typeOptions.blocks === "always";
|
||||
}
|
||||
if (Object.hasOwn(typeOptions, "switches")) {
|
||||
options.switches = typeOptions.switches === "always";
|
||||
}
|
||||
if (Object.hasOwn(typeOptions, "classes")) {
|
||||
options.classes = typeOptions.classes === "always";
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.hasOwn(exceptOptions, "allowSingleLineBlocks")) {
|
||||
options.allowSingleLineBlocks =
|
||||
exceptOptions.allowSingleLineBlocks === true;
|
||||
}
|
||||
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Gets the open brace token from a given node.
|
||||
* @param {ASTNode} node A BlockStatement or SwitchStatement node from which to get the open brace.
|
||||
* @returns {Token} The token of the open brace.
|
||||
*/
|
||||
function getOpenBrace(node) {
|
||||
if (node.type === "SwitchStatement") {
|
||||
return sourceCode.getTokenBefore(node.cases[0]);
|
||||
}
|
||||
|
||||
if (node.type === "StaticBlock") {
|
||||
return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
|
||||
}
|
||||
|
||||
// `BlockStatement` or `ClassBody`
|
||||
return sourceCode.getFirstToken(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given parameter is a comment node
|
||||
* @param {ASTNode|Token} node An AST node or token
|
||||
* @returns {boolean} True if node is a comment
|
||||
*/
|
||||
function isComment(node) {
|
||||
return node.type === "Line" || node.type === "Block";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is padding between two tokens
|
||||
* @param {Token} first The first token
|
||||
* @param {Token} second The second token
|
||||
* @returns {boolean} True if there is at least a line between the tokens
|
||||
*/
|
||||
function isPaddingBetweenTokens(first, second) {
|
||||
return second.loc.start.line - first.loc.end.line >= 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given token has a blank line after it.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} Whether or not the token is followed by a blank line.
|
||||
*/
|
||||
function getFirstBlockToken(token) {
|
||||
let prev,
|
||||
first = token;
|
||||
|
||||
do {
|
||||
prev = first;
|
||||
first = sourceCode.getTokenAfter(first, {
|
||||
includeComments: true,
|
||||
});
|
||||
} while (
|
||||
isComment(first) &&
|
||||
first.loc.start.line === prev.loc.end.line
|
||||
);
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given token is preceded by a blank line.
|
||||
* @param {Token} token The token to check
|
||||
* @returns {boolean} Whether or not the token is preceded by a blank line
|
||||
*/
|
||||
function getLastBlockToken(token) {
|
||||
let last = token,
|
||||
next;
|
||||
|
||||
do {
|
||||
next = last;
|
||||
last = sourceCode.getTokenBefore(last, {
|
||||
includeComments: true,
|
||||
});
|
||||
} while (
|
||||
isComment(last) &&
|
||||
last.loc.end.line === next.loc.start.line
|
||||
);
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a node should be padded, according to the rule config.
|
||||
* @param {ASTNode} node The AST node to check.
|
||||
* @throws {Error} (Unreachable)
|
||||
* @returns {boolean} True if the node should be padded, false otherwise.
|
||||
*/
|
||||
function requirePaddingFor(node) {
|
||||
switch (node.type) {
|
||||
case "BlockStatement":
|
||||
case "StaticBlock":
|
||||
return options.blocks;
|
||||
case "SwitchStatement":
|
||||
return options.switches;
|
||||
case "ClassBody":
|
||||
return options.classes;
|
||||
|
||||
/* c8 ignore next */
|
||||
default:
|
||||
throw new Error("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given BlockStatement node to be padded if the block is not empty.
|
||||
* @param {ASTNode} node The AST node of a BlockStatement.
|
||||
* @returns {void} undefined.
|
||||
*/
|
||||
function checkPadding(node) {
|
||||
const openBrace = getOpenBrace(node),
|
||||
firstBlockToken = getFirstBlockToken(openBrace),
|
||||
tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, {
|
||||
includeComments: true,
|
||||
}),
|
||||
closeBrace = sourceCode.getLastToken(node),
|
||||
lastBlockToken = getLastBlockToken(closeBrace),
|
||||
tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, {
|
||||
includeComments: true,
|
||||
}),
|
||||
blockHasTopPadding = isPaddingBetweenTokens(
|
||||
tokenBeforeFirst,
|
||||
firstBlockToken,
|
||||
),
|
||||
blockHasBottomPadding = isPaddingBetweenTokens(
|
||||
lastBlockToken,
|
||||
tokenAfterLast,
|
||||
);
|
||||
|
||||
if (
|
||||
options.allowSingleLineBlocks &&
|
||||
astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requirePaddingFor(node)) {
|
||||
if (!blockHasTopPadding) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: tokenBeforeFirst.loc.start,
|
||||
end: firstBlockToken.loc.start,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(
|
||||
tokenBeforeFirst,
|
||||
"\n",
|
||||
);
|
||||
},
|
||||
messageId: "alwaysPadBlock",
|
||||
});
|
||||
}
|
||||
if (!blockHasBottomPadding) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
end: tokenAfterLast.loc.start,
|
||||
start: lastBlockToken.loc.end,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(tokenAfterLast, "\n");
|
||||
},
|
||||
messageId: "alwaysPadBlock",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (blockHasTopPadding) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: tokenBeforeFirst.loc.start,
|
||||
end: firstBlockToken.loc.start,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[
|
||||
tokenBeforeFirst.range[1],
|
||||
firstBlockToken.range[0] -
|
||||
firstBlockToken.loc.start.column,
|
||||
],
|
||||
"\n",
|
||||
);
|
||||
},
|
||||
messageId: "neverPadBlock",
|
||||
});
|
||||
}
|
||||
|
||||
if (blockHasBottomPadding) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
end: tokenAfterLast.loc.start,
|
||||
start: lastBlockToken.loc.end,
|
||||
},
|
||||
messageId: "neverPadBlock",
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[
|
||||
lastBlockToken.range[1],
|
||||
tokenAfterLast.range[0] -
|
||||
tokenAfterLast.loc.start.column,
|
||||
],
|
||||
"\n",
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rule = {};
|
||||
|
||||
if (Object.hasOwn(options, "switches")) {
|
||||
rule.SwitchStatement = function (node) {
|
||||
if (node.cases.length === 0) {
|
||||
return;
|
||||
}
|
||||
checkPadding(node);
|
||||
};
|
||||
}
|
||||
|
||||
if (Object.hasOwn(options, "blocks")) {
|
||||
rule.BlockStatement = function (node) {
|
||||
if (node.body.length === 0) {
|
||||
return;
|
||||
}
|
||||
checkPadding(node);
|
||||
};
|
||||
rule.StaticBlock = rule.BlockStatement;
|
||||
}
|
||||
|
||||
if (Object.hasOwn(options, "classes")) {
|
||||
rule.ClassBody = function (node) {
|
||||
if (node.body.length === 0) {
|
||||
return;
|
||||
}
|
||||
checkPadding(node);
|
||||
};
|
||||
}
|
||||
|
||||
return rule;
|
||||
},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
import type { LibDefinition } from '../variable';
|
||||
export declare const esnext: LibDefinition;
|
||||
Reference in New Issue
Block a user