WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
"use strict";
|
||||
|
||||
var _assert = _interopRequireDefault(require("assert"));
|
||||
|
||||
var _v = _interopRequireDefault(require("./v1.js"));
|
||||
|
||||
var _v2 = _interopRequireDefault(require("./v3.js"));
|
||||
|
||||
var _v3 = _interopRequireDefault(require("./v4.js"));
|
||||
|
||||
var _v4 = _interopRequireDefault(require("./v5.js"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function usage() {
|
||||
console.log('Usage:');
|
||||
console.log(' uuid');
|
||||
console.log(' uuid v1');
|
||||
console.log(' uuid v3 <name> <namespace uuid>');
|
||||
console.log(' uuid v4');
|
||||
console.log(' uuid v5 <name> <namespace uuid>');
|
||||
console.log(' uuid --help');
|
||||
console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC4122');
|
||||
}
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.indexOf('--help') >= 0) {
|
||||
usage();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const version = args.shift() || 'v4';
|
||||
|
||||
switch (version) {
|
||||
case 'v1':
|
||||
console.log((0, _v.default)());
|
||||
break;
|
||||
|
||||
case 'v3':
|
||||
{
|
||||
const name = args.shift();
|
||||
let namespace = args.shift();
|
||||
(0, _assert.default)(name != null, 'v3 name not specified');
|
||||
(0, _assert.default)(namespace != null, 'v3 namespace not specified');
|
||||
|
||||
if (namespace === 'URL') {
|
||||
namespace = _v2.default.URL;
|
||||
}
|
||||
|
||||
if (namespace === 'DNS') {
|
||||
namespace = _v2.default.DNS;
|
||||
}
|
||||
|
||||
console.log((0, _v2.default)(name, namespace));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v4':
|
||||
console.log((0, _v3.default)());
|
||||
break;
|
||||
|
||||
case 'v5':
|
||||
{
|
||||
const name = args.shift();
|
||||
let namespace = args.shift();
|
||||
(0, _assert.default)(name != null, 'v5 name not specified');
|
||||
(0, _assert.default)(namespace != null, 'v5 namespace not specified');
|
||||
|
||||
if (namespace === 'URL') {
|
||||
namespace = _v4.default.URL;
|
||||
}
|
||||
|
||||
if (namespace === 'DNS') {
|
||||
namespace = _v4.default.DNS;
|
||||
}
|
||||
|
||||
console.log((0, _v4.default)(name, namespace));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
usage();
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## v.2.0.0
|
||||
|
||||
Features
|
||||
|
||||
- Added stable-stringify (see documentation)
|
||||
- Support replacer
|
||||
- Support spacer
|
||||
- toJSON support without forceDecirc property
|
||||
- Improved performance
|
||||
|
||||
Breaking changes
|
||||
|
||||
- Manipulating the input value in a `toJSON` function is not possible anymore in
|
||||
all cases (see documentation)
|
||||
- Dropped support for e.g. IE8 and Node.js < 4
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,56 @@
|
||||
declare class Queue<ValueType> implements Iterable<ValueType> {
|
||||
/**
|
||||
The size of the queue.
|
||||
*/
|
||||
readonly size: number;
|
||||
|
||||
/**
|
||||
Tiny queue data structure.
|
||||
|
||||
The instance is an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols), which means you can iterate over the queue front to back with a “for…of” loop, or use spreading to convert the queue to an array. Don't do this unless you really need to though, since it's slow.
|
||||
|
||||
@example
|
||||
```
|
||||
import Queue = require('yocto-queue');
|
||||
|
||||
const queue = new Queue();
|
||||
|
||||
queue.enqueue('🦄');
|
||||
queue.enqueue('🌈');
|
||||
|
||||
console.log(queue.size);
|
||||
//=> 2
|
||||
|
||||
console.log(...queue);
|
||||
//=> '🦄 🌈'
|
||||
|
||||
console.log(queue.dequeue());
|
||||
//=> '🦄'
|
||||
|
||||
console.log(queue.dequeue());
|
||||
//=> '🌈'
|
||||
```
|
||||
*/
|
||||
constructor();
|
||||
|
||||
[Symbol.iterator](): IterableIterator<ValueType>;
|
||||
|
||||
/**
|
||||
Add a value to the queue.
|
||||
*/
|
||||
enqueue(value: ValueType): void;
|
||||
|
||||
/**
|
||||
Remove the next value in the queue.
|
||||
|
||||
@returns The removed value or `undefined` if the queue is empty.
|
||||
*/
|
||||
dequeue(): ValueType | undefined;
|
||||
|
||||
/**
|
||||
Clear the queue.
|
||||
*/
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
export = Queue;
|
||||
@@ -0,0 +1,43 @@
|
||||
name: Publish release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'The version number to tag and release'
|
||||
required: true
|
||||
type: string
|
||||
prerelease:
|
||||
description: 'Release as pre-release'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
release-npm:
|
||||
runs-on: ubuntu-latest
|
||||
environment: main
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '22'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm install npm -g
|
||||
- run: npm install
|
||||
- name: Change version number and sync
|
||||
run: |
|
||||
node scripts/sync-version.mjs ${{ inputs.version }}
|
||||
- name: GIT commit and push all changed files
|
||||
run: |
|
||||
git config --global user.name "mcollina"
|
||||
git config --global user.email "hello@matteocollina.com"
|
||||
git commit -n -a -m "Bumped v${{ inputs.version }}"
|
||||
git push origin HEAD:${{ github.ref }}
|
||||
- run: npm publish --access public --tag ${{ inputs.prerelease == true && 'next' || 'latest' }}
|
||||
- name: 'Create release notes'
|
||||
run: |
|
||||
npx @matteo.collina/release-notes -a ${{ secrets.GITHUB_TOKEN }} -t v${{ inputs.version }} -r redact -o pinojs ${{ github.event.inputs.prerelease == 'true' && '-p' || '' }} -c ${{ github.ref }}
|
||||
@@ -0,0 +1,131 @@
|
||||
'use strict';
|
||||
|
||||
const { EMPTY_BUFFER } = require('./constants');
|
||||
|
||||
const FastBuffer = Buffer[Symbol.species];
|
||||
|
||||
/**
|
||||
* 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 new FastBuffer(target.buffer, target.byteOffset, 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) {
|
||||
for (let i = 0; i < buffer.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.length === buf.buffer.byteLength) {
|
||||
return buf.buffer;
|
||||
}
|
||||
|
||||
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = new FastBuffer(data);
|
||||
} else if (ArrayBuffer.isView(data)) {
|
||||
buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);
|
||||
} else {
|
||||
buf = Buffer.from(data);
|
||||
toBuffer.readOnly = false;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
concat,
|
||||
mask: _mask,
|
||||
toArrayBuffer,
|
||||
toBuffer,
|
||||
unmask: _unmask
|
||||
};
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (!process.env.WS_NO_BUFFER_UTIL) {
|
||||
try {
|
||||
const bufferUtil = require('bufferutil');
|
||||
|
||||
module.exports.mask = function (source, mask, output, offset, length) {
|
||||
if (length < 48) _mask(source, mask, output, offset, length);
|
||||
else bufferUtil.mask(source, mask, output, offset, length);
|
||||
};
|
||||
|
||||
module.exports.unmask = function (buffer, mask) {
|
||||
if (buffer.length < 32) _unmask(buffer, mask);
|
||||
else bufferUtil.unmask(buffer, mask);
|
||||
};
|
||||
} catch (e) {
|
||||
// Continue regardless of the error.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @fileoverview Merge Strategy
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Container class for several different merge strategies.
|
||||
*/
|
||||
class MergeStrategy {
|
||||
/**
|
||||
* Merges two keys by overwriting the first with the second.
|
||||
* @template TValue1 The type of the value from the first object key.
|
||||
* @template TValue2 The type of the value from the second object key.
|
||||
* @param {TValue1} value1 The value from the first object key.
|
||||
* @param {TValue2} value2 The value from the second object key.
|
||||
* @returns {TValue2} The second value.
|
||||
*/
|
||||
static overwrite(value1, value2) {
|
||||
return value2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two keys by replacing the first with the second only if the
|
||||
* second is defined.
|
||||
* @template TValue1 The type of the value from the first object key.
|
||||
* @template TValue2 The type of the value from the second object key.
|
||||
* @param {TValue1} value1 The value from the first object key.
|
||||
* @param {TValue2} value2 The value from the second object key.
|
||||
* @returns {TValue1 | TValue2} The second value if it is defined.
|
||||
*/
|
||||
static replace(value1, value2) {
|
||||
if (typeof value2 !== "undefined") {
|
||||
return value2;
|
||||
}
|
||||
|
||||
return value1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two properties by assigning properties from the second to the first.
|
||||
* @template {Record<string | number | symbol, unknown> | undefined} TValue1 The type of the value from the first object key.
|
||||
* @template {Record<string | number | symbol, unknown>} TValue2 The type of the value from the second object key.
|
||||
* @param {TValue1} value1 The value from the first object key.
|
||||
* @param {TValue2} value2 The value from the second object key.
|
||||
* @returns {Omit<TValue1, keyof TValue2> & TValue2} A new object containing properties from both value1 and
|
||||
* value2.
|
||||
*/
|
||||
static assign(value1, value2) {
|
||||
return Object.assign({}, value1, value2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @fileoverview Validation Strategy
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Container class for several different validation strategies.
|
||||
*/
|
||||
class ValidationStrategy {
|
||||
/**
|
||||
* Validates that a value is an array.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static array(value) {
|
||||
if (!Array.isArray(value)) {
|
||||
throw new TypeError("Expected an array.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is a boolean.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static boolean(value) {
|
||||
if (typeof value !== "boolean") {
|
||||
throw new TypeError("Expected a boolean.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is a number.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static number(value) {
|
||||
if (typeof value !== "number") {
|
||||
throw new TypeError("Expected a number.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is an object.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static object(value) {
|
||||
if (!value || typeof value !== "object") {
|
||||
throw new TypeError("Expected an object.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is an object or null.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static "object?"(value) {
|
||||
if (typeof value !== "object") {
|
||||
throw new TypeError("Expected an object or null.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is a string.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static string(value) {
|
||||
if (typeof value !== "string") {
|
||||
throw new TypeError("Expected a string.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a value is a non-empty string.
|
||||
* @param {unknown} value The value to validate.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} If the value is invalid.
|
||||
*/
|
||||
static "string!"(value) {
|
||||
if (typeof value !== "string" || value.length === 0) {
|
||||
throw new TypeError("Expected a non-empty string.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @fileoverview Object Schema
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @import * as $typests from "./types.ts"; */
|
||||
/** @typedef {$typests.BuiltInMergeStrategy} BuiltInMergeStrategy */
|
||||
/** @typedef {$typests.BuiltInValidationStrategy} BuiltInValidationStrategy */
|
||||
/** @typedef {$typests.CustomMergeStrategy} CustomMergeStrategy */
|
||||
/** @typedef {$typests.CustomValidationStrategy} CustomValidationStrategy */
|
||||
/** @typedef {$typests.ObjectDefinition} ObjectDefinition */
|
||||
/** @typedef {$typests.PropertyDefinition} PropertyDefinition */
|
||||
/** @typedef {$typests.PropertyDefinitionWithSchema} PropertyDefinitionWithSchema */
|
||||
/** @typedef {$typests.PropertyDefinitionWithStrategies} PropertyDefinitionWithStrategies */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Private
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validates a schema strategy.
|
||||
* @param {string} name The name of the key this strategy is for.
|
||||
* @param {PropertyDefinition} definition The strategy for the object key.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} When the strategy is missing a name.
|
||||
* @throws {TypeError} When the strategy is missing a merge() method.
|
||||
* @throws {TypeError} When the strategy is missing a validate() method.
|
||||
*/
|
||||
function validateDefinition(name, definition) {
|
||||
let hasSchema = false;
|
||||
if (definition.schema) {
|
||||
if (typeof definition.schema === "object") {
|
||||
hasSchema = true;
|
||||
} else {
|
||||
throw new TypeError("Schema must be an object.");
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof definition.merge === "string") {
|
||||
if (!(definition.merge in MergeStrategy)) {
|
||||
throw new TypeError(
|
||||
`Definition for key "${name}" missing valid merge strategy.`,
|
||||
);
|
||||
}
|
||||
} else if (!hasSchema && typeof definition.merge !== "function") {
|
||||
throw new TypeError(
|
||||
`Definition for key "${name}" must have a merge property.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof definition.validate === "string") {
|
||||
if (!(definition.validate in ValidationStrategy)) {
|
||||
throw new TypeError(
|
||||
`Definition for key "${name}" missing valid validation strategy.`,
|
||||
);
|
||||
}
|
||||
} else if (!hasSchema && typeof definition.validate !== "function") {
|
||||
throw new TypeError(
|
||||
`Definition for key "${name}" must have a validate() method.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Error when an unexpected key is found.
|
||||
*/
|
||||
class UnexpectedKeyError extends Error {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {string} key The key that was unexpected.
|
||||
*/
|
||||
constructor(key) {
|
||||
super(`Unexpected key "${key}" found.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error when a required key is missing.
|
||||
*/
|
||||
class MissingKeyError extends Error {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {string} key The key that was missing.
|
||||
*/
|
||||
constructor(key) {
|
||||
super(`Missing required key "${key}".`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error when a key requires other keys that are missing.
|
||||
*/
|
||||
class MissingDependentKeysError extends Error {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {string} key The key that was unexpected.
|
||||
* @param {Array<string>} requiredKeys The keys that are required.
|
||||
*/
|
||||
constructor(key, requiredKeys) {
|
||||
super(`Key "${key}" requires keys "${requiredKeys.join('", "')}".`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper error for errors occuring during a merge or validate operation.
|
||||
*/
|
||||
class WrapperError extends Error {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {string} key The object key causing the error.
|
||||
* @param {Error} source The source error.
|
||||
*/
|
||||
constructor(key, source) {
|
||||
super(`Key "${key}": ${source.message}`, { cause: source });
|
||||
|
||||
// copy over custom properties that aren't represented
|
||||
for (const sourceKey of Object.keys(source)) {
|
||||
if (!(sourceKey in this)) {
|
||||
this[sourceKey] = source[sourceKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Represents an object validation/merging schema.
|
||||
*/
|
||||
class ObjectSchema {
|
||||
/**
|
||||
* Track all definitions in the schema by key.
|
||||
* @type {Map<string, PropertyDefinition>}
|
||||
*/
|
||||
#definitions = new Map();
|
||||
|
||||
/**
|
||||
* Separately track any keys that are required for faster validation.
|
||||
* @type {Map<string, PropertyDefinition>}
|
||||
*/
|
||||
#requiredKeys = new Map();
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {ObjectDefinition} definitions The schema definitions.
|
||||
* @throws {Error} When the definitions are missing or invalid.
|
||||
*/
|
||||
constructor(definitions) {
|
||||
if (!definitions) {
|
||||
throw new Error("Schema definitions missing.");
|
||||
}
|
||||
|
||||
// add in all strategies
|
||||
for (const key of Object.keys(definitions)) {
|
||||
const definition = definitions[key];
|
||||
|
||||
validateDefinition(key, definition);
|
||||
|
||||
let normalizedDefinition = definition;
|
||||
|
||||
// normalize merge and validate methods if subschema is present
|
||||
if (typeof normalizedDefinition.schema === "object") {
|
||||
const schema = new ObjectSchema(normalizedDefinition.schema);
|
||||
normalizedDefinition = {
|
||||
...normalizedDefinition,
|
||||
merge(first = {}, second = {}) {
|
||||
return schema.merge(first, second);
|
||||
},
|
||||
validate(value) {
|
||||
ValidationStrategy.object(value);
|
||||
schema.validate(value);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// normalize the merge method in case there's a string
|
||||
if (typeof normalizedDefinition.merge === "string") {
|
||||
normalizedDefinition = {
|
||||
...normalizedDefinition,
|
||||
merge: MergeStrategy[normalizedDefinition.merge],
|
||||
};
|
||||
}
|
||||
|
||||
// normalize the validate method in case there's a string
|
||||
if (typeof normalizedDefinition.validate === "string") {
|
||||
normalizedDefinition = {
|
||||
...normalizedDefinition,
|
||||
validate: ValidationStrategy[normalizedDefinition.validate],
|
||||
};
|
||||
}
|
||||
|
||||
this.#definitions.set(key, normalizedDefinition);
|
||||
|
||||
if (normalizedDefinition.required) {
|
||||
this.#requiredKeys.set(key, normalizedDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a strategy has been registered for the given object key.
|
||||
* @param {string} key The object key to find a strategy for.
|
||||
* @returns {boolean} True if the key has a strategy registered, false if not.
|
||||
*/
|
||||
hasKey(key) {
|
||||
return this.#definitions.has(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges objects together to create a new object comprised of the keys
|
||||
* of the all objects. Keys are merged based on the each key's merge
|
||||
* strategy.
|
||||
* @param {...Object} objects The objects to merge.
|
||||
* @returns {Object} A new object with a mix of all objects' keys.
|
||||
* @throws {TypeError} If any object is invalid.
|
||||
*/
|
||||
merge(...objects) {
|
||||
// double check arguments
|
||||
if (objects.length < 2) {
|
||||
throw new TypeError("merge() requires at least two arguments.");
|
||||
}
|
||||
|
||||
if (
|
||||
objects.some(
|
||||
object => object === null || typeof object !== "object",
|
||||
)
|
||||
) {
|
||||
throw new TypeError("All arguments must be objects.");
|
||||
}
|
||||
|
||||
return objects.reduce((result, object) => {
|
||||
this.validate(object);
|
||||
|
||||
for (const [key, strategy] of this.#definitions) {
|
||||
try {
|
||||
if (key in result || key in object) {
|
||||
const merge = /** @type {Function} */ (strategy.merge);
|
||||
const value = merge.call(
|
||||
this,
|
||||
result[key],
|
||||
object[key],
|
||||
);
|
||||
if (value !== undefined) {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
throw new WrapperError(key, ex);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an object's keys based on the validate strategy for each key.
|
||||
* @param {Object} object The object to validate.
|
||||
* @returns {void}
|
||||
* @throws {Error} When the object is invalid.
|
||||
*/
|
||||
validate(object) {
|
||||
// check existing keys first
|
||||
for (const key of Object.keys(object)) {
|
||||
// check to see if the key is defined
|
||||
if (!this.hasKey(key)) {
|
||||
throw new UnexpectedKeyError(key);
|
||||
}
|
||||
|
||||
// validate existing keys
|
||||
const definition = /** @type {PropertyDefinition} */ (
|
||||
this.#definitions.get(key)
|
||||
); // `definition` is guaranteed to exist since we check with `hasKey()` above.
|
||||
|
||||
// first check to see if any other keys are required
|
||||
if (Array.isArray(definition.requires)) {
|
||||
if (
|
||||
!definition.requires.every(otherKey => otherKey in object)
|
||||
) {
|
||||
throw new MissingDependentKeysError(
|
||||
key,
|
||||
definition.requires,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// now apply remaining validation strategy
|
||||
try {
|
||||
const validate = /** @type {Function} */ (definition.validate);
|
||||
validate.call(definition, object[key]);
|
||||
} catch (ex) {
|
||||
throw new WrapperError(key, ex);
|
||||
}
|
||||
}
|
||||
|
||||
// ensure required keys aren't missing
|
||||
for (const [key] of this.#requiredKeys) {
|
||||
if (!(key in object)) {
|
||||
throw new MissingKeyError(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.MergeStrategy = MergeStrategy;
|
||||
exports.ObjectSchema = ObjectSchema;
|
||||
exports.ValidationStrategy = ValidationStrategy;
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { TSESTree } from '@typescript-eslint/types';
|
||||
import type { ScopeManager } from '../ScopeManager';
|
||||
import type { Scope } from './Scope';
|
||||
import { ScopeBase } from './ScopeBase';
|
||||
import { ScopeType } from './ScopeType';
|
||||
export declare class TSEnumScope extends ScopeBase<ScopeType.tsEnum, TSESTree.TSEnumDeclaration, Scope> {
|
||||
constructor(scopeManager: ScopeManager, upperScope: TSEnumScope['upper'], block: TSEnumScope['block']);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/mini";
|
||||
|
||||
test("no locale by default", () => {
|
||||
const result = z.safeParse(z.string(), 12);
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error!.issues[0].message).toEqual("Invalid input");
|
||||
});
|
||||
|
||||
test("error inheritance", () => {
|
||||
const e1 = z.string().safeParse(123).error!;
|
||||
expect(e1).toBeInstanceOf(z.core.$ZodError);
|
||||
// expect(e1).not.toBeInstanceOf(Error);
|
||||
|
||||
try {
|
||||
z.string().parse(123);
|
||||
} catch (e2) {
|
||||
expect(e2).toBeInstanceOf(z.core.$ZodRealError);
|
||||
expect(e2).toBeInstanceOf(Error);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
const { join } = require('path')
|
||||
const ThreadStream = require('..')
|
||||
const assert = require('assert')
|
||||
|
||||
let worker = null
|
||||
|
||||
function setup () {
|
||||
const stream = new ThreadStream({
|
||||
filename: join(__dirname, 'to-file.js'),
|
||||
workerData: { dest: process.argv[2] },
|
||||
sync: true
|
||||
})
|
||||
|
||||
worker = stream.worker
|
||||
|
||||
stream.write('hello')
|
||||
stream.write(' ')
|
||||
stream.write('world\n')
|
||||
stream.flushSync()
|
||||
stream.unref()
|
||||
|
||||
// the stream object goes out of scope here
|
||||
setImmediate(gc) // eslint-disable-line
|
||||
}
|
||||
|
||||
setup()
|
||||
|
||||
let exitEmitted = false
|
||||
worker.on('exit', function () {
|
||||
exitEmitted = true
|
||||
})
|
||||
|
||||
process.on('exit', function () {
|
||||
assert.strictEqual(exitEmitted, true)
|
||||
})
|
||||
@@ -0,0 +1,143 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getNameLocationInGlobalDirectiveComment = getNameLocationInGlobalDirectiveComment;
|
||||
exports.forEachReturnStatement = forEachReturnStatement;
|
||||
exports.forEachChildESTree = forEachChildESTree;
|
||||
const visitor_keys_1 = require("@typescript-eslint/visitor-keys");
|
||||
const ts = __importStar(require("typescript"));
|
||||
const escapeRegExp_1 = require("./escapeRegExp");
|
||||
// deeply re-export, for convenience
|
||||
__exportStar(require("@typescript-eslint/utils/ast-utils"), exports);
|
||||
// The following is copied from `eslint`'s source code since it doesn't exist in eslint@5.
|
||||
// https://github.com/eslint/eslint/blob/145aec1ab9052fbca96a44d04927c595951b1536/lib/rules/utils/ast-utils.js#L1751-L1779
|
||||
// Could be export { getNameLocationInGlobalDirectiveComment } from 'eslint/lib/rules/utils/ast-utils'
|
||||
/**
|
||||
* Get the `loc` object of a given name in a `/*globals` comment directive.
|
||||
* @param sourceCode The source code to convert index to loc.
|
||||
* @param comment The `/*globals` comment directive which include the name.
|
||||
* @param name The name to find.
|
||||
* @returns The `loc` object.
|
||||
*/
|
||||
function getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) {
|
||||
const namePattern = new RegExp(`[\\s,]${(0, escapeRegExp_1.escapeRegExp)(name)}(?:$|[\\s,:])`, 'gu');
|
||||
// To ignore the first text "global".
|
||||
namePattern.lastIndex = comment.value.indexOf('global') + 6;
|
||||
// Search a given variable name.
|
||||
const match = namePattern.exec(comment.value);
|
||||
// Convert the index to loc.
|
||||
const start = sourceCode.getLocFromIndex(comment.range[0] + '/*'.length + (match ? match.index + 1 : 0));
|
||||
const end = {
|
||||
column: start.column + (match ? name.length : 1),
|
||||
line: start.line,
|
||||
};
|
||||
return { end, start };
|
||||
}
|
||||
// Copied from typescript https://github.com/microsoft/TypeScript/blob/42b0e3c4630c129ca39ce0df9fff5f0d1b4dd348/src/compiler/utilities.ts#L1335
|
||||
// Warning: This has the same semantics as the forEach family of functions,
|
||||
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
|
||||
function forEachReturnStatement(body, visitor) {
|
||||
return traverse(body);
|
||||
function traverse(node) {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.ReturnStatement:
|
||||
return visitor(node);
|
||||
case ts.SyntaxKind.CaseBlock:
|
||||
case ts.SyntaxKind.Block:
|
||||
case ts.SyntaxKind.IfStatement:
|
||||
case ts.SyntaxKind.DoStatement:
|
||||
case ts.SyntaxKind.WhileStatement:
|
||||
case ts.SyntaxKind.ForStatement:
|
||||
case ts.SyntaxKind.ForInStatement:
|
||||
case ts.SyntaxKind.ForOfStatement:
|
||||
case ts.SyntaxKind.WithStatement:
|
||||
case ts.SyntaxKind.SwitchStatement:
|
||||
case ts.SyntaxKind.CaseClause:
|
||||
case ts.SyntaxKind.DefaultClause:
|
||||
case ts.SyntaxKind.LabeledStatement:
|
||||
case ts.SyntaxKind.TryStatement:
|
||||
case ts.SyntaxKind.CatchClause:
|
||||
return ts.forEachChild(node, traverse);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
function isESTreeNodeLike(node) {
|
||||
return (typeof node === 'object' &&
|
||||
node != null &&
|
||||
'type' in node &&
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
||||
typeof node.type === 'string');
|
||||
}
|
||||
/**
|
||||
* Rough equivalent to ts.forEachChild for ESTree nodes.
|
||||
* It returns the first truthy value returned by the callback, if any.
|
||||
*/
|
||||
function forEachChildESTree(node, callback) {
|
||||
function visit(currentNode) {
|
||||
const result = callback(currentNode);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
const currentKeys = visitor_keys_1.visitorKeys[currentNode.type];
|
||||
if (!currentKeys) {
|
||||
return undefined;
|
||||
}
|
||||
for (const key of currentKeys) {
|
||||
const currentProperty = currentNode[key];
|
||||
if (Array.isArray(currentProperty)) {
|
||||
for (const child of currentProperty) {
|
||||
if (isESTreeNodeLike(child)) {
|
||||
const result = visit(child);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isESTreeNodeLike(currentProperty)) {
|
||||
const result = visit(currentProperty);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return visit(node);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { _ as _class_apply_descriptor_get } from "./_class_apply_descriptor_get.js";
|
||||
import { _ as _class_check_private_static_access } from "./_class_check_private_static_access.js";
|
||||
import { _ as _class_check_private_static_field_descriptor } from "./_class_check_private_static_field_descriptor.js";
|
||||
|
||||
function _class_static_private_field_spec_get(receiver, classConstructor, descriptor) {
|
||||
_class_check_private_static_access(receiver, classConstructor);
|
||||
_class_check_private_static_field_descriptor(descriptor, "get");
|
||||
|
||||
return _class_apply_descriptor_get(receiver, descriptor);
|
||||
}
|
||||
export { _class_static_private_field_spec_get as _ };
|
||||
@@ -0,0 +1,30 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
const { once } = require('events')
|
||||
const { join } = require('path')
|
||||
const ThreadStream = require('..')
|
||||
|
||||
test('ignores worker messages without a protocol code', async function () {
|
||||
const stream = new ThreadStream({
|
||||
filename: join(__dirname, 'message-without-code.js'),
|
||||
sync: false
|
||||
})
|
||||
|
||||
const errors = []
|
||||
stream.on('error', err => {
|
||||
errors.push(err)
|
||||
})
|
||||
|
||||
const ready = once(stream, 'ready')
|
||||
const close = once(stream, 'close')
|
||||
|
||||
assert.ok(stream.write('hello world\n'))
|
||||
stream.end()
|
||||
|
||||
await ready
|
||||
await close
|
||||
|
||||
assert.deepStrictEqual(errors, [])
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "isomorphic-ws",
|
||||
"version": "4.0.1",
|
||||
"description": "Isomorphic implementation of WebSocket",
|
||||
"main": "node.js",
|
||||
"browser": "browser.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/heineiuo/isomorphic-ws.git"
|
||||
},
|
||||
"keywords": [
|
||||
"browser",
|
||||
"browsers",
|
||||
"isomorphic",
|
||||
"node",
|
||||
"websocket",
|
||||
"ws"
|
||||
],
|
||||
"author": "@heineiuo",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/heineiuo/isomorphic-ws/issues"
|
||||
},
|
||||
"homepage": "https://github.com/heineiuo/isomorphic-ws#readme",
|
||||
"peerDependencies": {
|
||||
"ws": "*"
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"node.js",
|
||||
"browser.js",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Buffer } from "node:buffer";
|
||||
const surrogateLeadByte = 0xED;
|
||||
const surrogateSecondByteMin = 0xA0;
|
||||
const surrogateSecondByteMax = 0xBF;
|
||||
const continuationByteMin = 0x80;
|
||||
const continuationByteMax = 0xBF;
|
||||
function isWtf8Surrogate(bytes, index) {
|
||||
return index + 2 < bytes.length
|
||||
&& bytes[index] === surrogateLeadByte
|
||||
&& bytes[index + 1] >= surrogateSecondByteMin
|
||||
&& bytes[index + 1] <= surrogateSecondByteMax
|
||||
&& bytes[index + 2] >= continuationByteMin
|
||||
&& bytes[index + 2] <= continuationByteMax;
|
||||
}
|
||||
function getSurrogateCodeUnit(bytes, index) {
|
||||
return 0xD000 | ((bytes[index + 1] & 0x3F) << 6) | (bytes[index + 2] & 0x3F);
|
||||
}
|
||||
function hasSurrogateLeadByte(bytes) {
|
||||
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).indexOf(surrogateLeadByte) >= 0;
|
||||
}
|
||||
function toUint8Array(input) {
|
||||
if (input instanceof Uint8Array) {
|
||||
return input;
|
||||
}
|
||||
if (ArrayBuffer.isView(input)) {
|
||||
return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
||||
}
|
||||
return new Uint8Array(input);
|
||||
}
|
||||
export class Wtf8Decoder extends TextDecoder {
|
||||
decode(input, options) {
|
||||
if (input === undefined) {
|
||||
return super.decode(input, options);
|
||||
}
|
||||
const bytes = toUint8Array(input);
|
||||
if (!hasSurrogateLeadByte(bytes)) {
|
||||
return super.decode(bytes, options);
|
||||
}
|
||||
const parts = [];
|
||||
let segmentStart = 0;
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
if (!isWtf8Surrogate(bytes, i)) {
|
||||
continue;
|
||||
}
|
||||
if (segmentStart < i) {
|
||||
parts.push(super.decode(bytes.subarray(segmentStart, i), options));
|
||||
}
|
||||
parts.push(String.fromCharCode(getSurrogateCodeUnit(bytes, i)));
|
||||
i += 2;
|
||||
segmentStart = i + 1;
|
||||
}
|
||||
if (segmentStart === 0) {
|
||||
return super.decode(bytes, options);
|
||||
}
|
||||
if (segmentStart < bytes.length) {
|
||||
parts.push(super.decode(bytes.subarray(segmentStart), options));
|
||||
}
|
||||
return parts.join("");
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=wtf8.js.map
|
||||
@@ -0,0 +1,15 @@
|
||||
export type Options = [
|
||||
{
|
||||
allowAny?: boolean;
|
||||
allowBoolean?: boolean;
|
||||
allowNullish?: boolean;
|
||||
allowNumberAndString?: boolean;
|
||||
allowRegExp?: boolean;
|
||||
skipCompoundAssignments?: boolean;
|
||||
}
|
||||
];
|
||||
export type MessageIds = 'bigintAndNumber' | 'invalid' | 'mismatched';
|
||||
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,452 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag use of variables before they are defined
|
||||
* @author Ilya Volodin
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("eslint-scope").Scope} Scope */
|
||||
/** @typedef {import("eslint-scope").Reference} Reference */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const SENTINEL_TYPE =
|
||||
/^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
|
||||
const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
|
||||
|
||||
/**
|
||||
* Parses a given value as options.
|
||||
* @param {any} options A value to parse.
|
||||
* @returns {Object} The parsed options.
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
if (typeof options === "object" && options !== null) {
|
||||
return options;
|
||||
}
|
||||
|
||||
const functions = typeof options === "string" ? options !== "nofunc" : true;
|
||||
|
||||
return {
|
||||
functions,
|
||||
classes: true,
|
||||
variables: true,
|
||||
allowNamedExports: false,
|
||||
enums: true,
|
||||
typedefs: true,
|
||||
ignoreTypeReferences: true,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not a given location is inside of the range of a given node.
|
||||
* @param {ASTNode} node An node to check.
|
||||
* @param {number} location A location to check.
|
||||
* @returns {boolean} `true` if the location is inside of the range of the node.
|
||||
*/
|
||||
function isInRange(node, location) {
|
||||
return node && node.range[0] <= location && location <= node.range[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not a given location is inside of the range of a class static initializer.
|
||||
* Static initializers are static blocks and initializers of static fields.
|
||||
* @param {ASTNode} node `ClassBody` node to check static initializers.
|
||||
* @param {number} location A location to check.
|
||||
* @returns {boolean} `true` if the location is inside of a class static initializer.
|
||||
*/
|
||||
function isInClassStaticInitializerRange(node, location) {
|
||||
return node.body.some(
|
||||
classMember =>
|
||||
(classMember.type === "StaticBlock" &&
|
||||
isInRange(classMember, location)) ||
|
||||
(classMember.type === "PropertyDefinition" &&
|
||||
classMember.static &&
|
||||
classMember.value &&
|
||||
isInRange(classMember.value, location)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given scope is the scope of a class static initializer.
|
||||
* Static initializers are static blocks and initializers of static fields.
|
||||
* @param {Scope} scope A scope to check.
|
||||
* @returns {boolean} `true` if the scope is a class static initializer scope.
|
||||
*/
|
||||
function isClassStaticInitializerScope(scope) {
|
||||
if (scope.type === "class-static-block") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scope.type === "class-field-initializer") {
|
||||
// `scope.block` is PropertyDefinition#value node
|
||||
const propertyDefinition = scope.block.parent;
|
||||
|
||||
return propertyDefinition.static;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given reference is evaluated in an execution context
|
||||
* that isn't the one where the variable it refers to is defined.
|
||||
* Execution contexts are:
|
||||
* - top-level
|
||||
* - functions
|
||||
* - class field initializers (implicit functions)
|
||||
* - class static blocks (implicit functions)
|
||||
* Static class field initializers and class static blocks are automatically run during the class definition evaluation,
|
||||
* and therefore we'll consider them as a part of the parent execution context.
|
||||
* Example:
|
||||
*
|
||||
* const x = 1;
|
||||
*
|
||||
* x; // returns `false`
|
||||
* () => x; // returns `true`
|
||||
*
|
||||
* class C {
|
||||
* field = x; // returns `true`
|
||||
* static field = x; // returns `false`
|
||||
*
|
||||
* method() {
|
||||
* x; // returns `true`
|
||||
* }
|
||||
*
|
||||
* static method() {
|
||||
* x; // returns `true`
|
||||
* }
|
||||
*
|
||||
* static {
|
||||
* x; // returns `false`
|
||||
* }
|
||||
* }
|
||||
* @param {Reference} reference A reference to check.
|
||||
* @returns {boolean} `true` if the reference is from a separate execution context.
|
||||
*/
|
||||
function isFromSeparateExecutionContext(reference) {
|
||||
const variable = reference.resolved;
|
||||
let scope = reference.from;
|
||||
|
||||
// Scope#variableScope represents execution context
|
||||
while (variable.scope.variableScope !== scope.variableScope) {
|
||||
if (isClassStaticInitializerScope(scope.variableScope)) {
|
||||
scope = scope.variableScope.upper;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not a given reference is evaluated during the initialization of its variable.
|
||||
*
|
||||
* This returns `true` in the following cases:
|
||||
*
|
||||
* var a = a
|
||||
* var [a = a] = list
|
||||
* var {a = a} = obj
|
||||
* for (var a in a) {}
|
||||
* for (var a of a) {}
|
||||
* var C = class { [C]; };
|
||||
* var C = class { static foo = C; };
|
||||
* var C = class { static { foo = C; } };
|
||||
* class C extends C {}
|
||||
* class C extends (class { static foo = C; }) {}
|
||||
* class C { [C]; }
|
||||
* @param {Reference} reference A reference to check.
|
||||
* @returns {boolean} `true` if the reference is evaluated during the initialization.
|
||||
*/
|
||||
function isEvaluatedDuringInitialization(reference) {
|
||||
if (isFromSeparateExecutionContext(reference)) {
|
||||
/*
|
||||
* Even if the reference appears in the initializer, it isn't evaluated during the initialization.
|
||||
* For example, `const x = () => x;` is valid.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
const location = reference.identifier.range[1];
|
||||
const definition = reference.resolved.defs[0];
|
||||
|
||||
if (definition.type === "ClassName") {
|
||||
// `ClassDeclaration` or `ClassExpression`
|
||||
const classDefinition = definition.node;
|
||||
|
||||
return (
|
||||
isInRange(classDefinition, location) &&
|
||||
/*
|
||||
* Class binding is initialized before running static initializers.
|
||||
* For example, `class C { static foo = C; static { bar = C; } }` is valid.
|
||||
*/
|
||||
!isInClassStaticInitializerRange(classDefinition.body, location)
|
||||
);
|
||||
}
|
||||
|
||||
let node = definition.name.parent;
|
||||
|
||||
while (node) {
|
||||
if (node.type === "VariableDeclarator") {
|
||||
if (isInRange(node.init, location)) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
FOR_IN_OF_TYPE.test(node.parent.parent.type) &&
|
||||
isInRange(node.parent.parent.right, location)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
} else if (node.type === "AssignmentPattern") {
|
||||
if (isInRange(node.right, location)) {
|
||||
return true;
|
||||
}
|
||||
} else if (SENTINEL_TYPE.test(node.type)) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the reference contains a type query.
|
||||
* @param {ASTNode} node Identifier node to check.
|
||||
* @returns {boolean} true if reference contains type query.
|
||||
*/
|
||||
function referenceContainsTypeQuery(node) {
|
||||
switch (node.type) {
|
||||
case "TSTypeQuery":
|
||||
return true;
|
||||
|
||||
case "TSQualifiedName":
|
||||
case "Identifier":
|
||||
return referenceContainsTypeQuery(node.parent);
|
||||
|
||||
default:
|
||||
// if we find a different node, there's no chance that we're in a TSTypeQuery
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorators are transpiled such that the decorator is placed after the class declaration
|
||||
* So it is considered safe
|
||||
* @param {Variable} variable The variable to check.
|
||||
* @param {Reference} reference The reference to check.
|
||||
* @returns {boolean} `true` if the reference is in a class decorator.
|
||||
*/
|
||||
function isClassRefInClassDecorator(variable, reference) {
|
||||
if (variable.defs[0].type !== "ClassName") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!variable.defs[0].node.decorators ||
|
||||
variable.defs[0].node.decorators.length === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const deco of variable.defs[0].node.decorators) {
|
||||
if (
|
||||
reference.identifier.range[0] >= deco.range[0] &&
|
||||
reference.identifier.range[1] <= deco.range[1]
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow the use of variables before they are defined",
|
||||
dialects: ["JavaScript", "TypeScript"],
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-use-before-define",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
enum: ["nofunc"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
functions: { type: "boolean" },
|
||||
classes: { type: "boolean" },
|
||||
variables: { type: "boolean" },
|
||||
allowNamedExports: { type: "boolean" },
|
||||
enums: { type: "boolean" },
|
||||
typedefs: { type: "boolean" },
|
||||
ignoreTypeReferences: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
defaultOptions: [
|
||||
{
|
||||
classes: true,
|
||||
functions: true,
|
||||
variables: true,
|
||||
allowNamedExports: false,
|
||||
enums: true,
|
||||
typedefs: true,
|
||||
ignoreTypeReferences: true,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
usedBeforeDefined: "'{{name}}' was used before it was defined.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = parseOptions(context.options[0]);
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Determines whether a given reference should be checked.
|
||||
*
|
||||
* Returns `false` if the reference is:
|
||||
* - initialization's (e.g., `let a = 1`).
|
||||
* - referring to an undefined variable (i.e., if it's an unresolved reference).
|
||||
* - referring to a variable that is defined, but not in the given source code
|
||||
* (e.g., global environment variable or `arguments` in functions).
|
||||
* - allowed by options.
|
||||
* @param {Reference} reference The reference
|
||||
* @returns {boolean} `true` if the reference should be checked
|
||||
*/
|
||||
function shouldCheck(reference) {
|
||||
if (reference.init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { identifier } = reference;
|
||||
|
||||
if (
|
||||
options.allowNamedExports &&
|
||||
identifier.parent.type === "ExportSpecifier" &&
|
||||
identifier.parent.local === identifier
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const variable = reference.resolved;
|
||||
|
||||
if (!variable || variable.defs.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const definitionType = variable.defs[0].type;
|
||||
|
||||
if (!options.functions && definitionType === "FunctionName") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
((!options.variables && definitionType === "Variable") ||
|
||||
(!options.classes && definitionType === "ClassName")) &&
|
||||
// don't skip checking the reference if it's in the same execution context, because of TDZ
|
||||
isFromSeparateExecutionContext(reference)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.enums && definitionType === "TSEnumName") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.typedefs && definitionType === "Type") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
options.ignoreTypeReferences &&
|
||||
(referenceContainsTypeQuery(identifier) ||
|
||||
identifier.parent.type === "TSTypeReference")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip nested namespace aliases as variable references
|
||||
if (identifier.parent.type === "TSQualifiedName") {
|
||||
let currentNode = identifier.parent;
|
||||
|
||||
while (currentNode.type === "TSQualifiedName") {
|
||||
currentNode = currentNode.left;
|
||||
}
|
||||
|
||||
if (currentNode === identifier) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isClassRefInClassDecorator(variable, reference)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and validates all references in a given scope and its child scopes.
|
||||
* @param {Scope} scope The scope object.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkReferencesInScope(scope) {
|
||||
scope.references.filter(shouldCheck).forEach(reference => {
|
||||
const variable = reference.resolved;
|
||||
const definitionIdentifier = variable.defs[0].name;
|
||||
|
||||
if (
|
||||
reference.identifier.range[1] <
|
||||
definitionIdentifier.range[1] ||
|
||||
(isEvaluatedDuringInitialization(reference) &&
|
||||
reference.identifier.parent.type !== "TSTypeReference")
|
||||
) {
|
||||
context.report({
|
||||
node: reference.identifier,
|
||||
messageId: "usedBeforeDefined",
|
||||
data: reference.identifier,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
scope.childScopes.forEach(checkReferencesInScope);
|
||||
}
|
||||
|
||||
return {
|
||||
Program(node) {
|
||||
checkReferencesInScope(sourceCode.getScope(node));
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("check any inference", () => {
|
||||
const t1 = z.any();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
expectTypeOf<t1>().toEqualTypeOf<any>();
|
||||
});
|
||||
|
||||
test("check unknown inference", () => {
|
||||
const t1 = z.unknown();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
expectTypeOf<t1>().toEqualTypeOf<unknown>();
|
||||
});
|
||||
|
||||
test("check never inference", () => {
|
||||
const t1 = z.never();
|
||||
expect(() => t1.parse(undefined)).toThrow();
|
||||
expect(() => t1.parse("asdf")).toThrow();
|
||||
expect(() => t1.parse(null)).toThrow();
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_write_only_error.js";
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "@influxdata/influxdb-client",
|
||||
"version": "1.35.0",
|
||||
"description": "InfluxDB 2.x client",
|
||||
"scripts": {
|
||||
"apidoc:extract": "api-extractor run",
|
||||
"build": "yarn run clean && yarn tsup --config ./tsup.config.browser.ts && yarn tsup",
|
||||
"clean": "rimraf dist build coverage .nyc_output doc *.lcov reports",
|
||||
"coverage": "nyc mocha --require ts-node/register 'test/**/*.test.ts' --exit",
|
||||
"coverage:ci": "yarn run coverage && yarn run coverage:lcov",
|
||||
"coverage:lcov": "yarn run --silent nyc report --reporter=text-lcov > coverage/coverage.lcov",
|
||||
"test": "yarn run lint && yarn run typecheck && yarn run test:all",
|
||||
"test:all": "mocha --require esbuild-runner/register 'test/**/*.test.ts' --exit",
|
||||
"test:unit": "mocha --require esbuild-runner/register 'test/unit/**/*.test.ts' --exit",
|
||||
"test:integration": "mocha --require esbuild-runner/register 'test/integration/**/*.test.ts' --exit",
|
||||
"test:ci": "yarn run lint:ci && yarn run test:all --exit --reporter mocha-junit-reporter --reporter-options mochaFile=../../reports/core_mocha/test-results.xml",
|
||||
"test:watch": "mocha --require esbuild-runner/register 'test/unit/**/*.test.ts' --watch-extensions ts --watch",
|
||||
"typecheck": "tsc --noEmit --pretty",
|
||||
"lint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
|
||||
"lint:ci": "yarn run lint --format junit --output-file ../../reports/core_eslint/eslint.xml",
|
||||
"lint:fix": "eslint --fix 'src/**/*.ts' 'test/**/*.ts'"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"module:browser": "dist/index.browser.mjs",
|
||||
"browser": "dist/index.browser.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"browser": {
|
||||
"import": "./dist/index.browser.mjs",
|
||||
"require": "./dist/index.browser.js",
|
||||
"script": "./dist/influxdb.js",
|
||||
"default": "./dist/index.browser.js"
|
||||
},
|
||||
"deno": "./dist/index.browser.mjs",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/influxdata/influxdb-client-js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/influxdata/influxdb-client-js",
|
||||
"directory": "packages/core"
|
||||
},
|
||||
"keywords": [
|
||||
"influxdb",
|
||||
"influxdata"
|
||||
],
|
||||
"author": {
|
||||
"name": "Pavel Zavora"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@microsoft/api-extractor": "^7.31.0",
|
||||
"@types/chai": "^4.2.5",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/sinon": "^17.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"esbuild": "^0.23.0",
|
||||
"esbuild-runner": "^2.2.1",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-tsdoc": "^0.3.0",
|
||||
"follow-redirects": "^1.14.7",
|
||||
"mocha": "^10.0.0",
|
||||
"mocha-junit-reporter": "^2.0.2",
|
||||
"nock": "^13.2.8",
|
||||
"nyc": "^17.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"rimraf": "^5.0.1",
|
||||
"rxjs": "^7.2.0",
|
||||
"sinon": "^18.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsup": "^8.0.2",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"gitHead": "fe5bc8eb17156b7e93434dc1caaa479f3181ede4"
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'method-signature-style',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Enforce using a particular method signature syntax',
|
||||
},
|
||||
fixable: 'code',
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
convertToMethodSignature: 'Convert to a method signature. This removes the `readonly` modifier, allowing the member to be reassigned.',
|
||||
errorMethod: 'Shorthand method signature is forbidden. Use a function property instead.',
|
||||
errorProperty: 'Function property signature is forbidden. Use a method shorthand instead.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'string',
|
||||
description: 'The method signature style to enforce using.',
|
||||
enum: ['property', 'method'],
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: ['property'],
|
||||
create(context, [mode]) {
|
||||
function getMethodKey(node) {
|
||||
let key = context.sourceCode.getText(node.key);
|
||||
if (node.computed) {
|
||||
key = `[${key}]`;
|
||||
}
|
||||
if (node.optional) {
|
||||
key = `${key}?`;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
function getMethodParams(node) {
|
||||
let params = '()';
|
||||
if (node.params.length > 0) {
|
||||
const openingParen = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.params[0], util_1.isOpeningParenToken), 'Missing opening paren before first parameter');
|
||||
const closingParen = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.params[node.params.length - 1], util_1.isClosingParenToken), 'Missing closing paren after last parameter');
|
||||
params = context.sourceCode.text.substring(openingParen.range[0], closingParen.range[1]);
|
||||
}
|
||||
if (node.typeParameters != null) {
|
||||
const typeParams = context.sourceCode.getText(node.typeParameters);
|
||||
params = `${typeParams}${params}`;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
function getMethodReturnType(node) {
|
||||
return node.returnType == null
|
||||
? // if the method has no return type, it implicitly has an `any` return type
|
||||
// we just make it explicit here so we can do the fix
|
||||
'any'
|
||||
: context.sourceCode.getText(node.returnType.typeAnnotation);
|
||||
}
|
||||
function getDelimiter(node) {
|
||||
const lastToken = context.sourceCode.getLastToken(node);
|
||||
if (lastToken &&
|
||||
((0, util_1.isSemicolonToken)(lastToken) || (0, util_1.isCommaToken)(lastToken))) {
|
||||
return lastToken.value;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function isNodeParentModuleDeclaration(node) {
|
||||
if (!node.parent) {
|
||||
return false;
|
||||
}
|
||||
if (node.parent.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration) {
|
||||
return true;
|
||||
}
|
||||
if (node.parent.type === utils_1.AST_NODE_TYPES.Program) {
|
||||
return false;
|
||||
}
|
||||
return isNodeParentModuleDeclaration(node.parent);
|
||||
}
|
||||
return {
|
||||
...(mode === 'property' && {
|
||||
TSMethodSignature(methodNode) {
|
||||
if (methodNode.kind !== 'method') {
|
||||
return;
|
||||
}
|
||||
const skipFix = returnTypeReferencesThisType(methodNode.returnType);
|
||||
const parent = methodNode.parent;
|
||||
const members = parent.type === utils_1.AST_NODE_TYPES.TSInterfaceBody
|
||||
? parent.body
|
||||
: parent.members;
|
||||
const duplicatedKeyMethodNodes = members.filter((element) => element.type === utils_1.AST_NODE_TYPES.TSMethodSignature &&
|
||||
element !== methodNode &&
|
||||
getMethodKey(element) === getMethodKey(methodNode));
|
||||
const isParentModule = isNodeParentModuleDeclaration(methodNode);
|
||||
if (duplicatedKeyMethodNodes.length > 0) {
|
||||
if (isParentModule) {
|
||||
context.report({
|
||||
node: methodNode,
|
||||
messageId: 'errorMethod',
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node: methodNode,
|
||||
messageId: 'errorMethod',
|
||||
fix: skipFix
|
||||
? undefined
|
||||
: function* fix(fixer) {
|
||||
const methodNodes = [
|
||||
methodNode,
|
||||
...duplicatedKeyMethodNodes,
|
||||
].sort((a, b) => (a.range[0] < b.range[0] ? -1 : 1));
|
||||
const typeString = methodNodes
|
||||
.map(node => {
|
||||
const params = getMethodParams(node);
|
||||
const returnType = getMethodReturnType(node);
|
||||
return `(${params} => ${returnType})`;
|
||||
})
|
||||
.join(' & ');
|
||||
const key = getMethodKey(methodNode);
|
||||
const delimiter = getDelimiter(methodNode);
|
||||
yield fixer.replaceText(methodNode, `${key}: ${typeString}${delimiter}`);
|
||||
for (const node of duplicatedKeyMethodNodes) {
|
||||
const lastToken = context.sourceCode.getLastToken(node);
|
||||
if (lastToken) {
|
||||
const nextToken = context.sourceCode.getTokenAfter(lastToken);
|
||||
if (nextToken) {
|
||||
yield fixer.remove(node);
|
||||
yield fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], '');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isParentModule) {
|
||||
context.report({
|
||||
node: methodNode,
|
||||
messageId: 'errorMethod',
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node: methodNode,
|
||||
messageId: 'errorMethod',
|
||||
fix: skipFix
|
||||
? undefined
|
||||
: fixer => {
|
||||
const key = getMethodKey(methodNode);
|
||||
const params = getMethodParams(methodNode);
|
||||
const returnType = getMethodReturnType(methodNode);
|
||||
const delimiter = getDelimiter(methodNode);
|
||||
return fixer.replaceText(methodNode, `${key}: ${params} => ${returnType}${delimiter}`);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
...(mode === 'method' && {
|
||||
TSPropertySignature(propertyNode) {
|
||||
const typeNode = propertyNode.typeAnnotation?.typeAnnotation;
|
||||
if (typeNode?.type !== utils_1.AST_NODE_TYPES.TSFunctionType) {
|
||||
return;
|
||||
}
|
||||
const fix = fixer => {
|
||||
const key = getMethodKey(propertyNode);
|
||||
const params = getMethodParams(typeNode);
|
||||
const returnType = getMethodReturnType(typeNode);
|
||||
const delimiter = getDelimiter(propertyNode);
|
||||
return fixer.replaceText(propertyNode, `${key}${params}: ${returnType}${delimiter}`);
|
||||
};
|
||||
// There is no syntax for a `readonly` method signature, so converting
|
||||
// a `readonly` function-typed property drops the `readonly` modifier.
|
||||
// That is a behavioral change (a method may be reassigned, a
|
||||
// `readonly` property may not), so it is offered as a suggestion
|
||||
// rather than applied as an autofix.
|
||||
if (propertyNode.readonly) {
|
||||
context.report({
|
||||
node: propertyNode,
|
||||
messageId: 'errorProperty',
|
||||
suggest: [{ messageId: 'convertToMethodSignature', fix }],
|
||||
});
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node: propertyNode,
|
||||
messageId: 'errorProperty',
|
||||
fix,
|
||||
});
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
function returnTypeReferencesThisType(node) {
|
||||
return (node &&
|
||||
(0, util_1.forEachChildESTree)(node.typeAnnotation, child => child.type === utils_1.AST_NODE_TYPES.TSThisType));
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
'use strict'
|
||||
|
||||
const SonicBoom = require('.')
|
||||
const sonic = new SonicBoom({ fd: process.stdout.fd })
|
||||
|
||||
let count = 0
|
||||
function scheduleWrites () {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
sonic.write('hello sonic\n')
|
||||
console.log('hello console')
|
||||
}
|
||||
|
||||
if (++count < 10) {
|
||||
setTimeout(scheduleWrites, 100)
|
||||
}
|
||||
}
|
||||
|
||||
scheduleWrites()
|
||||
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
var _class_check_private_static_access = require("./_class_check_private_static_access.cjs");
|
||||
|
||||
function _class_static_private_method_get(receiver, classConstructor, method) {
|
||||
_class_check_private_static_access._(receiver, classConstructor);
|
||||
|
||||
return method;
|
||||
}
|
||||
exports._ = _class_static_private_method_get;
|
||||
@@ -0,0 +1,4 @@
|
||||
function _newArrowCheck(n, r) {
|
||||
if (n !== r) throw new TypeError("Cannot instantiate an arrow function");
|
||||
}
|
||||
export { _newArrowCheck as default };
|
||||
Reference in New Issue
Block a user