From 228357546dd45b5d9edbf6b976cb6cba407f7cac Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Sat, 10 Feb 2024 00:00:16 +0100 Subject: [PATCH] Add support for parsing TypeScript files (#49) * Add methods to handle and find controllers with different fileendings * Use `@typescript-eslint/parser` for parsing * Detect .ts files in project * Rename `ts-rails` to `typescript` controller * Resolve types warnings * Rename `filename` argument * Switch to `@typescript-eslint/typescript-estree` for parsing * Add @typescript-eslint/types * Change TypeScript `module` from `commonjs` to `es2020` and let Vite bundle up the commonjs file * Change TypeScript `module` and `moduleResolution` to `node16` * Drop Vite * Drop direct `@typescript-eslint/types` dependency --------- Co-authored-by: Fran Zekan Co-authored-by: Carlos Garcia --- package.json | 2 +- src/parser.ts | 22 +- src/project.ts | 4 +- test/parser.test.ts | 568 ++++++++++++++++++++++++++++++++------------ tsconfig.json | 6 +- yarn.lock | 218 ++++++++++++++++- 6 files changed, 652 insertions(+), 168 deletions(-) diff --git a/package.json b/package.json index ebc908c..c7bfe28 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@hotwired/stimulus-webpack-helpers": "^1.0.1", - "acorn": "^8.11.2", + "@typescript-eslint/typescript-estree": "^6.21.0", "acorn-walk": "^8.3.1", "fs": "^0.0.1-security", "glob": "^10.3.10" diff --git a/src/parser.ts b/src/parser.ts index 817f523..6ee1a9c 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,11 +1,10 @@ import { simple } from "acorn-walk" -import { Parser as AcornParser } from "acorn" +import * as ESLintParser from "@typescript-eslint/typescript-estree" + import { Project } from "./project" import { ControllerDefinition, defaultValuesForType } from "./controller_definition" import { NodeElement, PropertyValue } from "./types" -import type { Program } from "acorn" - type NestedArray = T | NestedArray[] type NestedObject = { [k: string]: T | NestedObject @@ -13,29 +12,34 @@ type NestedObject = { export class Parser { private readonly project: Project - private parser: typeof AcornParser + private parser: typeof ESLintParser constructor(project: Project) { this.project = project - this.parser = AcornParser + this.parser = ESLintParser } - parse(code: string): Program { + parse(code: string, filename?: string) { return this.parser.parse(code, { sourceType: "module", ecmaVersion: "latest", + filePath: filename }) } parseController(code: string, filename: string) { try { - const ast = this.parse(code) + const ast = this.parse(code, filename) const controller = new ControllerDefinition(this.project, filename) - simple(ast, { + simple(ast as any, { MethodDefinition(node: any): void { if (node.kind === "method") { - controller.methods.push(node.key.name) + const methodName = node.key.name + const isPrivate = node.accessibility === "private" || node.key.type === "PrivateIdentifier" + const name = isPrivate ? `#${methodName}` : methodName + + controller.methods.push(name) } }, diff --git a/src/project.ts b/src/project.ts index 822a5eb..48e3de4 100644 --- a/src/project.ts +++ b/src/project.ts @@ -76,7 +76,7 @@ export class Project { } get controllerRoot() { - return this.controllerRoots[0] || this.controllerRootFallback + return this.controllerRoots[0] || this.controllerRootFallback } get controllerRoots() { @@ -102,7 +102,7 @@ export class Project { const relativePath = this.relativePath(path) const relativeRoots = this.controllerRoots.map(root => this.relativePath(root)) - return relativeRoots.find(root => relativePath.startsWith(root)) || this.controllerRootFallback + return relativeRoots.find(root => relativePath.startsWith(root)) || this.controllerRootFallback } private async readControllerFiles() { diff --git a/test/parser.test.ts b/test/parser.test.ts index ff7769d..4cd84de 100644 --- a/test/parser.test.ts +++ b/test/parser.test.ts @@ -1,200 +1,466 @@ -import { expect, test, vi } from "vitest" +import { expect, test, vi, describe } from "vitest" import { Project, Parser } from "../src" const project = new Project(process.cwd()) const parser = new Parser(project) -test("parse targets", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" +describe("with JS Syntax", () => { + test("parse targets", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - static targets = ["one", "two", "three"] - } - ` - const controller = parser.parseController(code, "target_controller.js") + export default class extends Controller { + static targets = ["one", "two", "three"] + } + ` + const controller = parser.parseController(code, "target_controller.js") - expect(controller.targets).toEqual(["one", "two", "three"]) -}) + expect(controller.targets).toEqual(["one", "two", "three"]) + }) -test("parse classes", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + test("parse classes", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - static classes = ["one", "two", "three"] - } - ` - const controller = parser.parseController(code, "class_controller.js") + export default class extends Controller { + static classes = ["one", "two", "three"] + } + ` + const controller = parser.parseController(code, "class_controller.js") - expect(controller.classes).toEqual(["one", "two", "three"]) -}) + expect(controller.classes).toEqual(["one", "two", "three"]) + }) -test("parse values", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" - - export default class extends Controller { - static values = { - string: String, - object: Object, - boolean: Boolean, - array: Array, - number: Number - } - } - ` - const controller = parser.parseController(code, "value_controller.js") - - expect(controller.values).toEqual({ - string: { type: "String", default: "" }, - object: { type: "Object", default: {} }, - boolean: { type: "Boolean", default: false }, - array: { type: "Array", default: [] }, - number: { type: "Number", default: 0 }, + test("parse values", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static values = { + string: String, + object: Object, + boolean: Boolean, + array: Array, + number: Number + } + } + ` + const controller = parser.parseController(code, "value_controller.js") + + expect(controller.values).toEqual({ + string: { type: "String", default: "" }, + object: { type: "Object", default: {} }, + boolean: { type: "Boolean", default: false }, + array: { type: "Array", default: [] }, + number: { type: "Number", default: 0 }, + }) }) -}) -test("parse values with with default values", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" - - export default class extends Controller { - static values = { - string: { type: String, default: "string" }, - object: { type: Object, default: { object: "Object" } }, - boolean: { type: Boolean, default: true }, - array: { type: Array, default: ["Array"] }, - number: { type: Number, default: 1 } - } - } - ` - const controller = parser.parseController(code, "value_controller.js") - - expect(controller.values).toEqual({ - string: { type: "String", default: "string" }, - object: { type: "Object", default: { object: "Object" } }, - boolean: { type: "Boolean", default: true }, - array: { type: "Array", default: ["Array"] }, - number: { type: "Number", default: 1 }, + test("parse values with with default values", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static values = { + string: { type: String, default: "string" }, + object: { type: Object, default: { object: "Object" } }, + boolean: { type: Boolean, default: true }, + array: { type: Array, default: ["Array"] }, + number: { type: Number, default: 1 } + } + } + ` + const controller = parser.parseController(code, "value_controller.js") + + expect(controller.values).toEqual({ + string: { type: "String", default: "string" }, + object: { type: "Object", default: { object: "Object" } }, + boolean: { type: "Boolean", default: true }, + array: { type: "Array", default: ["Array"] }, + number: { type: "Number", default: 1 }, + }) }) -}) -test("should handle syntax errors", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + test("should handle syntax errors", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - ` - const spy = vi.spyOn(console, 'error') + export default class extends Controller { + ` + const spy = vi.spyOn(console, 'error') - const controller = parser.parseController(code, "error_controller.js") + const controller = parser.parseController(code, "error_controller.js") - expect(controller.identifier).toEqual("error") - expect(controller.parseError).toEqual("Unexpected token (5:2)") + expect(controller.identifier).toEqual("error") + expect(controller.parseError).toEqual("'}' expected.") - expect(spy).toBeCalledWith("Error while parsing controller in 'error_controller.js': Unexpected token (5:2)") -}) + expect(spy).toBeCalledWith("Error while parsing controller in 'error_controller.js': '}' expected.") + }) + + test("parse arrow function", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" -test("parse arrow function", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + export default class extends Controller { + connect() { + document.addEventListener('event', this.load) + } - export default class extends Controller { - connect() { - document.addEventListener('event', this.load) + load = (event) => { + anotherArrowFunction = (something) => { + + } + } } + ` - load = (event) => {} - } - ` + const controller = parser.parseController(code, "controller.js") - const controller = parser.parseController(code, "controller.js") + expect(controller.methods).toEqual(["connect", "load"]) + expect(controller.parseError).toBeUndefined() + }) - expect(controller.methods).toEqual(["connect", "load"]) - expect(controller.parseError).toBeUndefined() -}) + test("parse methods", () => { + const code = ` + export default class extends Controller { + load() {} + unload() {} + } + ` + const controller = parser.parseController(code, "controller.js") -test("parse private methods", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + expect(controller.methods).toEqual(["load", "unload"]) + expect(controller.parseError).toBeUndefined() + }) - export default class extends Controller { - #load() {} - } - ` - const controller = parser.parseController(code, "controller.js") + test("parse private methods", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - expect(controller.methods).toEqual(["load"]) - expect(controller.parseError).toBeUndefined() -}) + export default class extends Controller { + #load() {} + } + ` + const controller = parser.parseController(code, "controller.js") + + expect(controller.methods).toEqual(["#load"]) + expect(controller.parseError).toBeUndefined() + }) -test("parse nested object/array default value types", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + test("parse nested object/array default value types", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - static values = { - object: { type: Object, default: { object: { some: { more: { levels: {} } } } } }, - array: { type: Array, default: [["Array", "with", ["nested", ["values"]]]] }, + export default class extends Controller { + static values = { + object: { type: Object, default: { object: { some: { more: { levels: {} } } } } }, + array: { type: Array, default: [["Array", "with", ["nested", ["values"]]]] }, + } } - } - ` - const controller = parser.parseController(code, "value_controller.js") + ` + const controller = parser.parseController(code, "value_controller.js") - expect(controller.values).toEqual({ - object: { type: "Object", default: { object: { some: { more: { levels: {} } } } } }, - array: { type: "Array", default: [["Array", "with", ["nested", ["values"]]]] }, + expect(controller.values).toEqual({ + object: { type: "Object", default: { object: { some: { more: { levels: {} } } } } }, + array: { type: "Array", default: [["Array", "with", ["nested", ["values"]]]] }, + }) }) -}) -test("parse controller with public class fields", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + test("parse controller with public class fields", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - instanceField - instanceFieldWithInitializer = "instance field" - static staticField - static staticFieldWithInitializer = "static field" - } - ` + export default class extends Controller { + instanceField + instanceFieldWithInitializer = "instance field" + static staticField + static staticFieldWithInitializer = "static field" + } + ` - const controller = parser.parseController(code, "controller.js") + const controller = parser.parseController(code, "controller.js") - expect(controller.parseError).toBeUndefined() -}) + expect(controller.parseError).toBeUndefined() + }) + + test("parse controller with private getter", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + get #privateGetter () { + return true + } + } + ` + + const controller = parser.parseController(code, "controller.js") + + expect(controller.parseError).toBeUndefined() + expect(controller.methods).toEqual([]) + }) + + test("parse controller with private setter", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + set #privateSetter (value) { + // set + } + } + ` + + const controller = parser.parseController(code, "controller.js") + + expect(controller.parseError).toBeUndefined() + expect(controller.methods).toEqual([]) + }) -test("parse controller with private getter", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" + test("parse controller with variable declaration in method body", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" - export default class extends Controller { - get #privateGetter () { - return true + export default class extends Controller { + method(value) { + const variable = 0 + } } - } - ` + ` - const controller = parser.parseController(code, "controller.js") + const controller = parser.parseController(code, "controller.js") - expect(controller.parseError).toBeUndefined() - expect(controller.methods).toEqual([]) + expect(controller.parseError).toBeUndefined() + expect(controller.methods).toEqual(["method"]) + }) }) -test("parse controller with private setter", () => { - const code = ` - import { Controller } from "@hotwired/stimulus" +describe("with TS Syntax", () => { + test("parse targets", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static targets = ["one", "two", "three"] + + declare readonly oneTarget: HTMLElement + declare readonly twoTarget: HTMLElement + declare readonly threeTarget: HTMLElement + } + ` + const controller = parser.parseController(code, "target_controller.ts") + + expect(controller.targets).toEqual(["one", "two", "three"]) + }) + + test("parse classes", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static classes = ["one", "two", "three"] + } + ` + const controller = parser.parseController(code, "class_controller.ts") + + expect(controller.classes).toEqual(["one", "two", "three"]) + }) + + test("parse values", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static values = { + string: String, + object: Object, + boolean: Boolean, + array: Array, + number: Number + } + + declare stringValue: string + declare objectValue: object + declare booleanValue: boolean + declare arrayValue: any[] + declare numberValue: number + } + ` + const controller = parser.parseController(code, "value_controller.ts") + + expect(controller.values).toEqual({ + string: { type: "String", default: "" }, + object: { type: "Object", default: {} }, + boolean: { type: "Boolean", default: false }, + array: { type: "Array", default: [] }, + number: { type: "Number", default: 0 }, + }) + }) - export default class extends Controller { - set #privateSetter (value) { - // set + test("parse values with with default values", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static values = { + string: { type: String, default: "string" }, + object: { type: Object, default: { object: "Object" } }, + boolean: { type: Boolean, default: true }, + array: { type: Array, default: ["Array"] }, + number: { type: Number, default: 1 } + } + + declare stringValue: string + declare objectValue: object + declare booleanValue: boolean + declare arrayValue: any[] + declare numberValue: number } - } - ` + ` + const controller = parser.parseController(code, "value_controller.ts") + + expect(controller.values).toEqual({ + string: { type: "String", default: "string" }, + object: { type: "Object", default: { object: "Object" } }, + boolean: { type: "Boolean", default: true }, + array: { type: "Array", default: ["Array"] }, + number: { type: "Number", default: 1 }, + }) + }) + + test("should handle syntax errors", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + ` + + const spy = vi.spyOn(console, 'error') + const controller = parser.parseController(code, "error_controller.ts") - const controller = parser.parseController(code, "controller.js") + expect(controller.identifier).toEqual("error") + expect(controller.parseError).toEqual("'}' expected.") + + expect(spy).toBeCalledWith("Error while parsing controller in 'error_controller.ts': '}' expected.") + }) + + test("parse arrow function", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + connect(): void { + document.addEventListener('event', this.load) + } + + load = (event: Event):void => {} + } + ` + + const controller = parser.parseController(code, "controller.ts") + + expect(controller.methods).toEqual(["connect", "load"]) + expect(controller.parseError).toBeUndefined() + }) + + test("parse methods", () => { + const code = ` + export default class extends Controller { + load(): void {} + + unload(): void {} + + isSomething(): Boolean {} + } + ` + const controller = parser.parseController(code, "controller.ts") + + expect(controller.methods).toEqual(["load", "unload", "isSomething"]) + expect(controller.parseError).toBeUndefined() + }) + + test("parse private methods", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + #load() {} + private unload() {} + } + ` + const controller = parser.parseController(code, "controller.ts") - expect(controller.parseError).toBeUndefined() - expect(controller.methods).toEqual([]) + expect(controller.methods).toEqual(["#load", "#unload"]) + expect(controller.parseError).toBeUndefined() + }) + + test("parse nested object/array default value types", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + static values = { + object: { type: Object, default: { object: { some: { more: { levels: {} } } } } }, + array: { type: Array, default: [["Array", "with", ["nested", ["values"]]]] }, + } + } + ` + const controller = parser.parseController(code, "value_controller.js") + + expect(controller.values).toEqual({ + object: { type: "Object", default: { object: { some: { more: { levels: {} } } } } }, + array: { type: "Array", default: [["Array", "with", ["nested", ["values"]]]] }, + }) + }) + + test("parse controller with public class fields", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + instanceField: any; + instanceFieldWithInitializer: string = "instance field"; + static staticField: any; + static staticFieldWithInitializer: string = "static field"; + } + ` + + const controller = parser.parseController(code, "controller.ts") + + expect(controller.parseError).toBeUndefined() + }) + + test("parse controller with private getter", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + private get privateGetter () { + return true + } + } + ` + + const controller = parser.parseController(code, "controller.ts") + + expect(controller.parseError).toBeUndefined() + expect(controller.methods).toEqual([]) + }) + + test("parse controller with private setter", () => { + const code = ` + import { Controller } from "@hotwired/stimulus" + + export default class extends Controller { + private set privateSetter (value) { + // set + } + } + ` + + const controller = parser.parseController(code, "controller.ts") + + expect(controller.parseError).toBeUndefined() + expect(controller.methods).toEqual([]) + }) }) diff --git a/tsconfig.json b/tsconfig.json index aad76d6..6b48705 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "es2019", + "target": "es2020", "lib": ["es2021", "dom"], - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "esModuleInterop": true, "sourceMap": true, "strict": true, diff --git a/yarn.lock b/yarn.lock index 4c574d2..26d4842 100644 --- a/yarn.lock +++ b/yarn.lock @@ -166,6 +166,27 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -273,6 +294,33 @@ dependencies: undici-types "~5.26.4" +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== + +"@typescript-eslint/typescript-estree@^6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" + "@vitest/expect@1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.2.2.tgz#39ea22e849bbf404b7e5272786551aa99e2663d0" @@ -322,7 +370,7 @@ acorn-walk@^8.1.1, acorn-walk@^8.3.1, acorn-walk@^8.3.2: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn@^8.10.0, acorn@^8.11.2, acorn@^8.4.1: +acorn@^8.10.0, acorn@^8.4.1: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -359,6 +407,11 @@ arg@^4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -376,6 +429,13 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + cac@^6.7.14: version "6.7.14" resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" @@ -451,6 +511,13 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -494,6 +561,11 @@ esbuild@^0.19.3: "@esbuild/win32-ia32" "0.19.9" "@esbuild/win32-x64" "0.19.9" +eslint-visitor-keys@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" @@ -516,6 +588,31 @@ execa@^8.0.1: signal-exit "^4.1.0" strip-final-newline "^3.0.0" +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" @@ -544,6 +641,13 @@ get-stream@^8.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^10.3.10, glob@^10.3.7: version "10.3.10" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" @@ -555,21 +659,55 @@ glob@^10.3.10, glob@^10.3.7: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-scurry "^1.10.1" +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + human-signals@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" @@ -616,6 +754,13 @@ loupe@^2.3.7: dependencies: get-func-name "^2.0.1" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + "lru-cache@^9.1.1 || ^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" @@ -638,12 +783,25 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mimic-fn@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -minimatch@^9.0.1, minimatch@^9.0.3: +minimatch@9.0.3, minimatch@^9.0.1, minimatch@^9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== @@ -714,6 +872,11 @@ path-scurry@^1.10.1: lru-cache "^9.1.1 || ^10.0.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + path@^0.12.7: version "0.12.7" resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" @@ -737,6 +900,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pkg-types@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" @@ -769,11 +937,21 @@ process@^0.11.1: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@^5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" @@ -801,6 +979,20 @@ rollup@^4.2.0: "@rollup/rollup-win32-x64-msvc" "4.8.0" fsevents "~2.3.2" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +semver@^7.5.4: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -828,6 +1020,11 @@ signal-exit@^4.1.0: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -904,6 +1101,18 @@ tinyspy@^2.2.0: resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.2.0.tgz#9dc04b072746520b432f77ea2c2d17933de5d6ce" integrity sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg== +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-api-utils@^1.0.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.2.1.tgz#f716c7e027494629485b21c0df6180f4d08f5e8b" + integrity sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA== + ts-node@^10.9.2: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" @@ -1042,6 +1251,11 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"