WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-present, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { TSESLint } from '@typescript-eslint/utils';
|
||||
declare const _default: TSESLint.RuleModule<"disallowedPromiseAwait" | "disallowedPromiseAwaitSuggestion" | "nonPromiseAwait" | "requiredPromiseAwait" | "requiredPromiseAwaitSuggestion", [string], import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,18 @@
|
||||
import { createRequire } from 'module';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname } from 'path';
|
||||
|
||||
/**
|
||||
* @fileoverview Universal module importer
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const require = createRequire(__dirname + "/");
|
||||
const { ModuleImporter } = require("./module-importer.cjs");
|
||||
|
||||
export { ModuleImporter };
|
||||
@@ -0,0 +1 @@
|
||||
export { __decorate as _ } from "tslib";
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
export declare function describeFilePath(filePath: string, tsconfigRootDir: string): string;
|
||||
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* @fileoverview Validate strings passed to the RegExp constructor
|
||||
* @author Michael Ficarra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const RegExpValidator = require("@eslint-community/regexpp").RegExpValidator;
|
||||
const validator = new RegExpValidator();
|
||||
const validFlags = "dgimsuvy";
|
||||
const undefined1 = void 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
defaultOptions: [{}],
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow invalid regular expression strings in `RegExp` constructors",
|
||||
recommended: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-invalid-regexp",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allowConstructorFlags: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
regexMessage: "{{message}}.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
const [{ allowConstructorFlags }] = context.options;
|
||||
let allowedFlags = [];
|
||||
|
||||
if (allowConstructorFlags) {
|
||||
const temp = allowConstructorFlags
|
||||
.join("")
|
||||
.replace(new RegExp(`[${validFlags}]`, "gu"), "");
|
||||
|
||||
if (temp) {
|
||||
allowedFlags = [...new Set(temp)];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports error with the provided message.
|
||||
* @param {ASTNode} node The node holding the invalid RegExp
|
||||
* @param {string} message The message to report.
|
||||
* @returns {void}
|
||||
*/
|
||||
function report(node, message) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "regexMessage",
|
||||
data: { message },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if node is a string
|
||||
* @param {ASTNode} node node to evaluate
|
||||
* @returns {boolean} True if its a string
|
||||
* @private
|
||||
*/
|
||||
function isString(node) {
|
||||
return (
|
||||
node &&
|
||||
node.type === "Literal" &&
|
||||
typeof node.value === "string"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets flags of a regular expression created by the given `RegExp()` or `new RegExp()` call
|
||||
* Examples:
|
||||
* new RegExp(".") // => ""
|
||||
* new RegExp(".", "gu") // => "gu"
|
||||
* new RegExp(".", flags) // => null
|
||||
* @param {ASTNode} node `CallExpression` or `NewExpression` node
|
||||
* @returns {string|null} flags if they can be determined, `null` otherwise
|
||||
* @private
|
||||
*/
|
||||
function getFlags(node) {
|
||||
if (node.arguments.length < 2) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (isString(node.arguments[1])) {
|
||||
return node.arguments[1].value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check syntax error in a given pattern.
|
||||
* @param {string} pattern The RegExp pattern to validate.
|
||||
* @param {Object} flags The RegExp flags to validate.
|
||||
* @param {boolean} [flags.unicode] The Unicode flag.
|
||||
* @param {boolean} [flags.unicodeSets] The UnicodeSets flag.
|
||||
* @returns {string|null} The syntax error.
|
||||
*/
|
||||
function validateRegExpPattern(pattern, flags) {
|
||||
try {
|
||||
validator.validatePattern(
|
||||
pattern,
|
||||
undefined1,
|
||||
undefined1,
|
||||
flags,
|
||||
);
|
||||
return null;
|
||||
} catch (err) {
|
||||
return err.message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check syntax error in a given flags.
|
||||
* @param {string|null} flags The RegExp flags to validate.
|
||||
* @param {string|null} flagsToCheck The RegExp invalid flags.
|
||||
* @param {string} allFlags all valid and allowed flags.
|
||||
* @returns {string|null} The syntax error.
|
||||
*/
|
||||
function validateRegExpFlags(flags, flagsToCheck, allFlags) {
|
||||
const duplicateFlags = [];
|
||||
|
||||
if (typeof flagsToCheck === "string") {
|
||||
for (const flag of flagsToCheck) {
|
||||
if (allFlags.includes(flag)) {
|
||||
duplicateFlags.push(flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* `regexpp` checks the combination of `u` and `v` flags when parsing `Pattern` according to `ecma262`,
|
||||
* but this rule may check only the flag when the pattern is unidentifiable, so check it here.
|
||||
* https://tc39.es/ecma262/multipage/text-processing.html#sec-parsepattern
|
||||
*/
|
||||
if (flags && flags.includes("u") && flags.includes("v")) {
|
||||
return "Regex 'u' and 'v' flags cannot be used together";
|
||||
}
|
||||
|
||||
if (duplicateFlags.length > 0) {
|
||||
return `Duplicate flags ('${duplicateFlags.join("")}') supplied to RegExp constructor`;
|
||||
}
|
||||
|
||||
if (!flagsToCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `Invalid flags supplied to RegExp constructor '${flagsToCheck}'`;
|
||||
}
|
||||
|
||||
return {
|
||||
"CallExpression, NewExpression"(node) {
|
||||
if (
|
||||
node.callee.type !== "Identifier" ||
|
||||
node.callee.name !== "RegExp" ||
|
||||
!sourceCode.isGlobalReference(node.callee)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const flags = getFlags(node);
|
||||
let flagsToCheck = flags;
|
||||
const allFlags =
|
||||
allowedFlags.length > 0
|
||||
? validFlags.split("").concat(allowedFlags)
|
||||
: validFlags.split("");
|
||||
|
||||
if (flags) {
|
||||
allFlags.forEach(flag => {
|
||||
flagsToCheck = flagsToCheck.replace(flag, "");
|
||||
});
|
||||
}
|
||||
|
||||
let message = validateRegExpFlags(
|
||||
flags,
|
||||
flagsToCheck,
|
||||
allFlags,
|
||||
);
|
||||
|
||||
if (message) {
|
||||
report(node, message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isString(node.arguments[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pattern = node.arguments[0].value;
|
||||
|
||||
message =
|
||||
// If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag
|
||||
flags === null
|
||||
? validateRegExpPattern(pattern, {
|
||||
unicode: true,
|
||||
unicodeSets: false,
|
||||
}) &&
|
||||
validateRegExpPattern(pattern, {
|
||||
unicode: false,
|
||||
unicodeSets: true,
|
||||
}) &&
|
||||
validateRegExpPattern(pattern, {
|
||||
unicode: false,
|
||||
unicodeSets: false,
|
||||
})
|
||||
: validateRegExpPattern(pattern, {
|
||||
unicode: flags.includes("u"),
|
||||
unicodeSets: flags.includes("v"),
|
||||
});
|
||||
|
||||
if (message) {
|
||||
report(node, message);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"visitor.generated.d.ts","sourceRoot":"","sources":["../../src/ast/visitor.generated.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAwHR,IAAI,EACJ,SAAS,EAqDZ,MAAM,UAAU,CAAC;AA4OlB;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,GAAG,SAAS,IAAI,GAAG,SAAS,EAAE,IAAI,SAAS,IAAI,EACrE,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,IAAI,GACnC,IAAI,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;AAC5B;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,SAAS,IAAI,GAAG,SAAS,EAClD,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GAC/B,IAAI,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;AAU5B;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAChG,wBAAgB,UAAU,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAUxH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC;AACrG,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,CAAC;AAmB7H;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC;AAC7E,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC"}
|
||||
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2015_reflect = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2015_reflect = {
|
||||
libs: [],
|
||||
variables: [['Reflect', base_config_1.TYPE_VALUE]],
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("type guard", () => {
|
||||
const stringToNumber = z.string().transform((arg) => arg.length);
|
||||
|
||||
const s1 = z.object({
|
||||
stringToNumber,
|
||||
});
|
||||
type t1 = z.input<typeof s1>;
|
||||
|
||||
const data = { stringToNumber: "asdf" };
|
||||
const parsed = s1.safeParse(data);
|
||||
if (parsed.success) {
|
||||
util.assertEqual<typeof data, t1>(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("test this binding", () => {
|
||||
const callback = (predicate: (val: string) => boolean) => {
|
||||
return predicate("hello");
|
||||
};
|
||||
|
||||
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
||||
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright Fedor Indutny, 2015.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "../../cjs/_construct.cjs",
|
||||
"module": "../../esm/_construct.js"
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
/**
|
||||
* @fileoverview The main file for the hfs package.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
/* global Buffer:readonly, URL */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("@humanfs/types").HfsImpl} HfsImpl */
|
||||
/** @typedef {import("@humanfs/types").HfsDirectoryEntry} HfsDirectoryEntry */
|
||||
/** @typedef {import("node:fs/promises")} Fsp */
|
||||
/** @typedef {import("fs").Dirent} Dirent */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Imports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
import { Hfs } from "@humanfs/core";
|
||||
import path from "node:path";
|
||||
import { Retrier } from "@humanwhocodes/retry";
|
||||
import nativeFsp from "node:fs/promises";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const RETRY_ERROR_CODES = new Set(["ENFILE", "EMFILE"]);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A class representing a directory entry.
|
||||
* @implements {HfsDirectoryEntry}
|
||||
*/
|
||||
class NodeHfsDirectoryEntry {
|
||||
/**
|
||||
* The name of the directory entry.
|
||||
* @type {string}
|
||||
*/
|
||||
name;
|
||||
|
||||
/**
|
||||
* True if the entry is a file.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isFile;
|
||||
|
||||
/**
|
||||
* True if the entry is a directory.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isDirectory;
|
||||
|
||||
/**
|
||||
* True if the entry is a symbolic link.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isSymlink;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Dirent} dirent The directory entry to wrap.
|
||||
*/
|
||||
constructor(dirent) {
|
||||
this.name = dirent.name;
|
||||
this.isFile = dirent.isFile();
|
||||
this.isDirectory = dirent.isDirectory();
|
||||
this.isSymlink = dirent.isSymbolicLink();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A class representing the Node.js implementation of Hfs.
|
||||
* @implements {HfsImpl}
|
||||
*/
|
||||
export class NodeHfsImpl {
|
||||
/**
|
||||
* The file system module to use.
|
||||
* @type {Fsp}
|
||||
*/
|
||||
#fsp;
|
||||
|
||||
/**
|
||||
* The retryer object used for retrying operations.
|
||||
* @type {Retrier}
|
||||
*/
|
||||
#retrier;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {object} [options] The options for the instance.
|
||||
* @param {Fsp} [options.fsp] The file system module to use.
|
||||
*/
|
||||
constructor({ fsp = nativeFsp } = {}) {
|
||||
this.#fsp = fsp;
|
||||
this.#retrier = new Retrier(error => RETRY_ERROR_CODES.has(error.code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file and returns the contents as an Uint8Array.
|
||||
* @param {string|URL} filePath The path to the file to read.
|
||||
* @returns {Promise<Uint8Array|undefined>} A promise that resolves with the contents
|
||||
* of the file or undefined if the file doesn't exist.
|
||||
* @throws {Error} If the file cannot be read.
|
||||
* @throws {TypeError} If the file path is not a string.
|
||||
*/
|
||||
bytes(filePath) {
|
||||
return this.#retrier
|
||||
.retry(() => this.#fsp.readFile(filePath))
|
||||
.then(buffer => new Uint8Array(buffer.buffer))
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a value to a file. If the value is a string, UTF-8 encoding is used.
|
||||
* @param {string|URL} filePath The path to the file to write.
|
||||
* @param {Uint8Array} contents The contents to write to the
|
||||
* file.
|
||||
* @returns {Promise<void>} A promise that resolves when the file is
|
||||
* written.
|
||||
* @throws {TypeError} If the file path is not a string.
|
||||
* @throws {Error} If the file cannot be written.
|
||||
*/
|
||||
async write(filePath, contents) {
|
||||
const value = Buffer.from(contents);
|
||||
|
||||
return this.#retrier
|
||||
.retry(() => this.#fsp.writeFile(filePath, value))
|
||||
.catch(error => {
|
||||
// the directory may not exist, so create it
|
||||
if (error.code === "ENOENT") {
|
||||
const dirPath = path.dirname(
|
||||
filePath instanceof URL
|
||||
? fileURLToPath(filePath)
|
||||
: filePath,
|
||||
);
|
||||
|
||||
return this.#fsp
|
||||
.mkdir(dirPath, { recursive: true })
|
||||
.then(() => this.#fsp.writeFile(filePath, value));
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a value to a file. If the value is a string, UTF-8 encoding is used.
|
||||
* @param {string|URL} filePath The path to the file to append to.
|
||||
* @param {Uint8Array} contents The contents to append to the
|
||||
* file.
|
||||
* @returns {Promise<void>} A promise that resolves when the file is
|
||||
* written.
|
||||
* @throws {TypeError} If the file path is not a string.
|
||||
* @throws {Error} If the file cannot be appended to.
|
||||
*/
|
||||
async append(filePath, contents) {
|
||||
const value = Buffer.from(contents);
|
||||
|
||||
return this.#retrier
|
||||
.retry(() => this.#fsp.appendFile(filePath, value))
|
||||
.catch(error => {
|
||||
// the directory may not exist, so create it
|
||||
if (error.code === "ENOENT") {
|
||||
const dirPath = path.dirname(
|
||||
filePath instanceof URL
|
||||
? fileURLToPath(filePath)
|
||||
: filePath,
|
||||
);
|
||||
|
||||
return this.#fsp
|
||||
.mkdir(dirPath, { recursive: true })
|
||||
.then(() => this.#fsp.appendFile(filePath, value));
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file exists.
|
||||
* @param {string|URL} filePath The path to the file to check.
|
||||
* @returns {Promise<boolean>} A promise that resolves with true if the
|
||||
* file exists or false if it does not.
|
||||
* @throws {Error} If the operation fails with a code other than ENOENT.
|
||||
*/
|
||||
isFile(filePath) {
|
||||
return this.#fsp
|
||||
.stat(filePath)
|
||||
.then(stat => stat.isFile())
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a directory exists.
|
||||
* @param {string|URL} dirPath The path to the directory to check.
|
||||
* @returns {Promise<boolean>} A promise that resolves with true if the
|
||||
* directory exists or false if it does not.
|
||||
* @throws {Error} If the operation fails with a code other than ENOENT.
|
||||
*/
|
||||
isDirectory(dirPath) {
|
||||
return this.#fsp
|
||||
.stat(dirPath)
|
||||
.then(stat => stat.isDirectory())
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory recursively.
|
||||
* @param {string|URL} dirPath The path to the directory to create.
|
||||
* @returns {Promise<void>} A promise that resolves when the directory is
|
||||
* created.
|
||||
*/
|
||||
async createDirectory(dirPath) {
|
||||
await this.#fsp.mkdir(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file or empty directory.
|
||||
* @param {string|URL} fileOrDirPath The path to the file or directory to
|
||||
* delete.
|
||||
* @returns {Promise<boolean>} A promise that resolves when the file or
|
||||
* directory is deleted, true if the file or directory is deleted, false
|
||||
* if the file or directory does not exist.
|
||||
* @throws {TypeError} If the file or directory path is not a string.
|
||||
* @throws {Error} If the file or directory cannot be deleted.
|
||||
*/
|
||||
delete(fileOrDirPath) {
|
||||
return this.#fsp
|
||||
.rm(fileOrDirPath)
|
||||
.then(() => true)
|
||||
.catch(error => {
|
||||
if (error.code === "ERR_FS_EISDIR") {
|
||||
return this.#fsp.rmdir(fileOrDirPath).then(() => true);
|
||||
}
|
||||
|
||||
if (error.code === "ENOENT") {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file or directory recursively.
|
||||
* @param {string|URL} fileOrDirPath The path to the file or directory to
|
||||
* delete.
|
||||
* @returns {Promise<boolean>} A promise that resolves when the file or
|
||||
* directory is deleted, true if the file or directory is deleted, false
|
||||
* if the file or directory does not exist.
|
||||
* @throws {TypeError} If the file or directory path is not a string.
|
||||
* @throws {Error} If the file or directory cannot be deleted.
|
||||
*/
|
||||
deleteAll(fileOrDirPath) {
|
||||
return this.#fsp
|
||||
.rm(fileOrDirPath, { recursive: true })
|
||||
.then(() => true)
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of directory entries for the given path.
|
||||
* @param {string|URL} dirPath The path to the directory to read.
|
||||
* @returns {AsyncIterable<HfsDirectoryEntry>} A promise that resolves with the
|
||||
* directory entries.
|
||||
* @throws {TypeError} If the directory path is not a string.
|
||||
* @throws {Error} If the directory cannot be read.
|
||||
*/
|
||||
async *list(dirPath) {
|
||||
const entries = await this.#fsp.readdir(dirPath, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
|
||||
for (const entry of entries) {
|
||||
yield new NodeHfsDirectoryEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a file. This method handles ENOENT errors
|
||||
* and returns undefined in that case.
|
||||
* @param {string|URL} filePath The path to the file to read.
|
||||
* @returns {Promise<number|undefined>} A promise that resolves with the size of the
|
||||
* file in bytes or undefined if the file doesn't exist.
|
||||
*/
|
||||
size(filePath) {
|
||||
return this.#fsp
|
||||
.stat(filePath)
|
||||
.then(stat => stat.size)
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modified date of a file or directory. This method handles ENOENT errors
|
||||
* and returns undefined in that case.
|
||||
* @param {string|URL} fileOrDirPath The path to the file to read.
|
||||
* @returns {Promise<Date|undefined>} A promise that resolves with the last modified
|
||||
* date of the file or directory, or undefined if the file doesn't exist.
|
||||
*/
|
||||
lastModified(fileOrDirPath) {
|
||||
return this.#fsp
|
||||
.stat(fileOrDirPath)
|
||||
.then(stat => stat.mtime)
|
||||
.catch(error => {
|
||||
if (error.code === "ENOENT") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a file from one location to another.
|
||||
* @param {string|URL} source The path to the file to copy.
|
||||
* @param {string|URL} destination The path to copy the file to.
|
||||
* @returns {Promise<void>} A promise that resolves when the file is copied.
|
||||
* @throws {Error} If the source file does not exist.
|
||||
* @throws {Error} If the source file is a directory.
|
||||
* @throws {Error} If the destination file is a directory.
|
||||
*/
|
||||
async copy(source, destination) {
|
||||
const stat = await this.#fsp.lstat(source);
|
||||
if (stat.isSymbolicLink()) {
|
||||
const target = await this.#fsp.readlink(source);
|
||||
return this.#fsp.symlink(target, destination);
|
||||
}
|
||||
return this.#fsp.copyFile(source, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a file or directory from one location to another.
|
||||
* @param {string|URL} source The path to the file or directory to copy.
|
||||
* @param {string|URL} destination The path to copy the file or directory to.
|
||||
* @returns {Promise<void>} A promise that resolves when the file or directory is
|
||||
* copied.
|
||||
* @throws {Error} If the source file or directory does not exist.
|
||||
* @throws {Error} If the destination file or directory is a directory.
|
||||
*/
|
||||
async copyAll(source, destination) {
|
||||
// for files use copy() and exit
|
||||
if (await this.isFile(source)) {
|
||||
return this.copy(source, destination);
|
||||
}
|
||||
|
||||
const sourceStr =
|
||||
source instanceof URL ? fileURLToPath(source) : source;
|
||||
|
||||
const destinationStr =
|
||||
destination instanceof URL
|
||||
? fileURLToPath(destination)
|
||||
: destination;
|
||||
|
||||
// for directories, create the destination directory and copy each entry
|
||||
await this.createDirectory(destination);
|
||||
|
||||
for await (const entry of this.list(source)) {
|
||||
const fromEntryPath = path.join(sourceStr, entry.name);
|
||||
const toEntryPath = path.join(destinationStr, entry.name);
|
||||
|
||||
if (entry.isSymlink) {
|
||||
const target = await this.#fsp.readlink(fromEntryPath);
|
||||
await this.#fsp.symlink(target, toEntryPath);
|
||||
} else if (entry.isDirectory) {
|
||||
await this.copyAll(fromEntryPath, toEntryPath);
|
||||
} else {
|
||||
await this.copy(fromEntryPath, toEntryPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file from the source path to the destination path.
|
||||
* @param {string|URL} source The location of the file to move.
|
||||
* @param {string|URL} destination The destination of the file to move.
|
||||
* @returns {Promise<void>} A promise that resolves when the move is complete.
|
||||
* @throws {TypeError} If the file paths are not strings.
|
||||
* @throws {Error} If the file cannot be moved.
|
||||
*/
|
||||
move(source, destination) {
|
||||
return this.#fsp.stat(source).then(stat => {
|
||||
if (stat.isDirectory()) {
|
||||
throw new Error(
|
||||
`EISDIR: illegal operation on a directory, move '${source}' -> '${destination}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return this.#fsp.rename(source, destination);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file or directory from the source path to the destination path.
|
||||
* @param {string|URL} source The location of the file or directory to move.
|
||||
* @param {string|URL} destination The destination of the file or directory to move.
|
||||
* @returns {Promise<void>} A promise that resolves when the move is complete.
|
||||
* @throws {TypeError} If the file paths are not strings.
|
||||
* @throws {Error} If the file or directory cannot be moved.
|
||||
*/
|
||||
async moveAll(source, destination) {
|
||||
return this.#fsp.rename(source, destination);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class representing a file system utility library.
|
||||
* @implements {HfsImpl}
|
||||
*/
|
||||
export class NodeHfs extends Hfs {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {object} [options] The options for the instance.
|
||||
* @param {Fsp} [options.fsp] The file system module to use.
|
||||
*/
|
||||
constructor({ fsp } = {}) {
|
||||
super({ impl: new NodeHfsImpl({ fsp }) });
|
||||
}
|
||||
}
|
||||
|
||||
export const hfs = new NodeHfs();
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"languageVariant.d.ts","sourceRoot":"","sources":["../../src/enums/languageVariant.ts"],"names":[],"mappings":"AAAA,eAAO,IAAI,eAAe,EAAE,GAAG,CAAC"}
|
||||
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* @fileoverview Rule to enforce grouped require statements for Node.JS
|
||||
* @author Raphael Pigulla
|
||||
* @deprecated in ESLint v7.0.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: {
|
||||
message: "Node.js rules were moved out of ESLint core.",
|
||||
url: "https://eslint.org/docs/latest/use/migrating-to-7.0.0#deprecate-node-rules",
|
||||
deprecatedSince: "7.0.0",
|
||||
availableUntil: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"eslint-plugin-n now maintains deprecated Node.js-related rules.",
|
||||
plugin: {
|
||||
name: "eslint-plugin-n",
|
||||
url: "https://github.com/eslint-community/eslint-plugin-n",
|
||||
},
|
||||
rule: {
|
||||
name: "no-mixed-requires",
|
||||
url: "https://github.com/eslint-community/eslint-plugin-n/tree/master/docs/rules/no-mixed-requires.md",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow `require` calls to be mixed with regular variable declarations",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-mixed-requires",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
grouping: {
|
||||
type: "boolean",
|
||||
},
|
||||
allowCall: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
messages: {
|
||||
noMixRequire: "Do not mix 'require' and other declarations.",
|
||||
noMixCoreModuleFileComputed:
|
||||
"Do not mix core, module, file and computed requires.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const options = context.options[0];
|
||||
let grouping = false,
|
||||
allowCall = false;
|
||||
|
||||
if (typeof options === "object") {
|
||||
grouping = options.grouping;
|
||||
allowCall = options.allowCall;
|
||||
} else {
|
||||
grouping = !!options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of built-in modules.
|
||||
* @returns {string[]} An array of built-in Node.js modules.
|
||||
*/
|
||||
function getBuiltinModules() {
|
||||
/*
|
||||
* This list is generated using:
|
||||
* `require("repl")._builtinLibs.concat('repl').sort()`
|
||||
* This particular list is as per nodejs v0.12.2 and iojs v0.7.1
|
||||
*/
|
||||
return [
|
||||
"assert",
|
||||
"buffer",
|
||||
"child_process",
|
||||
"cluster",
|
||||
"crypto",
|
||||
"dgram",
|
||||
"dns",
|
||||
"domain",
|
||||
"events",
|
||||
"fs",
|
||||
"http",
|
||||
"https",
|
||||
"net",
|
||||
"os",
|
||||
"path",
|
||||
"punycode",
|
||||
"querystring",
|
||||
"readline",
|
||||
"repl",
|
||||
"smalloc",
|
||||
"stream",
|
||||
"string_decoder",
|
||||
"tls",
|
||||
"tty",
|
||||
"url",
|
||||
"util",
|
||||
"v8",
|
||||
"vm",
|
||||
"zlib",
|
||||
];
|
||||
}
|
||||
|
||||
const BUILTIN_MODULES = getBuiltinModules();
|
||||
|
||||
const DECL_REQUIRE = "require",
|
||||
DECL_UNINITIALIZED = "uninitialized",
|
||||
DECL_OTHER = "other";
|
||||
|
||||
const REQ_CORE = "core",
|
||||
REQ_FILE = "file",
|
||||
REQ_MODULE = "module",
|
||||
REQ_COMPUTED = "computed";
|
||||
|
||||
/**
|
||||
* Determines the type of a declaration statement.
|
||||
* @param {ASTNode} initExpression The init node of the VariableDeclarator.
|
||||
* @returns {string} The type of declaration represented by the expression.
|
||||
*/
|
||||
function getDeclarationType(initExpression) {
|
||||
if (!initExpression) {
|
||||
// "var x;"
|
||||
return DECL_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (
|
||||
initExpression.type === "CallExpression" &&
|
||||
initExpression.callee.type === "Identifier" &&
|
||||
initExpression.callee.name === "require"
|
||||
) {
|
||||
// "var x = require('util');"
|
||||
return DECL_REQUIRE;
|
||||
}
|
||||
if (
|
||||
allowCall &&
|
||||
initExpression.type === "CallExpression" &&
|
||||
initExpression.callee.type === "CallExpression"
|
||||
) {
|
||||
// "var x = require('diagnose')('sub-module');"
|
||||
return getDeclarationType(initExpression.callee);
|
||||
}
|
||||
if (initExpression.type === "MemberExpression") {
|
||||
// "var x = require('glob').Glob;"
|
||||
return getDeclarationType(initExpression.object);
|
||||
}
|
||||
|
||||
// "var x = 42;"
|
||||
return DECL_OTHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the type of module that is loaded via require.
|
||||
* @param {ASTNode} initExpression The init node of the VariableDeclarator.
|
||||
* @returns {string} The module type.
|
||||
*/
|
||||
function inferModuleType(initExpression) {
|
||||
if (initExpression.type === "MemberExpression") {
|
||||
// "var x = require('glob').Glob;"
|
||||
return inferModuleType(initExpression.object);
|
||||
}
|
||||
if (initExpression.arguments.length === 0) {
|
||||
// "var x = require();"
|
||||
return REQ_COMPUTED;
|
||||
}
|
||||
|
||||
const arg = initExpression.arguments[0];
|
||||
|
||||
if (arg.type !== "Literal" || typeof arg.value !== "string") {
|
||||
// "var x = require(42);"
|
||||
return REQ_COMPUTED;
|
||||
}
|
||||
|
||||
if (BUILTIN_MODULES.includes(arg.value)) {
|
||||
// "var fs = require('fs');"
|
||||
return REQ_CORE;
|
||||
}
|
||||
if (/^\.{0,2}\//u.test(arg.value)) {
|
||||
// "var utils = require('./utils');"
|
||||
return REQ_FILE;
|
||||
}
|
||||
|
||||
// "var async = require('async');"
|
||||
return REQ_MODULE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the list of variable declarations is mixed, i.e. whether it
|
||||
* contains both require and other declarations.
|
||||
* @param {ASTNode} declarations The list of VariableDeclarators.
|
||||
* @returns {boolean} True if the declarations are mixed, false if not.
|
||||
*/
|
||||
function isMixed(declarations) {
|
||||
const contains = {};
|
||||
|
||||
declarations.forEach(declaration => {
|
||||
const type = getDeclarationType(declaration.init);
|
||||
|
||||
contains[type] = true;
|
||||
});
|
||||
|
||||
return !!(
|
||||
contains[DECL_REQUIRE] &&
|
||||
(contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all require declarations in the given list are of the same
|
||||
* type.
|
||||
* @param {ASTNode} declarations The list of VariableDeclarators.
|
||||
* @returns {boolean} True if the declarations are grouped, false if not.
|
||||
*/
|
||||
function isGrouped(declarations) {
|
||||
const found = {};
|
||||
|
||||
declarations.forEach(declaration => {
|
||||
if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
|
||||
found[inferModuleType(declaration.init)] = true;
|
||||
}
|
||||
});
|
||||
|
||||
return Object.keys(found).length <= 1;
|
||||
}
|
||||
|
||||
return {
|
||||
VariableDeclaration(node) {
|
||||
if (isMixed(node.declarations)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "noMixRequire",
|
||||
});
|
||||
} else if (grouping && !isGrouped(node.declarations)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "noMixCoreModuleFileComputed",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import * as ts from 'typescript';
|
||||
import type { TSESTreeOptions } from '../parser-options';
|
||||
import type { MutableParseSettings } from './index';
|
||||
export declare function createParseSettings(code: string | ts.SourceFile, tsestreeOptions?: Partial<TSESTreeOptions>): MutableParseSettings;
|
||||
export declare function clearTSConfigMatchCache(): void;
|
||||
export declare function clearTSServerProjectService(): void;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"reg": {
|
||||
"name": "reg",
|
||||
"browser": "IE 9.0.0 (Windows 7 0.0.0)",
|
||||
"suite": "escape-long",
|
||||
"hz": 295607.88583768904,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.007232800727358036,
|
||||
"rhz": 0.4980642885243391,
|
||||
"sampleSize": 170
|
||||
},
|
||||
"fn if": {
|
||||
"name": "fn if",
|
||||
"browser": "IE 9.0.0 (Windows 7 0.0.0)",
|
||||
"suite": "escape-long",
|
||||
"hz": 89162.00387931858,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.014524314993346383,
|
||||
"rhz": 0.15022742001524522,
|
||||
"sampleSize": 168
|
||||
},
|
||||
"fn if reverse": {
|
||||
"name": "fn if reverse",
|
||||
"browser": "IE 9.0.0 (Windows 7 0.0.0)",
|
||||
"suite": "escape-long",
|
||||
"hz": 58497.49421155238,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.019957328292353076,
|
||||
"rhz": 0.09856135181363554,
|
||||
"sampleSize": 158
|
||||
},
|
||||
"escape31": {
|
||||
"name": "escape31",
|
||||
"browser": "IE 9.0.0 (Windows 7 0.0.0)",
|
||||
"suite": "escape-long",
|
||||
"hz": 94657.77431504549,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.018818194357686804,
|
||||
"rhz": 0.1594871425162423,
|
||||
"sampleSize": 169
|
||||
},
|
||||
"native": {
|
||||
"name": "native",
|
||||
"browser": "IE 9.0.0 (Windows 7 0.0.0)",
|
||||
"suite": "escape-long",
|
||||
"hz": 593513.513513514,
|
||||
"success": true,
|
||||
"fastest": true,
|
||||
"rme": 0.011966146496422055,
|
||||
"rhz": 1,
|
||||
"sampleSize": 159
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const readFileSync = fp => {
|
||||
return _fs.default.readFileSync(fp, 'utf8');
|
||||
};
|
||||
|
||||
const pathExists = fp => new Promise(resolve => {
|
||||
_fs.default.access(fp, err => {
|
||||
resolve(!err);
|
||||
});
|
||||
});
|
||||
|
||||
const pathExistsSync = _fs.default.existsSync;
|
||||
|
||||
class JoyCon {
|
||||
constructor({
|
||||
files,
|
||||
cwd = process.cwd(),
|
||||
stopDir,
|
||||
packageKey,
|
||||
parseJSON = JSON.parse
|
||||
} = {}) {
|
||||
this.options = {
|
||||
files,
|
||||
cwd,
|
||||
stopDir,
|
||||
packageKey,
|
||||
parseJSON
|
||||
};
|
||||
this.existsCache = new Map();
|
||||
this.loaders = new Set();
|
||||
this.packageJsonCache = new Map();
|
||||
this.loadCache = new Map();
|
||||
}
|
||||
|
||||
addLoader(loader) {
|
||||
this.loaders.add(loader);
|
||||
return this;
|
||||
}
|
||||
|
||||
removeLoader(name) {
|
||||
for (const loader of this.loaders) {
|
||||
if (name && loader.name === name) {
|
||||
this.loaders.delete(loader);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
async recusivelyResolve(options) {
|
||||
if (options.cwd === options.stopDir || _path.default.basename(options.cwd) === 'node_modules') {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const filename of options.files) {
|
||||
const file = _path.default.resolve(options.cwd, filename);
|
||||
|
||||
const exists = process.env.NODE_ENV !== 'test' && this.existsCache.has(file) ? this.existsCache.get(file) : await pathExists(file);
|
||||
this.existsCache.set(file, exists);
|
||||
|
||||
if (exists) {
|
||||
if (!options.packageKey || _path.default.basename(file) !== 'package.json') {
|
||||
return file;
|
||||
}
|
||||
|
||||
const data = require(file);
|
||||
|
||||
delete require.cache[file];
|
||||
const hasPackageKey = Object.prototype.hasOwnProperty.call(data, options.packageKey);
|
||||
|
||||
if (hasPackageKey) {
|
||||
this.packageJsonCache.set(file, data);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return this.recusivelyResolve(Object.assign({}, options, {
|
||||
cwd: _path.default.dirname(options.cwd)
|
||||
}));
|
||||
}
|
||||
|
||||
recusivelyResolveSync(options) {
|
||||
if (options.cwd === options.stopDir || _path.default.basename(options.cwd) === 'node_modules') {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const filename of options.files) {
|
||||
const file = _path.default.resolve(options.cwd, filename);
|
||||
|
||||
const exists = process.env.NODE_ENV !== 'test' && this.existsCache.has(file) ? this.existsCache.get(file) : pathExistsSync(file);
|
||||
this.existsCache.set(file, exists);
|
||||
|
||||
if (exists) {
|
||||
if (!options.packageKey || _path.default.basename(file) !== 'package.json') {
|
||||
return file;
|
||||
}
|
||||
|
||||
const data = require(file);
|
||||
|
||||
delete require.cache[file];
|
||||
const hasPackageKey = Object.prototype.hasOwnProperty.call(data, options.packageKey);
|
||||
|
||||
if (hasPackageKey) {
|
||||
this.packageJsonCache.set(file, data);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return this.recusivelyResolveSync(Object.assign({}, options, {
|
||||
cwd: _path.default.dirname(options.cwd)
|
||||
}));
|
||||
}
|
||||
|
||||
async resolve(...args) {
|
||||
const options = this.normalizeOptions(args);
|
||||
return this.recusivelyResolve(options);
|
||||
}
|
||||
|
||||
resolveSync(...args) {
|
||||
const options = this.normalizeOptions(args);
|
||||
return this.recusivelyResolveSync(options);
|
||||
}
|
||||
|
||||
runLoaderSync(loader, filepath) {
|
||||
return loader.loadSync(filepath);
|
||||
}
|
||||
|
||||
runLoader(loader, filepath) {
|
||||
if (!loader.load) return loader.loadSync(filepath);
|
||||
return loader.load(filepath);
|
||||
}
|
||||
|
||||
async load(...args) {
|
||||
const options = this.normalizeOptions(args);
|
||||
const filepath = await this.recusivelyResolve(options);
|
||||
|
||||
if (filepath) {
|
||||
const defaultLoader = {
|
||||
test: /\.+/,
|
||||
loadSync: filepath => {
|
||||
const extname = _path.default.extname(filepath).slice(1);
|
||||
|
||||
if (extname === 'js' || extname === 'cjs') {
|
||||
delete require.cache[filepath];
|
||||
return require(filepath);
|
||||
}
|
||||
|
||||
if (this.packageJsonCache.has(filepath)) {
|
||||
return this.packageJsonCache.get(filepath)[options.packageKey];
|
||||
}
|
||||
|
||||
const data = this.options.parseJSON(readFileSync(filepath));
|
||||
return data;
|
||||
}
|
||||
};
|
||||
const loader = this.findLoader(filepath) || defaultLoader;
|
||||
let data;
|
||||
|
||||
if (this.loadCache.has(filepath)) {
|
||||
data = this.loadCache.get(filepath);
|
||||
} else {
|
||||
data = await this.runLoader(loader, filepath);
|
||||
this.loadCache.set(filepath, data);
|
||||
}
|
||||
|
||||
return {
|
||||
path: filepath,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
loadSync(...args) {
|
||||
const options = this.normalizeOptions(args);
|
||||
const filepath = this.recusivelyResolveSync(options);
|
||||
|
||||
if (filepath) {
|
||||
const defaultLoader = {
|
||||
test: /\.+/,
|
||||
loadSync: filepath => {
|
||||
const extname = _path.default.extname(filepath).slice(1);
|
||||
|
||||
if (extname === 'js' || extname === 'cjs') {
|
||||
delete require.cache[filepath];
|
||||
return require(filepath);
|
||||
}
|
||||
|
||||
if (this.packageJsonCache.has(filepath)) {
|
||||
return this.packageJsonCache.get(filepath)[options.packageKey];
|
||||
}
|
||||
|
||||
const data = this.options.parseJSON(readFileSync(filepath));
|
||||
return data;
|
||||
}
|
||||
};
|
||||
const loader = this.findLoader(filepath) || defaultLoader;
|
||||
let data;
|
||||
|
||||
if (this.loadCache.has(filepath)) {
|
||||
data = this.loadCache.get(filepath);
|
||||
} else {
|
||||
data = this.runLoaderSync(loader, filepath);
|
||||
this.loadCache.set(filepath, data);
|
||||
}
|
||||
|
||||
return {
|
||||
path: filepath,
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
findLoader(filepath) {
|
||||
for (const loader of this.loaders) {
|
||||
if (loader.test && loader.test.test(filepath)) {
|
||||
return loader;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
this.existsCache.clear();
|
||||
this.packageJsonCache.clear();
|
||||
this.loadCache.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
normalizeOptions(args) {
|
||||
const options = Object.assign({}, this.options);
|
||||
|
||||
if (Object.prototype.toString.call(args[0]) === '[object Object]') {
|
||||
Object.assign(options, args[0]);
|
||||
} else {
|
||||
if (args[0]) {
|
||||
options.files = args[0];
|
||||
}
|
||||
|
||||
if (args[1]) {
|
||||
options.cwd = args[1];
|
||||
}
|
||||
|
||||
if (args[2]) {
|
||||
options.stopDir = args[2];
|
||||
}
|
||||
}
|
||||
|
||||
options.cwd = _path.default.resolve(options.cwd);
|
||||
options.stopDir = options.stopDir ? _path.default.resolve(options.stopDir) : _path.default.parse(options.cwd).root;
|
||||
|
||||
if (!options.files || options.files.length === 0) {
|
||||
throw new Error('[joycon] files must be an non-empty array!');
|
||||
}
|
||||
|
||||
options.__normalized__ = true;
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = JoyCon;
|
||||
module.exports = JoyCon;
|
||||
module.exports.default = JoyCon;
|
||||
@@ -0,0 +1,12 @@
|
||||
export default KEYS;
|
||||
export type VisitorKeys = {
|
||||
readonly [type: string]: ReadonlyArray<string>;
|
||||
};
|
||||
/**
|
||||
* @typedef {{ readonly [type: string]: ReadonlyArray<string> }} VisitorKeys
|
||||
*/
|
||||
/**
|
||||
* @type {VisitorKeys}
|
||||
*/
|
||||
declare const KEYS: VisitorKeys;
|
||||
//# sourceMappingURL=visitor-keys.d.ts.map
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"for + if": {
|
||||
"name": "for + if",
|
||||
"browser": "Chrome 60.0.3112 (Windows 7 0.0.0)",
|
||||
"suite": "itar-long",
|
||||
"hz": 36411.53526294366,
|
||||
"success": true,
|
||||
"fastest": true,
|
||||
"rme": 0.007522440507810787,
|
||||
"rhz": 1,
|
||||
"sampleSize": 211
|
||||
},
|
||||
"while + if": {
|
||||
"name": "while + if",
|
||||
"browser": "Chrome 60.0.3112 (Windows 7 0.0.0)",
|
||||
"suite": "itar-long",
|
||||
"hz": 36119.51959062462,
|
||||
"success": true,
|
||||
"fastest": true,
|
||||
"rme": 0.009843502140930696,
|
||||
"rhz": 0.9919801329383596,
|
||||
"sampleSize": 211
|
||||
},
|
||||
"array join": {
|
||||
"name": "array join",
|
||||
"browser": "Chrome 60.0.3112 (Windows 7 0.0.0)",
|
||||
"suite": "itar-long",
|
||||
"hz": 32849.563515559996,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.0115358668742216,
|
||||
"rhz": 0.902174634448641,
|
||||
"sampleSize": 213
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
"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: 'related-getter-setter-pairs',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce that `get()` types should be assignable to their equivalent `set()` type',
|
||||
recommended: 'strict',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
mismatch: '`get()` type should be assignable to its equivalent `set()` type.',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const methodPairsStack = [];
|
||||
function addPropertyNode(member, inner, kind) {
|
||||
const methodPairs = methodPairsStack[methodPairsStack.length - 1];
|
||||
const { name } = (0, util_1.getNameFromMember)(member, context.sourceCode);
|
||||
methodPairs.set(name, {
|
||||
...methodPairs.get(name),
|
||||
[kind]: inner,
|
||||
});
|
||||
}
|
||||
return {
|
||||
':matches(ClassBody, TSInterfaceBody, TSTypeLiteral):exit'() {
|
||||
const methodPairs = methodPairsStack[methodPairsStack.length - 1];
|
||||
for (const pair of methodPairs.values()) {
|
||||
if (!pair.get || !pair.set) {
|
||||
continue;
|
||||
}
|
||||
const getter = pair.get;
|
||||
const getType = services.getTypeAtLocation(getter);
|
||||
const setType = services.getTypeAtLocation(pair.set.params[0]);
|
||||
if (!checker.isTypeAssignableTo(getType, setType)) {
|
||||
context.report({
|
||||
node: getter.returnType.typeAnnotation,
|
||||
messageId: 'mismatch',
|
||||
});
|
||||
}
|
||||
}
|
||||
methodPairsStack.pop();
|
||||
},
|
||||
':matches(MethodDefinition, TSMethodSignature)[kind=get]'(node) {
|
||||
const getter = getMethodFromNode(node);
|
||||
if (getter.returnType) {
|
||||
addPropertyNode(node, getter, 'get');
|
||||
}
|
||||
},
|
||||
':matches(MethodDefinition, TSMethodSignature)[kind=set]'(node) {
|
||||
const setter = getMethodFromNode(node);
|
||||
if (setter.params.length === 1) {
|
||||
addPropertyNode(node, setter, 'set');
|
||||
}
|
||||
},
|
||||
'ClassBody, TSInterfaceBody, TSTypeLiteral'() {
|
||||
methodPairsStack.push(new Map());
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
function getMethodFromNode(node) {
|
||||
return node.type === utils_1.AST_NODE_TYPES.TSMethodSignature ? node : node.value;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
const createWebSocketStream = require('./lib/stream');
|
||||
const extension = require('./lib/extension');
|
||||
const PerMessageDeflate = require('./lib/permessage-deflate');
|
||||
const Receiver = require('./lib/receiver');
|
||||
const Sender = require('./lib/sender');
|
||||
const subprotocol = require('./lib/subprotocol');
|
||||
const WebSocket = require('./lib/websocket');
|
||||
const WebSocketServer = require('./lib/websocket-server');
|
||||
|
||||
WebSocket.createWebSocketStream = createWebSocketStream;
|
||||
WebSocket.extension = extension;
|
||||
WebSocket.PerMessageDeflate = PerMessageDeflate;
|
||||
WebSocket.Receiver = Receiver;
|
||||
WebSocket.Sender = Sender;
|
||||
WebSocket.Server = WebSocketServer;
|
||||
WebSocket.subprotocol = subprotocol;
|
||||
WebSocket.WebSocket = WebSocket;
|
||||
WebSocket.WebSocketServer = WebSocketServer;
|
||||
|
||||
module.exports = WebSocket;
|
||||
@@ -0,0 +1,161 @@
|
||||
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^WebSocket$" }] */
|
||||
'use strict';
|
||||
|
||||
const WebSocket = require('./websocket');
|
||||
const { Duplex } = require('stream');
|
||||
|
||||
/**
|
||||
* Emits the `'close'` event on a stream.
|
||||
*
|
||||
* @param {Duplex} stream The stream.
|
||||
* @private
|
||||
*/
|
||||
function emitClose(stream) {
|
||||
stream.emit('close');
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener of the `'end'` event.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function duplexOnEnd() {
|
||||
if (!this.destroyed && this._writableState.finished) {
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener of the `'error'` event.
|
||||
*
|
||||
* @param {Error} err The error
|
||||
* @private
|
||||
*/
|
||||
function duplexOnError(err) {
|
||||
this.removeListener('error', duplexOnError);
|
||||
this.destroy();
|
||||
if (this.listenerCount('error') === 0) {
|
||||
// Do not suppress the throwing behavior.
|
||||
this.emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a `WebSocket` in a duplex stream.
|
||||
*
|
||||
* @param {WebSocket} ws The `WebSocket` to wrap
|
||||
* @param {Object} [options] The options for the `Duplex` constructor
|
||||
* @return {Duplex} The duplex stream
|
||||
* @public
|
||||
*/
|
||||
function createWebSocketStream(ws, options) {
|
||||
let terminateOnDestroy = true;
|
||||
|
||||
const duplex = new Duplex({
|
||||
...options,
|
||||
autoDestroy: false,
|
||||
emitClose: false,
|
||||
objectMode: false,
|
||||
writableObjectMode: false
|
||||
});
|
||||
|
||||
ws.on('message', function message(msg, isBinary) {
|
||||
const data =
|
||||
!isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
|
||||
|
||||
if (!duplex.push(data)) ws.pause();
|
||||
});
|
||||
|
||||
ws.once('error', function error(err) {
|
||||
if (duplex.destroyed) return;
|
||||
|
||||
// Prevent `ws.terminate()` from being called by `duplex._destroy()`.
|
||||
//
|
||||
// - If the `'error'` event is emitted before the `'open'` event, then
|
||||
// `ws.terminate()` is a noop as no socket is assigned.
|
||||
// - Otherwise, the error is re-emitted by the listener of the `'error'`
|
||||
// event of the `Receiver` object. The listener already closes the
|
||||
// connection by calling `ws.close()`. This allows a close frame to be
|
||||
// sent to the other peer. If `ws.terminate()` is called right after this,
|
||||
// then the close frame might not be sent.
|
||||
terminateOnDestroy = false;
|
||||
duplex.destroy(err);
|
||||
});
|
||||
|
||||
ws.once('close', function close() {
|
||||
if (duplex.destroyed) return;
|
||||
|
||||
duplex.push(null);
|
||||
});
|
||||
|
||||
duplex._destroy = function (err, callback) {
|
||||
if (ws.readyState === ws.CLOSED) {
|
||||
callback(err);
|
||||
process.nextTick(emitClose, duplex);
|
||||
return;
|
||||
}
|
||||
|
||||
let called = false;
|
||||
|
||||
ws.once('error', function error(err) {
|
||||
called = true;
|
||||
callback(err);
|
||||
});
|
||||
|
||||
ws.once('close', function close() {
|
||||
if (!called) callback(err);
|
||||
process.nextTick(emitClose, duplex);
|
||||
});
|
||||
|
||||
if (terminateOnDestroy) ws.terminate();
|
||||
};
|
||||
|
||||
duplex._final = function (callback) {
|
||||
if (ws.readyState === ws.CONNECTING) {
|
||||
ws.once('open', function open() {
|
||||
duplex._final(callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// If the value of the `_socket` property is `null` it means that `ws` is a
|
||||
// client websocket and the handshake failed. In fact, when this happens, a
|
||||
// socket is never assigned to the websocket. Wait for the `'error'` event
|
||||
// that will be emitted by the websocket.
|
||||
if (ws._socket === null) return;
|
||||
|
||||
if (ws._socket._writableState.finished) {
|
||||
callback();
|
||||
if (duplex._readableState.endEmitted) duplex.destroy();
|
||||
} else {
|
||||
ws._socket.once('finish', function finish() {
|
||||
// `duplex` is not destroyed here because the `'end'` event will be
|
||||
// emitted on `duplex` after this `'finish'` event. The EOF signaling
|
||||
// `null` chunk is, in fact, pushed when the websocket emits `'close'`.
|
||||
callback();
|
||||
});
|
||||
ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
duplex._read = function () {
|
||||
if (ws.isPaused) ws.resume();
|
||||
};
|
||||
|
||||
duplex._write = function (chunk, encoding, callback) {
|
||||
if (ws.readyState === ws.CONNECTING) {
|
||||
ws.once('open', function open() {
|
||||
duplex._write(chunk, encoding, callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
ws.send(chunk, callback);
|
||||
};
|
||||
|
||||
duplex.on('end', duplexOnEnd);
|
||||
duplex.on('error', duplexOnError);
|
||||
return duplex;
|
||||
}
|
||||
|
||||
module.exports = createWebSocketStream;
|
||||
@@ -0,0 +1,5 @@
|
||||
const file5 = require("./file5.js")
|
||||
|
||||
module.exports = function () {
|
||||
file5()
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
interface PromiseWithResolvers<T> {
|
||||
promise: Promise<T>;
|
||||
resolve: (value: T | PromiseLike<T>) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* Creates a new Promise and returns it in an object, along with its resolve and reject functions.
|
||||
* @returns An object with the properties `promise`, `resolve`, and `reject`.
|
||||
*
|
||||
* ```ts
|
||||
* const { promise, resolve, reject } = Promise.withResolvers<T>();
|
||||
* ```
|
||||
*/
|
||||
withResolvers<T>(): PromiseWithResolvers<T>;
|
||||
}
|
||||
Reference in New Issue
Block a user