diff --git a/language/javascript/extractor/.eslintignore b/language/javascript/extractor/.eslintignore new file mode 100644 index 00000000..587ee6bf --- /dev/null +++ b/language/javascript/extractor/.eslintignore @@ -0,0 +1,4 @@ +node_modules/ +test/ +dist/ +out/ diff --git a/language/javascript/extractor/.eslintrc.js b/language/javascript/extractor/.eslintrc.js new file mode 100644 index 00000000..493f70ee --- /dev/null +++ b/language/javascript/extractor/.eslintrc.js @@ -0,0 +1,10 @@ +// eslint-disable-next-line no-undef +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + rules: { + '@typescript-eslint/no-empty-interface': 'off', + }, +}; diff --git a/language/javascript/extractor/.gitignore b/language/javascript/extractor/.gitignore new file mode 100644 index 00000000..4b9303a6 --- /dev/null +++ b/language/javascript/extractor/.gitignore @@ -0,0 +1,14 @@ +.DS_Store + +.vscode/ +.idea/ + +node_modules/ +coverage/ +dist/ +out/ + +bazel-* + +*.db +*.db-journal \ No newline at end of file diff --git a/language/javascript/extractor/.prettierignore b/language/javascript/extractor/.prettierignore new file mode 100644 index 00000000..587ee6bf --- /dev/null +++ b/language/javascript/extractor/.prettierignore @@ -0,0 +1,4 @@ +node_modules/ +test/ +dist/ +out/ diff --git a/language/javascript/extractor/.prettierrc.json b/language/javascript/extractor/.prettierrc.json new file mode 100644 index 00000000..dc08f702 --- /dev/null +++ b/language/javascript/extractor/.prettierrc.json @@ -0,0 +1,15 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "endOfLine": "lf", + "bracketSameLine": false, + "jsxSingleQuote": false, + "printWidth": 80, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false +} diff --git a/language/javascript/extractor/README.md b/language/javascript/extractor/README.md new file mode 100644 index 00000000..4774dd43 --- /dev/null +++ b/language/javascript/extractor/README.md @@ -0,0 +1,9 @@ +# Introduction +coref-js-src-extractor is a data generation tool that extracts JavaScript / TypeScript source code into COREF format data. + +# Quick Start +1. Environment requirements Node>=18. +2. Install yarn. `npm install --global yarn` and then install dependencies with `yarn`. +3. Build && package. `npm run pkg`. A coref-javascript-src-extractor executable file will be generated in the current directory. +4. Run the extractor. `./coref-javascript-src-extractor extract -s {source_root}`. +5. For more help. `./coref-javascript-src-extractor -h` or `./coref-javascript-src-extractor extract -h`. \ No newline at end of file diff --git a/language/javascript/extractor/README_cn.md b/language/javascript/extractor/README_cn.md new file mode 100644 index 00000000..4636d7a6 --- /dev/null +++ b/language/javascript/extractor/README_cn.md @@ -0,0 +1,9 @@ +# 介绍 +coref-js-src-extractor 是一个数据生成工具,该工具将 JavaScript / TypeScript 源码抽取为COREF格式的数据。 + +# 快速开始 +1. 环境要求 Node>=18。 +2. 安装 yarn。 `npm install --global yarn` 并安装依赖 `yarn`。 +3. 构建 && 打包。 `npm run pkg`. 当前目录下会生成 `coref-javascript-src-extractor` 可执行文件。 +4. 运行抽取器。`./coref-javascript-src-extractor extract -s {source_root}`。 +5. 查看更多帮助。`./coref-javascript-src-extractor -h` 或 `./coref-javascript-src-extractor extract -h`。 diff --git a/language/javascript/extractor/coref-javascript-er.puml b/language/javascript/extractor/coref-javascript-er.puml new file mode 100644 index 00000000..58495c97 --- /dev/null +++ b/language/javascript/extractor/coref-javascript-er.puml @@ -0,0 +1,221 @@ +@startuml +' https://plantuml.com/ie-diagram + +' Location table +entity location { + oid: INTEGER <> + file_oid: INTEGER + start_line_number: INTEGER + start_column_number: INTEGER + end_line_number: INTEGER + end_column_number: INTEGER + text: TEXT +} + + +' Number of lines table +entity number_of_lines { + location_oid: INTEGER <> + lines: INTEGER + code_lines: INTEGER + comment_lines: INTEGER +} + + +entity file { + oid: INTEGER <> + name: TEXT + extension: TEXT + relative_path: TEXT + location_oid: INTEGER +} + +entity directory { + oid: INTEGER <> + name: TEXT + relative_path: TEXT + location_oid: INTEGER +} + +' parent_oid: ref directory +' child_oid: ref directory | file +entity directory_hierarchy { + parent_oid: INTEGER + child_oid: INTEGER <> +} + +' kind: +' enum { +' script = 0 +' inline_script = 1 +' event_handler = 2 +' javascript_url = 3 +' template_top_level = 4 +' } +entity top_level { + oid: INTEGER <> + kind: INTEGER + location_oid: INTEGER +} + +entity node { + oid: INTEGER <> + kind: INTEGER + parent_oid: INTEGER + index: INTEGER + location_oid: INTEGER +} + +entity literal { + oid: INTEGER <> + value: TEXT +} + +entity binding_element_property_name { + oid: INTEGER <> + property_name_oid: INTEGER +} + +entity binding_element_name { + oid: INTEGER <> + name_oid: INTEGER +} + +entity binding_element_initializer { + oid: INTEGER <> + initializer_oid: INTEGER +} + +' +' Class declaration or expression +' +entity class_like_declaration { + oid: INTEGER <> + kind: INTEGER + name: TEXT +} + +entity function_like_declaration { + oid: INTEGER <> + kind: INTEGER + name: TEXT +} + +entity function_enclosing_node { + node_oid: INTEGER <> + function_oid: INTEGER +} + +entity modifier { + oid: INTEGER <> + index: INTEGER +} + +' use `symbol_` instead of `symbol` to avoid the typescript error TS2457: Type alias name cannot be 'symbol'. +entity symbol_ { + oid: INTEGER <> + name: TEXT + description: TEXT +} + +entity node_symbol { + node_oid: INTEGER <> + symbol_oid: INTEGER +} + +entity shorthand_assignment_value_symbol { + node_oid: INTEGER <> + symbol_oid: INTEGER +} + +entity call_site { + invoke_expression_oid: INTEGER <> + callee_oid: INTEGER +} + +entity cfg_entry_node { + oid: INTEGER <> + ast_node_oid: INTEGER +} + +entity cfg_exit_node { + oid: INTEGER <> + ast_node_oid: INTEGER +} + + +' ---- +' Type +' ---- + +' ' Type table +' ' +' entity type { +' oid: INTEGER <> +' kind: INTEGER +' name: TEXT +' } + +' ' Type hierarchy table +' ' +' ' child_oid: ref type +' ' parent_oid: ref type +' ' index: the index of child type in the parent type +' entity type_hierarchy { +' oid: INTEGER <> +' parent_oid: INTEGER +' child_oid: INTEGER +' index: INTEGER +' } + +' ' Type alias table +' ' +' ' alias_type_oid: ref type +' ' underlying_type_oid: ref type +' entity type_alias { +' alias_type_oid: INTEGER <> +' underlying_type_oid: INTEGER +' } + +' Comment table +entity comment { + oid: INTEGER <> + kind: INTEGER + location_oid: INTEGER +} + +' Node comment table +entity node_comment { + oid: INTEGER <> + node_oid: INTEGER + comment_oid: INTEGER + type: INTEGER +} + +' entity token { +' oid: INTEGER <> +' kind: INTEGER +' location_oid: INTEGER +' } + +' JS parse error table +entity js_parse_error { + oid: INTEGER <> + message: TEXT + line: TEXT +} + +entity metadata { + oid: INTEGER <> + version: TEXT + created_time: DATETIME +} + +entity ignored_path { + oid: INTEGER <> + path_kind: INTEGER + path: TEXT + ignore_kind: INTEGER +} + +@enduml diff --git a/language/javascript/extractor/jest.config.ts b/language/javascript/extractor/jest.config.ts new file mode 100644 index 00000000..1f9e9502 --- /dev/null +++ b/language/javascript/extractor/jest.config.ts @@ -0,0 +1,195 @@ +/* + * For a detailed explanation regarding each configuration property and type check, visit: + * https://jestjs.io/docs/configuration + */ + +export default { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/private/var/folders/n_/rmrmp4lj1s726pp0jdggy4j00000gp/T/jest_dy", + + // Automatically clear mock calls, instances and results before every test + // clearMocks: false, + + // Indicates whether the coverage information should be collected while executing the test + // collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + // coverageDirectory: undefined, + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + // coverageProvider: "babel", + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // 由于多 worker 模式,序列化 bigint 存在 bug,因此将 maxWorkers 设置为1。参考: https://github.com/facebook/jest/issues/11617 + maxWorkers: 1, + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "jsx", + // "ts", + // "tsx", + // "json", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + preset: 'ts-jest', + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state before every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state and implementation before every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + // testEnvironment: "jest-environment-node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: [ + // "**/__tests__/**/*.[jt]s?(x)", + // "**/?(*.)+(spec|test).[tj]s?(x)" + // ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jest-circus/runner", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: "http://localhost", + + // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" + // timers: "real", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; diff --git a/language/javascript/extractor/jinja/DOClass.gdl.j2 b/language/javascript/extractor/jinja/DOClass.gdl.j2 new file mode 100644 index 00000000..cbac506e --- /dev/null +++ b/language/javascript/extractor/jinja/DOClass.gdl.j2 @@ -0,0 +1,23 @@ +/** + * @filename: DOCLASS + * @author: 张玉 + * @brief: DOCLASS provides classes and predicates for working with basic model of JavaScript / TypeScript code database. + */ + +package coref.javascript + +{% for table in table_list %} +class {{ table.name | to_camel }}DO { + {{ table.name | to_camel }}DO() { + {{ table.name }}({{ generate_doclass_predicate_params(table) | join(", ") }}) + } + {%- for column in table.column_list if not column.is_pk %} + + {{ column.gdl_type }} get{{ column.name | to_camel }}() { + return {{ column.name | to_lower_camel }}: exists({{ column.gdl_type }} {{ column.name | to_lower_camel }}) { + {{ table.name }}({{ generate_doclass_predicate_params(table, column) | join(', ') }}) + } + } + {%- endfor %} +} +{% endfor %} diff --git a/language/javascript/extractor/jinja/EDBConnection.gdl.j2 b/language/javascript/extractor/jinja/EDBConnection.gdl.j2 new file mode 100644 index 00000000..c155779a --- /dev/null +++ b/language/javascript/extractor/jinja/EDBConnection.gdl.j2 @@ -0,0 +1,60 @@ +/** + * @filename: EDBCONNECTION + * @author: 张玉 + * @brief: EDBCONNECTION provides predicates for working with JavaScript / TypeScript code database connections. + */ + +package coref.javascript + + +@builtin +predicate input(string dbname, string name) { + _ +} + +@builtin +string cat(string a, string b) { + _ +} + +@builtin +string contains(string a, string b) { + _ +} + +@builtin +string match(string a, string b) { + _ +} + +@builtin +string to_number(string a) { + _ +} + +@builtin +int strlen(string a) { + _ +} + +@builtin +string substr(string a, int i, int j) { + _ +} + +@builtin +string to_string(int s) { + _ +} + +{% for table in table_list %} +predicate {{ table.name }} ( + {{ table.column_list[0].gdl_type }} {{ table.column_list[0].name }} + {%- for column in table.column_list[1:] -%} + , + {{ column.gdl_type }} {{ column.name -}} + {%- endfor -%} +) { + input("coref_javascript_src.db", "{{ table.name }}") +} +{% endfor %} diff --git a/language/javascript/extractor/jinja/puml_to_schema_prisma.py b/language/javascript/extractor/jinja/puml_to_schema_prisma.py new file mode 100755 index 00000000..ff80cc88 --- /dev/null +++ b/language/javascript/extractor/jinja/puml_to_schema_prisma.py @@ -0,0 +1,212 @@ +#! python3 + +""" 根据 coref-javascript-er.puml 生成 schema.prisma 文件 + +Author: 张玉 + +""" + +import argparse +import os +import re +from xmlrpc.client import boolean +from dataclasses import dataclass +from pathlib import Path +from typing import List, Optional + +from jinja2 import Environment, FileSystemLoader +from jinja2_strcase.jinja2_strcase import to_lower_camel + +prisma_type_map = { + "INTEGER": "Int", + "TEXT": "String", + "DATETIME": "DateTime", +} + +PRISMA_OID_TYPE = "BigInt" +OID_SUFFIX = "oid" + +gdl_type_map = { + "INTEGER": "int", + "TEXT": "string", + "DATETIME": "string", +} + +script_dir_path = os.path.dirname(__file__) + +@dataclass +class Column: + name: str + type: str + prisma_type: str + gdl_type: str + is_pk: bool = False + + +@dataclass +class Table: + name: str + column_list: List[Column] + pk_index: int + + +def parse_args(): + """ 解析脚本的参数 + + Returns: + 解析后的 args 对象 + + """ + + parser = argparse.ArgumentParser(description='Convert Plantuml ER file to prisma.schema') + parser.add_argument("puml_er_file", type=argparse.FileType(encoding="utf-8", errors="replace")) + parser.add_argument( + "--prisma-schema", "--output", "-o", + dest="output_path", + default=script_dir_path + ) + + return parser.parse_args() + + +def parse_puml_er(puml_er_str: str) -> List[Table]: + """ 解析 puml ER 图的内容 + + Format: + entity location { + oid: INTEGER + file_oid: INTEGER + start_line_number: INTEGER + start_column_number: INTEGER + end_line_number: INTEGER + end_column_number: INTEGER + } + + Returns: + table_list: 解析后的 Table 列表 + + """ + + table_list: List[Table] = [] + + # 匹配每一个 ER 图中 entity 的内容 + entity_regex = r"(?<=\nentity ).+ \{[^\}]+\}" + matches = re.finditer(entity_regex, puml_er_str, re.MULTILINE) + for match in matches: + entity_str = match.group() + + # 匹配表名 + table_name_regex = r".+(?= \{)" + table_name_match = re.search( + pattern=table_name_regex, + string=entity_str + ) + if table_name_match is None: + continue + table_name = table_name_match.group() + + # 匹配全部列的内容 + column_content_regex = r"(?<=\{).+(?=\})" + column_content_match = re.search( + pattern=column_content_regex, + string=entity_str, + flags=re.MULTILINE | re.DOTALL + ) + if column_content_match is None: + continue + column_content = column_content_match.group().strip() + + # 获取每一个列名和类型 + column_desc_list = [x.strip() for x in column_content.splitlines()] + column_desc_list = [x for x in column_desc_list if x] + column_list: List[Column] = [] + pk_index = 0 + for column_desc in column_desc_list: + column_desc_list = [x.strip() for x in column_desc.split(" ")] + column_desc_list = [x for x in column_desc_list if x] + column_name = column_desc_list[0] + if column_name.endswith(":"): + column_name = column_name[:-1] + + column_type = column_desc_list[1] + column_prisma_type = PRISMA_OID_TYPE if column_name.endswith(OID_SUFFIX) else prisma_type_map.get(column_type) + if column_prisma_type is None: + raise RuntimeError(f"Cannot convert column type to prisma type: {column_type}") + column_gdl_type = gdl_type_map.get(column_type) + if column_gdl_type is None: + raise RuntimeError(f"Cannot convert column type to gdl type: {column_type}") + + is_pk = len(column_desc_list) == 3 and column_desc_list[2] == "<>" + if is_pk: + pk_index = len(column_list) + + column = Column( + name=column_name, + type=column_type, + prisma_type=column_prisma_type, + gdl_type=column_gdl_type, + is_pk=is_pk, + ) + column_list.append(column) + + table = Table( + name=table_name, + column_list=column_list, + pk_index=pk_index, + ) + + table_list.append(table) + + return table_list + + +def generate_doclass_predicate_params(table: Table, column: Optional[Column] = None) -> List[str]: + """ 生成 godel DOClass 中的 predicate 参数列表 + + Args: + table: 表 + column: 列,如果不指定则生成 DOClass 的构造函数参数列表 + + Returns: + param_list: godel DOClass 中的 predicate 参数列表 + + """ + param_list = ["_"] * len(table.column_list) + param_list[table.pk_index] = "this" + if column and not column.is_pk: + index = table.column_list.index(column) + param_list[index] = to_lower_camel(column.name) + + return param_list + + +def main(): + args = parse_args() + puml_er_file = args.puml_er_file + puml_er_str = puml_er_file.read() + table_list = parse_puml_er(puml_er_str=puml_er_str) + puml_er_file.close() + + jinja_env = Environment( + loader=FileSystemLoader( + searchpath=script_dir_path + ), + extensions=["jinja2_strcase.StrcaseExtension"] + ) + + def test(): + return ['_'] * 10 + + for template_name in jinja_env.list_templates(extensions="j2"): + template = jinja_env.get_template(template_name) + rendered_content = template.render( + table_list=table_list, + generate_doclass_predicate_params=generate_doclass_predicate_params + ) + rendered_path = Path(args.output_path, Path(template_name).stem) + with open(rendered_path, 'w') as f: + f.write(rendered_content) + + +if __name__ == '__main__': + main() diff --git a/language/javascript/extractor/jinja/requirements.txt b/language/javascript/extractor/jinja/requirements.txt new file mode 100644 index 00000000..17298e77 --- /dev/null +++ b/language/javascript/extractor/jinja/requirements.txt @@ -0,0 +1,2 @@ +Jinja2==3.0.3 +jinja2-strcase==0.0.2 diff --git a/language/javascript/extractor/jinja/schema.prisma.j2 b/language/javascript/extractor/jinja/schema.prisma.j2 new file mode 100644 index 00000000..42a6e23b --- /dev/null +++ b/language/javascript/extractor/jinja/schema.prisma.j2 @@ -0,0 +1,19 @@ +// Generated from coref-javascript-er.puml + +datasource db { + provider = "sqlite" + url = "file:../init.db" +} + +generator client { + provider = "prisma-client-js" + binaryTargets = ["darwin", "darwin-arm64", "debian-openssl-1.0.x", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "rhel-openssl-1.0.x", "rhel-openssl-1.1.x", "rhel-openssl-3.0.x"] +} + +{% for table in table_list %} +model {{table.name}} { + {%- for column in table.column_list %} + {{ column.name }} {{column.prisma_type}}{% if column.is_pk %} @id {%- endif -%} + {% endfor %} +} +{% endfor %} diff --git a/language/javascript/extractor/package.json b/language/javascript/extractor/package.json new file mode 100644 index 00000000..bfa814db --- /dev/null +++ b/language/javascript/extractor/package.json @@ -0,0 +1,67 @@ +{ + "name": "coref-js-src-extractor", + "version": "1.0.0", + "description": "A COREF JavaScript source extractor", + "main": "dist/src/index.js", + "bin": "dist/src/index.js", + "pkg": { + "assets": [ + "init.db" + ], + "scripts": [ + "dist/src/core/worker.js" + ] + }, + "scripts": { + "lint": "npx eslint . --ext .js,.jsx,.ts,.tsx", + "clean": "rm -rf dist", + "clean-all": "rm -rf node_modules dist", + "build": "npm run clean && npx tsc -p .", + "pkg": "npm run build && npx prisma db push && node scripts/fix-dot-prisma-client-package-json.js && npx pkg . -C GZip -t node18 -o coref-js-src-extractor --options max-old-space-size=7168", + "rebuild": "npm run clean-all && npm i && npx tsc -p .", + "extract-ts-node-relations": "npx ts-node src/index.ts extract-ts-node-relations", + "generate-model": "python3 jinja/puml_to_schema_prisma.py coref-javascript-er.puml && mv jinja/schema.prisma prisma/schema.prisma && mv jinja/*.gdl ../lib/config", + "update-db": "npx prisma db push", + "prettier": "npx prettier --write .", + "test": "npx jest" + }, + "repository": { + "type": "git", + "url": "git@code.alipay.com:codeinsight_sys/coref-js-src-extractor.git" + }, + "keywords": [ + "coref", + "extractor" + ], + "author": "", + "license": "ISC", + "dependencies": { + "@prisma/client": "^5.1.1", + "commander": "^11.0.0", + "ignore": "^5.2.4", + "lodash": "^4.17.21", + "shelljs": "^0.8.5", + "threads": "^1.7.0", + "typescript": "4.5.5" + }, + "devDependencies": { + "@bazel/typescript": "^5.8.1", + "@types/jest": "^29.5.3", + "@types/lodash": "^4.14.196", + "@types/node": "^18.11.9", + "@types/shelljs": "^0.8.12", + "@typescript-eslint/eslint-plugin": "^6.3.0", + "@typescript-eslint/parser": "^6.3.0", + "eslint": "^8.46.0", + "jest": "^29.6.2", + "pkg": "^5.8.1", + "prettier": "^3.0.1", + "prisma": "^5.1.1", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "typescript-latest": "npm:typescript@^5.1.6" + }, + "prisma": { + "schema": "prisma/schema.prisma" + } +} diff --git a/language/javascript/extractor/prisma/schema.prisma b/language/javascript/extractor/prisma/schema.prisma new file mode 100644 index 00000000..47b7fd29 --- /dev/null +++ b/language/javascript/extractor/prisma/schema.prisma @@ -0,0 +1,168 @@ +// Generated from coref-javascript-er.puml + +datasource db { + provider = "sqlite" + url = "file:../init.db" +} + +generator client { + provider = "prisma-client-js" + binaryTargets = ["darwin", "darwin-arm64", "debian-openssl-1.0.x", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "rhel-openssl-1.0.x", "rhel-openssl-1.1.x", "rhel-openssl-3.0.x"] +} + + +model location { + oid BigInt @id + file_oid BigInt + start_line_number Int + start_column_number Int + end_line_number Int + end_column_number Int + text String +} + +model number_of_lines { + location_oid BigInt @id + lines Int + code_lines Int + comment_lines Int +} + +model file { + oid BigInt @id + name String + extension String + relative_path String + location_oid BigInt +} + +model directory { + oid BigInt @id + name String + relative_path String + location_oid BigInt +} + +model directory_hierarchy { + parent_oid BigInt + child_oid BigInt @id +} + +model top_level { + oid BigInt @id + kind Int + location_oid BigInt +} + +model node { + oid BigInt @id + kind Int + parent_oid BigInt + index Int + location_oid BigInt +} + +model literal { + oid BigInt @id + value String +} + +model binding_element_property_name { + oid BigInt @id + property_name_oid BigInt +} + +model binding_element_name { + oid BigInt @id + name_oid BigInt +} + +model binding_element_initializer { + oid BigInt @id + initializer_oid BigInt +} + +model class_like_declaration { + oid BigInt @id + kind Int + name String +} + +model function_like_declaration { + oid BigInt @id + kind Int + name String +} + +model function_enclosing_node { + node_oid BigInt @id + function_oid BigInt +} + +model modifier { + oid BigInt @id + index Int +} + +model symbol_ { + oid BigInt @id + name String + description String +} + +model node_symbol { + node_oid BigInt @id + symbol_oid BigInt +} + +model shorthand_assignment_value_symbol { + node_oid BigInt @id + symbol_oid BigInt +} + +model call_site { + invoke_expression_oid BigInt @id + callee_oid BigInt +} + +model cfg_entry_node { + oid BigInt @id + ast_node_oid BigInt +} + +model cfg_exit_node { + oid BigInt @id + ast_node_oid BigInt +} + +model comment { + oid BigInt @id + kind Int + location_oid BigInt +} + +model node_comment { + oid BigInt @id + node_oid BigInt + comment_oid BigInt + type Int +} + +model js_parse_error { + oid BigInt @id + message String + line String +} + +model metadata { + oid BigInt @id + version String + created_time DateTime +} + +model ignored_path { + oid BigInt @id + path_kind Int + path String + ignore_kind Int +} diff --git a/language/javascript/extractor/scripts/fix-dot-prisma-client-package-json.js b/language/javascript/extractor/scripts/fix-dot-prisma-client-package-json.js new file mode 100644 index 00000000..5be5853f --- /dev/null +++ b/language/javascript/extractor/scripts/fix-dot-prisma-client-package-json.js @@ -0,0 +1,11 @@ + + +const shell = require('shelljs'); +const path = require('path'); + +// Set a fake version for ".prisma/client/package.json" +const packageJsonPath = path.join( + path.dirname(__dirname), + '/node_modules/.prisma/client/package.json', +); +shell.sed('-i', /^\{$/, '{\n "version": "0.0.1",', packageJsonPath); diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/binding-pattern.ts b/language/javascript/extractor/src/__test__/core/expected-coref/binding-pattern.ts new file mode 100644 index 00000000..c94e5e93 --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/binding-pattern.ts @@ -0,0 +1,779 @@ + + +export const bindingPatternNodes = [ + { + oid: -4246786361847064053n, + kind: 79, + location: { + oid: -1447491131845923008n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 10, offset: 9 }, + end: { line: 1, column: 11, offset: 10 }, + text: 'a', + }, + parent_oid: 2280000790093214095n, + index: 0, + }, + { + oid: 8172280562058547851n, + kind: 79, + location: { + oid: -3998888667396471241n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 15, offset: 14 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'b', + }, + parent_oid: -6458225655727183887n, + index: 0, + }, + { + oid: 7884506870129767919n, + kind: 8, + location: { + oid: 6582680305800366772n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 19, offset: 18 }, + end: { line: 1, column: 20, offset: 19 }, + text: '4', + }, + value: '4', + parent_oid: -6458225655727183887n, + index: 1, + }, + { + oid: -1700678596642740122n, + kind: 226, + location: { + oid: 1549528087037210419n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 8, offset: 7 }, + end: { line: 1, column: 8, offset: 7 }, + text: '', + }, + parent_oid: -6905330016331948382n, + index: 0, + }, + { + oid: 2280000790093214095n, + kind: 202, + location: { + oid: -1447491131845923008n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 10, offset: 9 }, + end: { line: 1, column: 11, offset: 10 }, + text: 'a', + }, + nameOid: -4246786361847064053n, + parent_oid: -6905330016331948382n, + index: 1, + }, + { + oid: -2381404826512761297n, + kind: 226, + location: { + oid: -6039579376299305282n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 12, offset: 11 }, + end: { line: 1, column: 12, offset: 11 }, + text: '', + }, + parent_oid: -6905330016331948382n, + index: 2, + }, + { + oid: -6458225655727183887n, + kind: 202, + location: { + oid: -5222856752318309071n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 15, offset: 14 }, + end: { line: 1, column: 20, offset: 19 }, + text: 'b = 4', + }, + nameOid: 8172280562058547851n, + initializerOid: 7884506870129767919n, + parent_oid: -6905330016331948382n, + index: 3, + }, + { + oid: -6686834473083156461n, + kind: 8, + location: { + oid: -1071443420307839167n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 25, offset: 24 }, + end: { line: 1, column: 26, offset: 25 }, + text: '1', + }, + value: '1', + parent_oid: 8297680356067873397n, + index: 0, + }, + { + oid: -3686529351536779963n, + kind: 8, + location: { + oid: -3076181306460552629n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 28, offset: 27 }, + end: { line: 1, column: 29, offset: 28 }, + text: '2', + }, + value: '2', + parent_oid: 8297680356067873397n, + index: 1, + }, + { + oid: 8354685449409048052n, + kind: 8, + location: { + oid: -3966310770618905020n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 31, offset: 30 }, + end: { line: 1, column: 32, offset: 31 }, + text: '3', + }, + value: '3', + parent_oid: 8297680356067873397n, + index: 2, + }, + { + oid: -6905330016331948382n, + kind: 201, + location: { + oid: -2269165141441383965n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 7, offset: 6 }, + end: { line: 1, column: 21, offset: 20 }, + text: '[, a, , b = 4]', + }, + parent_oid: 8375754584870238756n, + index: 0, + }, + { + oid: 8297680356067873397n, + kind: 203, + location: { + oid: -3056556261279189606n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 24, offset: 23 }, + end: { line: 1, column: 33, offset: 32 }, + text: '[1, 2, 3]', + }, + parent_oid: 8375754584870238756n, + index: 1, + }, + { + oid: 8375754584870238756n, + kind: 253, + location: { + oid: 223444377857857516n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 7, offset: 6 }, + end: { line: 1, column: 33, offset: 32 }, + text: '[, a, , b = 4] = [1, 2, 3]', + }, + parent_oid: -6244906081437478520n, + index: 0, + }, + { + oid: -6244906081437478520n, + kind: 254, + location: { + oid: 2048842289627522726n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 33, offset: 32 }, + text: 'const [, a, , b = 4] = [1, 2, 3]', + }, + parent_oid: -6334087105900493209n, + index: 0, + }, + { + oid: 2514700051251150593n, + kind: 79, + location: { + oid: -3547430297856482656n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 9, offset: 42 }, + end: { line: 2, column: 10, offset: 43 }, + text: 'x', + }, + parent_oid: -3123047611434177923n, + index: 0, + }, + { + oid: 7175212762998716061n, + kind: 79, + location: { + oid: 8806697018317246235n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 12, offset: 45 }, + end: { line: 2, column: 13, offset: 46 }, + text: 'b', + }, + parent_oid: -5622451158028247189n, + index: 0, + }, + { + oid: 932279114546082528n, + kind: 79, + location: { + oid: -1475894181314227051n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 15, offset: 48 }, + end: { line: 2, column: 16, offset: 49 }, + text: 'y', + }, + parent_oid: -5622451158028247189n, + index: 1, + }, + { + oid: -1136092844867676242n, + kind: 25, + location: { + oid: 6020900006874321928n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 18, offset: 51 }, + end: { line: 2, column: 21, offset: 54 }, + text: '...', + }, + parent_oid: -3325876657747674592n, + index: 0, + }, + { + oid: -3304925721244204841n, + kind: 79, + location: { + oid: 5427873995605938258n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 21, offset: 54 }, + end: { line: 2, column: 22, offset: 55 }, + text: 'z', + }, + parent_oid: -3325876657747674592n, + index: 1, + }, + { + oid: -3123047611434177923n, + kind: 202, + location: { + oid: -3547430297856482656n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 9, offset: 42 }, + end: { line: 2, column: 10, offset: 43 }, + text: 'x', + }, + nameOid: 2514700051251150593n, + parent_oid: 5826315108876157060n, + index: 0, + }, + { + oid: -5622451158028247189n, + kind: 202, + location: { + oid: 7617706719771554491n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 12, offset: 45 }, + end: { line: 2, column: 16, offset: 49 }, + text: 'b: y', + }, + propertyNameOid: 7175212762998716061n, + nameOid: 932279114546082528n, + parent_oid: 5826315108876157060n, + index: 1, + }, + { + oid: -3325876657747674592n, + kind: 202, + location: { + oid: 3672173016568282681n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 18, offset: 51 }, + end: { line: 2, column: 22, offset: 55 }, + text: '...z', + }, + nameOid: -3304925721244204841n, + parent_oid: 5826315108876157060n, + index: 2, + }, + { + oid: 398406002426688392n, + kind: 79, + location: { + oid: 1606607283395383069n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 29, offset: 62 }, + end: { line: 2, column: 30, offset: 63 }, + text: 'x', + }, + parent_oid: 3156103746898593114n, + index: 0, + }, + { + oid: 1989423827739680164n, + kind: 8, + location: { + oid: -7335271091293259930n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 32, offset: 65 }, + end: { line: 2, column: 33, offset: 66 }, + text: '1', + }, + value: '1', + parent_oid: 3156103746898593114n, + index: 1, + }, + { + oid: -4089025887355607372n, + kind: 79, + location: { + oid: 1917449464570962275n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 35, offset: 68 }, + end: { line: 2, column: 36, offset: 69 }, + text: 'b', + }, + parent_oid: 5396315603117816972n, + index: 0, + }, + { + oid: 2072983599837777194n, + kind: 8, + location: { + oid: -1770510405752287340n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 38, offset: 71 }, + end: { line: 2, column: 39, offset: 72 }, + text: '2', + }, + value: '2', + parent_oid: 5396315603117816972n, + index: 1, + }, + { + oid: -4865736489807708106n, + kind: 79, + location: { + oid: -4566166882220805309n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 41, offset: 74 }, + end: { line: 2, column: 42, offset: 75 }, + text: 'c', + }, + parent_oid: -656483300044222531n, + index: 0, + }, + { + oid: 519930599990752055n, + kind: 8, + location: { + oid: -5953137852814756592n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 44, offset: 77 }, + end: { line: 2, column: 45, offset: 78 }, + text: '3', + }, + value: '3', + parent_oid: -656483300044222531n, + index: 1, + }, + { + oid: 2875935766612743264n, + kind: 79, + location: { + oid: 1270186253808355740n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 47, offset: 80 }, + end: { line: 2, column: 48, offset: 81 }, + text: 'd', + }, + parent_oid: -8308296810397712739n, + index: 0, + }, + { + oid: 3781274724907788594n, + kind: 8, + location: { + oid: -8574753904804200900n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 50, offset: 83 }, + end: { line: 2, column: 51, offset: 84 }, + text: '4', + }, + value: '4', + parent_oid: -8308296810397712739n, + index: 1, + }, + { + oid: 3156103746898593114n, + kind: 294, + location: { + oid: -64948842518226791n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 29, offset: 62 }, + end: { line: 2, column: 33, offset: 66 }, + text: 'x: 1', + }, + parent_oid: 1999050683603047115n, + index: 0, + }, + { + oid: 5396315603117816972n, + kind: 294, + location: { + oid: 8156763499285837815n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 35, offset: 68 }, + end: { line: 2, column: 39, offset: 72 }, + text: 'b: 2', + }, + parent_oid: 1999050683603047115n, + index: 1, + }, + { + oid: -656483300044222531n, + kind: 294, + location: { + oid: 262085237663769464n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 41, offset: 74 }, + end: { line: 2, column: 45, offset: 78 }, + text: 'c: 3', + }, + parent_oid: 1999050683603047115n, + index: 2, + }, + { + oid: -8308296810397712739n, + kind: 294, + location: { + oid: 5103554022471999189n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 47, offset: 80 }, + end: { line: 2, column: 51, offset: 84 }, + text: 'd: 4', + }, + parent_oid: 1999050683603047115n, + index: 3, + }, + { + oid: 5826315108876157060n, + kind: 200, + location: { + oid: -6719356795269821843n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 7, offset: 40 }, + end: { line: 2, column: 24, offset: 57 }, + text: '{ x, b: y, ...z }', + }, + parent_oid: -6329652925765871924n, + index: 0, + }, + { + oid: 1999050683603047115n, + kind: 204, + location: { + oid: -820417508571961402n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 27, offset: 60 }, + end: { line: 2, column: 53, offset: 86 }, + text: '{ x: 1, b: 2, c: 3, d: 4 }', + }, + parent_oid: -6329652925765871924n, + index: 1, + }, + { + oid: -6329652925765871924n, + kind: 253, + location: { + oid: 3239524746400742591n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 7, offset: 40 }, + end: { line: 2, column: 53, offset: 86 }, + text: '{ x, b: y, ...z } = { x: 1, b: 2, c: 3, d: 4 }', + }, + parent_oid: -8290723001452899282n, + index: 0, + }, + { + oid: -8290723001452899282n, + kind: 254, + location: { + oid: 4539907272669935082n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 1, offset: 34 }, + end: { line: 2, column: 53, offset: 86 }, + text: 'const { x, b: y, ...z } = { x: 1, b: 2, c: 3, d: 4 }', + }, + parent_oid: 8484629532988454804n, + index: 0, + }, + { + oid: -6334087105900493209n, + kind: 236, + location: { + oid: -3708491126196849172n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 34, offset: 33 }, + text: 'const [, a, , b = 4] = [1, 2, 3];', + }, + parent_oid: -8965019041605517731n, + index: 0, + }, + { + oid: 8484629532988454804n, + kind: 236, + location: { + oid: -8753577169651814570n, + file: { + oid: 2912759445034331157n, + name: 'binding-pattern.ts', + extension: '.ts', + relativePath: 'binding-pattern.ts', + locationOid: -5531347451343665188n, + }, + start: { line: 2, column: 1, offset: 34 }, + end: { line: 2, column: 54, offset: 87 }, + text: 'const { x, b: y, ...z } = { x: 1, b: 2, c: 3, d: 4 };', + }, + parent_oid: -8965019041605517731n, + index: 1, + }, +]; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/comment.ts b/language/javascript/extractor/src/__test__/core/expected-coref/comment.ts new file mode 100644 index 00000000..a78f3b52 --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/comment.ts @@ -0,0 +1,370 @@ + + +export const commentCoref = { + comments: [ + { + oid: -1110728879817158026n, + kind: 3, + location: { + oid: -2566561945798912293n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 3, column: 4, offset: 50 }, + text: '/**\n * Copyright 2022-2023 Ant Group CO., Ltd.\n */', + }, + commentKind: 1, + }, + { + oid: 6691789866961927815n, + kind: 2, + location: { + oid: 3684483758057237465n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 5, column: 1, offset: 52 }, + end: { line: 5, column: 9, offset: 60 }, + text: '// test1', + }, + commentKind: 0, + }, + { + oid: 33370432759224511n, + kind: 2, + location: { + oid: 3496625402799083061n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 18, offset: 78 }, + end: { line: 6, column: 26, offset: 86 }, + text: '// test1', + }, + commentKind: 0, + }, + { + oid: 6521459556772605149n, + kind: 3, + location: { + oid: 573697451394877732n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 8, column: 1, offset: 88 }, + end: { line: 8, column: 13, offset: 100 }, + text: '/** test2 */', + }, + commentKind: 1, + }, + { + oid: -4909798232494684022n, + kind: 3, + location: { + oid: -502017144889268209n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 18, offset: 118 }, + end: { line: 9, column: 30, offset: 130 }, + text: '/** test2 */', + }, + commentKind: 1, + }, + { + oid: -7967661793336760111n, + kind: 2, + location: { + oid: 4525103167162641634n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 11, column: 1, offset: 132 }, + end: { line: 11, column: 9, offset: 140 }, + text: '// test3', + }, + commentKind: 0, + }, + ], + nodes: [ + { + oid: 3433094567629474496n, + kind: 79, + location: { + oid: 5193567455604755035n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 7, offset: 67 }, + end: { line: 6, column: 12, offset: 72 }, + text: 'test1', + }, + parent_oid: -5349587668526978870n, + index: 0, + }, + { + oid: -6825567904999286233n, + kind: 8, + location: { + oid: 5066796588386530695n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 15, offset: 75 }, + end: { line: 6, column: 16, offset: 76 }, + text: '1', + }, + value: '1', + parent_oid: -5349587668526978870n, + index: 1, + }, + { + oid: -5349587668526978870n, + kind: 253, + location: { + oid: -7993123226138720966n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 7, offset: 67 }, + end: { line: 6, column: 16, offset: 76 }, + text: 'test1 = 1', + }, + parent_oid: -4372203275552147212n, + index: 0, + }, + { + oid: -4372203275552147212n, + kind: 254, + location: { + oid: 8447862192537798785n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 1, offset: 61 }, + end: { line: 6, column: 16, offset: 76 }, + text: 'const test1 = 1', + }, + parent_oid: -2366012814038236925n, + index: 0, + }, + { + oid: -7444984485382419504n, + kind: 79, + location: { + oid: -2057719434413587182n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 7, offset: 107 }, + end: { line: 9, column: 12, offset: 112 }, + text: 'test2', + }, + parent_oid: -4107660491406335808n, + index: 0, + }, + { + oid: -2217207039650146456n, + kind: 8, + location: { + oid: 4057612669953705711n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 15, offset: 115 }, + end: { line: 9, column: 16, offset: 116 }, + text: '2', + }, + value: '2', + parent_oid: -4107660491406335808n, + index: 1, + }, + { + oid: -4107660491406335808n, + kind: 253, + location: { + oid: -6259239162025836247n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 7, offset: 107 }, + end: { line: 9, column: 16, offset: 116 }, + text: 'test2 = 2', + }, + parent_oid: 3194902079657026235n, + index: 0, + }, + { + oid: 3194902079657026235n, + kind: 254, + location: { + oid: -2447281222413906870n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 1, offset: 101 }, + end: { line: 9, column: 16, offset: 116 }, + text: 'const test2 = 2', + }, + parent_oid: -2386807080587654265n, + index: 0, + }, + { + oid: -2366012814038236925n, + kind: 236, + location: { + oid: 309902191598086501n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 6, column: 1, offset: 61 }, + end: { line: 6, column: 17, offset: 77 }, + text: 'const test1 = 1;', + }, + parent_oid: -5123986984753617060n, + index: 0, + }, + { + oid: -2386807080587654265n, + kind: 236, + location: { + oid: 7420471485763264320n, + file: { + oid: -4709767712954094484n, + name: 'comment.ts', + extension: '.ts', + relativePath: 'comment.ts', + locationOid: -9048507244550037512n, + }, + start: { line: 9, column: 1, offset: 101 }, + end: { line: 9, column: 17, offset: 117 }, + text: 'const test2 = 2;', + }, + parent_oid: -5123986984753617060n, + index: 1, + }, + ], + nodeComments: [ + { + oid: 3149489737925991383n, + nodeOid: -4372203275552147212n, + commentOid: -1110728879817158026n, + type: 0, + }, + { + oid: 7988343498221309709n, + nodeOid: -4372203275552147212n, + commentOid: 6691789866961927815n, + type: 0, + }, + { + oid: -4285491061922299194n, + nodeOid: -2366012814038236925n, + commentOid: -1110728879817158026n, + type: 0, + }, + { + oid: 1307757883976346345n, + nodeOid: -2366012814038236925n, + commentOid: 6691789866961927815n, + type: 0, + }, + { + oid: -2154889149408006075n, + nodeOid: -2366012814038236925n, + commentOid: 33370432759224511n, + type: 1, + }, + { + oid: 8602605640876593127n, + nodeOid: 3194902079657026235n, + commentOid: 6521459556772605149n, + type: 0, + }, + { + oid: 8641246310417171505n, + nodeOid: -2386807080587654265n, + commentOid: 6521459556772605149n, + type: 0, + }, + { + oid: 2919182433724623520n, + nodeOid: -2386807080587654265n, + commentOid: -4909798232494684022n, + type: 1, + }, + { + oid: 4707602771016258220n, + nodeOid: -5123986984753617060n, + commentOid: -1110728879817158026n, + type: 0, + }, + { + oid: 4187134418009168185n, + nodeOid: -5123986984753617060n, + commentOid: 6691789866961927815n, + type: 0, + }, + ], +}; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/for-statement.ts b/language/javascript/extractor/src/__test__/core/expected-coref/for-statement.ts new file mode 100644 index 00000000..fa95c217 --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/for-statement.ts @@ -0,0 +1,961 @@ + + +import { Literal, Node } from '../../../model/coref'; + +export const forStatementNodes: (Node | Literal)[] = [ + { + oid: 4417953990286519927n, + kind: 79, + location: { + oid: 8918253734098640173n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 1, column: 5, offset: 4 }, + end: { line: 1, column: 6, offset: 5 }, + text: 'i', + }, + parent_oid: -1848824995536749153n, + index: 0, + }, + { + oid: -393469777934960583n, + kind: 8, + location: { + oid: 6968403110181133123n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 1, column: 9, offset: 8 }, + end: { line: 1, column: 10, offset: 9 }, + text: '0', + }, + value: '0', + parent_oid: -1848824995536749153n, + index: 1, + }, + { + oid: -1848824995536749153n, + kind: 253, + location: { + oid: -5004605697652003912n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 1, column: 5, offset: 4 }, + end: { line: 1, column: 10, offset: 9 }, + text: 'i = 0', + }, + parent_oid: -2651186838890272664n, + index: 0, + }, + { + oid: -2651186838890272664n, + kind: 254, + location: { + oid: -9012506092906580858n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 10, offset: 9 }, + text: 'let i = 0', + }, + parent_oid: -2594963787184972582n, + index: 0, + }, + { + oid: 2613091547609784897n, + kind: 79, + location: { + oid: -1346170418692863642n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 8, offset: 19 }, + end: { line: 3, column: 9, offset: 20 }, + text: 'i', + }, + parent_oid: 5307869802140025325n, + index: 0, + }, + { + oid: -5722874743680103645n, + kind: 29, + location: { + oid: -59701184464655782n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 10, offset: 21 }, + end: { line: 3, column: 11, offset: 22 }, + text: '<', + }, + parent_oid: 5307869802140025325n, + index: 1, + }, + { + oid: 5334152481181854023n, + kind: 8, + location: { + oid: -5706378206224911036n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 12, offset: 23 }, + end: { line: 3, column: 13, offset: 24 }, + text: '5', + }, + value: '5', + parent_oid: 5307869802140025325n, + index: 2, + }, + { + oid: 8793911552118476775n, + kind: 79, + location: { + oid: -3680049266524191952n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 15, offset: 26 }, + end: { line: 3, column: 16, offset: 27 }, + text: 'i', + }, + parent_oid: -2883858918882860145n, + index: 0, + }, + { + oid: -4821239801638123475n, + kind: 45, + location: { + oid: 4188226761207283828n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 16, offset: 27 }, + end: { line: 3, column: 18, offset: 29 }, + text: '++', + }, + parent_oid: -2883858918882860145n, + index: 1, + }, + { + oid: 9169231027473987931n, + kind: 79, + location: { + oid: 5160092370435959686n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 3, offset: 35 }, + end: { line: 4, column: 10, offset: 42 }, + text: 'console', + }, + parent_oid: -4988002561192660177n, + index: 0, + }, + { + oid: -56887219523850726n, + kind: 79, + location: { + oid: 8906617969938335962n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 11, offset: 43 }, + end: { line: 4, column: 14, offset: 46 }, + text: 'log', + }, + parent_oid: -4988002561192660177n, + index: 1, + }, + { + oid: -4988002561192660177n, + kind: 205, + location: { + oid: 1640241548816941671n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 3, offset: 35 }, + end: { line: 4, column: 14, offset: 46 }, + text: 'console.log', + }, + parent_oid: 2348397814661714889n, + index: 0, + }, + { + oid: 580545038174791000n, + kind: 79, + location: { + oid: -7717288074326111854n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 15, offset: 47 }, + end: { line: 4, column: 16, offset: 48 }, + text: 'i', + }, + parent_oid: 2348397814661714889n, + index: 1, + }, + { + oid: 2348397814661714889n, + kind: 207, + location: { + oid: 4496709144284528852n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 3, offset: 35 }, + end: { line: 4, column: 17, offset: 49 }, + text: 'console.log(i)', + }, + parent_oid: 2898274088788402064n, + index: 0, + }, + { + oid: 2898274088788402064n, + kind: 237, + location: { + oid: -4768597095458718793n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 4, column: 3, offset: 35 }, + end: { line: 4, column: 18, offset: 50 }, + text: 'console.log(i);', + }, + parent_oid: 5535791613955898396n, + index: 0, + }, + { + oid: 5307869802140025325n, + kind: 220, + location: { + oid: -3310151851607449110n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 8, offset: 19 }, + end: { line: 3, column: 13, offset: 24 }, + text: 'i < 5', + }, + parent_oid: -5712446920760621094n, + index: 1, + }, + { + oid: -2883858918882860145n, + kind: 219, + location: { + oid: 6509358806778151052n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 15, offset: 26 }, + end: { line: 3, column: 18, offset: 29 }, + text: 'i++', + }, + parent_oid: -5712446920760621094n, + index: 2, + }, + { + oid: 5535791613955898396n, + kind: 234, + location: { + oid: -6187279088637224518n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 20, offset: 31 }, + end: { line: 5, column: 2, offset: 52 }, + text: '{\n console.log(i);\n}', + }, + parent_oid: -5712446920760621094n, + index: 3, + }, + { + oid: 6470218670596352179n, + kind: 79, + location: { + oid: -1603457077507513938n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 6, offset: 59 }, + end: { line: 7, column: 7, offset: 60 }, + text: 'i', + }, + parent_oid: -8826396271578988842n, + index: 0, + }, + { + oid: 1541531288322856435n, + kind: 63, + location: { + oid: 1488824528963999853n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 8, offset: 61 }, + end: { line: 7, column: 9, offset: 62 }, + text: '=', + }, + parent_oid: -8826396271578988842n, + index: 1, + }, + { + oid: -4845795493507328896n, + kind: 8, + location: { + oid: -9162690614645413193n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 10, offset: 63 }, + end: { line: 7, column: 11, offset: 64 }, + text: '0', + }, + value: '0', + parent_oid: -8826396271578988842n, + index: 2, + }, + { + oid: 6395526108634370320n, + kind: 79, + location: { + oid: 4645935941032561732n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 3, offset: 74 }, + end: { line: 8, column: 10, offset: 81 }, + text: 'console', + }, + parent_oid: -8089384649573883724n, + index: 0, + }, + { + oid: 5721372429702697706n, + kind: 79, + location: { + oid: -1566961427210846519n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 11, offset: 82 }, + end: { line: 8, column: 14, offset: 85 }, + text: 'log', + }, + parent_oid: -8089384649573883724n, + index: 1, + }, + { + oid: -8089384649573883724n, + kind: 205, + location: { + oid: 3521664531662084457n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 3, offset: 74 }, + end: { line: 8, column: 14, offset: 85 }, + text: 'console.log', + }, + parent_oid: 6559214997272214002n, + index: 0, + }, + { + oid: 5440308364006246069n, + kind: 79, + location: { + oid: -2698270016411525395n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 15, offset: 86 }, + end: { line: 8, column: 16, offset: 87 }, + text: 'i', + }, + parent_oid: 6559214997272214002n, + index: 1, + }, + { + oid: 6559214997272214002n, + kind: 207, + location: { + oid: -6965205646529564366n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 3, offset: 74 }, + end: { line: 8, column: 17, offset: 88 }, + text: 'console.log(i)', + }, + parent_oid: 1570807230807286989n, + index: 0, + }, + { + oid: 8845469255836288599n, + kind: 79, + location: { + oid: 6840826047722818015n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 7, offset: 97 }, + end: { line: 10, column: 8, offset: 98 }, + text: 'i', + }, + parent_oid: -4980927897694810877n, + index: 0, + }, + { + oid: 2880608590256468639n, + kind: 36, + location: { + oid: -8309094520642820607n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 9, offset: 99 }, + end: { line: 10, column: 12, offset: 102 }, + text: '===', + }, + parent_oid: -4980927897694810877n, + index: 1, + }, + { + oid: -6633693875801226340n, + kind: 8, + location: { + oid: 4067231107285246556n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 13, offset: 103 }, + end: { line: 10, column: 14, offset: 104 }, + text: '1', + }, + value: '1', + parent_oid: -4980927897694810877n, + index: 2, + }, + { + oid: 7145465769499290486n, + kind: 244, + location: { + oid: -3045846010451106954n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 11, column: 5, offset: 112 }, + end: { line: 11, column: 14, offset: 121 }, + text: 'continue;', + }, + parent_oid: 7873483148483099017n, + index: 0, + }, + { + oid: -4980927897694810877n, + kind: 220, + location: { + oid: 8526073948063148666n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 7, offset: 97 }, + end: { line: 10, column: 14, offset: 104 }, + text: 'i === 1', + }, + parent_oid: -2089685774247872533n, + index: 0, + }, + { + oid: 7873483148483099017n, + kind: 234, + location: { + oid: -962896942906356870n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 16, offset: 106 }, + end: { line: 12, column: 4, offset: 125 }, + text: '{\n continue;\n }', + }, + parent_oid: -2089685774247872533n, + index: 1, + }, + { + oid: -3494890108910525587n, + kind: 79, + location: { + oid: 84588773375919427n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 7, offset: 133 }, + end: { line: 14, column: 8, offset: 134 }, + text: 'i', + }, + parent_oid: -3986700046106139098n, + index: 0, + }, + { + oid: -7277178288121964896n, + kind: 31, + location: { + oid: -5265082650004618026n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 9, offset: 135 }, + end: { line: 14, column: 10, offset: 136 }, + text: '>', + }, + parent_oid: -3986700046106139098n, + index: 1, + }, + { + oid: -8630880030062369384n, + kind: 8, + location: { + oid: 4868016208741331175n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 11, offset: 137 }, + end: { line: 14, column: 12, offset: 138 }, + text: '4', + }, + value: '4', + parent_oid: -3986700046106139098n, + index: 2, + }, + { + oid: -8077368888089910632n, + kind: 245, + location: { + oid: -3633657468866717198n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 15, column: 5, offset: 146 }, + end: { line: 15, column: 11, offset: 152 }, + text: 'break;', + }, + parent_oid: 5942457217874559512n, + index: 0, + }, + { + oid: -3986700046106139098n, + kind: 220, + location: { + oid: -6927523862825906074n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 7, offset: 133 }, + end: { line: 14, column: 12, offset: 138 }, + text: 'i > 4', + }, + parent_oid: 8381293959712744653n, + index: 0, + }, + { + oid: 5942457217874559512n, + kind: 234, + location: { + oid: 8419542947950313485n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 14, offset: 140 }, + end: { line: 16, column: 4, offset: 156 }, + text: '{\n break;\n }', + }, + parent_oid: 8381293959712744653n, + index: 1, + }, + { + oid: -8363588264291094115n, + kind: 79, + location: { + oid: -5797171331226658680n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 18, column: 3, offset: 160 }, + end: { line: 18, column: 4, offset: 161 }, + text: 'i', + }, + parent_oid: -7707689429282915992n, + index: 0, + }, + { + oid: 4600666877651822743n, + kind: 45, + location: { + oid: -3071956943100349180n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 18, column: 4, offset: 161 }, + end: { line: 18, column: 6, offset: 163 }, + text: '++', + }, + parent_oid: -7707689429282915992n, + index: 1, + }, + { + oid: -7707689429282915992n, + kind: 219, + location: { + oid: -873183575756678708n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 18, column: 3, offset: 160 }, + end: { line: 18, column: 6, offset: 163 }, + text: 'i++', + }, + parent_oid: 2807963415525252429n, + index: 0, + }, + { + oid: 1570807230807286989n, + kind: 237, + location: { + oid: 43912140005878248n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 8, column: 3, offset: 74 }, + end: { line: 8, column: 18, offset: 89 }, + text: 'console.log(i);', + }, + parent_oid: -2149297823975874159n, + index: 0, + }, + { + oid: -2089685774247872533n, + kind: 238, + location: { + oid: 1582412478447365609n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 10, column: 3, offset: 93 }, + end: { line: 12, column: 4, offset: 125 }, + text: 'if (i === 1) {\n continue;\n }', + }, + parent_oid: -2149297823975874159n, + index: 1, + }, + { + oid: 8381293959712744653n, + kind: 238, + location: { + oid: 8843418210370043289n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 14, column: 3, offset: 129 }, + end: { line: 16, column: 4, offset: 156 }, + text: 'if (i > 4) {\n break;\n }', + }, + parent_oid: -2149297823975874159n, + index: 2, + }, + { + oid: 2807963415525252429n, + kind: 237, + location: { + oid: -2812075189769422778n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 18, column: 3, offset: 160 }, + end: { line: 18, column: 7, offset: 164 }, + text: 'i++;', + }, + parent_oid: -2149297823975874159n, + index: 3, + }, + { + oid: -8826396271578988842n, + kind: 220, + location: { + oid: 1759489342440642133n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 6, offset: 59 }, + end: { line: 7, column: 11, offset: 64 }, + text: 'i = 0', + }, + parent_oid: 5737456942573236407n, + index: 0, + }, + { + oid: -2149297823975874159n, + kind: 234, + location: { + oid: 5305094393628270464n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 17, offset: 70 }, + end: { line: 19, column: 2, offset: 166 }, + text: '{\n console.log(i);\n\n if (i === 1) {\n continue;\n }\n\n if (i > 4) {\n break;\n }\n\n i++;\n}', + }, + parent_oid: 5737456942573236407n, + index: 3, + }, + { + oid: -2594963787184972582n, + kind: 236, + location: { + oid: -3013348445414677589n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 11, offset: 10 }, + text: 'let i = 0;', + }, + parent_oid: -3360183831444581813n, + index: 0, + }, + { + oid: -5712446920760621094n, + kind: 241, + location: { + oid: 6908610824860630628n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 3, column: 1, offset: 12 }, + end: { line: 5, column: 2, offset: 52 }, + text: 'for (; i < 5; i++) {\n console.log(i);\n}', + }, + parent_oid: -3360183831444581813n, + index: 1, + }, + { + oid: 5737456942573236407n, + kind: 241, + location: { + oid: 2369229345975174264n, + file: { + oid: 699647385114522383n, + name: 'for-statement.ts', + extension: '.ts', + relativePath: 'for-statement.ts', + locationOid: -289282490874230113n, + }, + start: { line: 7, column: 1, offset: 54 }, + end: { line: 19, column: 2, offset: 166 }, + text: 'for (i = 0; ; ) {\n console.log(i);\n\n if (i === 1) {\n continue;\n }\n\n if (i > 4) {\n break;\n }\n\n i++;\n}', + }, + parent_oid: -3360183831444581813n, + index: 2, + }, +]; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/function.ts b/language/javascript/extractor/src/__test__/core/expected-coref/function.ts new file mode 100644 index 00000000..2b3dab3e --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/function.ts @@ -0,0 +1,1111 @@ + + +import { coref } from '../../../model'; + +export const callSiteMap = new Map([ + [7989925055347479910n, -7680370939886111243n], +]); + +export const functionFunctionEnclosingNodes: coref.FunctionEnclosingNode[] = [ + { nodeOid: 5163095232367063200n, functionOid: -7680370939886111243n }, + { nodeOid: -1686537665207166989n, functionOid: -7680370939886111243n }, + { nodeOid: -8981970962707516113n, functionOid: -7680370939886111243n }, + { nodeOid: 8594798307753447918n, functionOid: -7680370939886111243n }, + { nodeOid: 6973895616642043927n, functionOid: -7680370939886111243n }, + { nodeOid: 7004303490369607568n, functionOid: -7680370939886111243n }, + { nodeOid: -2089942872308770828n, functionOid: -7680370939886111243n }, + { nodeOid: 2776680580114753345n, functionOid: -7680370939886111243n }, + { nodeOid: 2228158096687175487n, functionOid: -7680370939886111243n }, + { nodeOid: 6759615643754216818n, functionOid: -7680370939886111243n }, + { nodeOid: -3029547024041866051n, functionOid: -7680370939886111243n }, + { nodeOid: 2367938657243177168n, functionOid: -7680370939886111243n }, + { nodeOid: -1797287777020962552n, functionOid: -7680370939886111243n }, + { nodeOid: 1165479732014653184n, functionOid: -7680370939886111243n }, + { nodeOid: 2500085078171656783n, functionOid: -7680370939886111243n }, + { nodeOid: -2573891236790505393n, functionOid: -7680370939886111243n }, + { nodeOid: 4285873317815423198n, functionOid: -7680370939886111243n }, + { nodeOid: 2724094344577604298n, functionOid: -7680370939886111243n }, + { nodeOid: 8679791000203915823n, functionOid: -7680370939886111243n }, + { nodeOid: -2482827858275010054n, functionOid: -7680370939886111243n }, + { nodeOid: -1253327865938107005n, functionOid: -7680370939886111243n }, + { nodeOid: 6363652578236537605n, functionOid: -7680370939886111243n }, + { nodeOid: 8007339430606108755n, functionOid: -7680370939886111243n }, + { nodeOid: 7929648171864929636n, functionOid: -7680370939886111243n }, + { nodeOid: 3271519559742586824n, functionOid: -7630378659301899856n }, + { nodeOid: -1628888209595352149n, functionOid: -7630378659301899856n }, + { nodeOid: -9063390581694204994n, functionOid: -7630378659301899856n }, + { nodeOid: -855113797781476234n, functionOid: -7630378659301899856n }, + { nodeOid: 8345382477881568638n, functionOid: -7630378659301899856n }, + { nodeOid: 1295812419639921512n, functionOid: -7630378659301899856n }, + { nodeOid: -8184664652604838368n, functionOid: -7630378659301899856n }, + { nodeOid: -8086561344205881090n, functionOid: -7630378659301899856n }, + { nodeOid: 8580576223643738969n, functionOid: -7630378659301899856n }, + { nodeOid: 5528737859027064183n, functionOid: -7630378659301899856n }, + { nodeOid: -2902181393983496016n, functionOid: -7630378659301899856n }, + { nodeOid: 8348450046834304261n, functionOid: -7630378659301899856n }, + { nodeOid: -4199453042962313607n, functionOid: -7630378659301899856n }, + { nodeOid: -8510889848095475690n, functionOid: -7630378659301899856n }, + { nodeOid: 6691657021584534717n, functionOid: -7630378659301899856n }, + { nodeOid: -8652599794525726394n, functionOid: -7630378659301899856n }, + { nodeOid: 6294499221264380554n, functionOid: -7630378659301899856n }, + { nodeOid: 8607058461628105798n, functionOid: -7630378659301899856n }, + { nodeOid: 6244429589290501003n, functionOid: -7630378659301899856n }, + { nodeOid: 920210705743695648n, functionOid: -7630378659301899856n }, + { nodeOid: -3766369741245341969n, functionOid: -7630378659301899856n }, + { nodeOid: -2923716734602301627n, functionOid: -7630378659301899856n }, + { nodeOid: 5247794326575326074n, functionOid: -7630378659301899856n }, + { nodeOid: 5644958383241877157n, functionOid: -7630378659301899856n }, + { nodeOid: -5053483803129262111n, functionOid: -7630378659301899856n }, +]; + +export const functionNodes = [ + { + oid: 7004303490369607568n, + kind: 79, + location: { + oid: 7064993674007621562n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 23, offset: 22 }, + end: { line: 1, column: 28, offset: 27 }, + text: 'TypeA', + }, + parent_oid: 6973895616642043927n, + index: 0, + }, + { + oid: 2776680580114753345n, + kind: 79, + location: { + oid: -3359562000440708349n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 30, offset: 29 }, + end: { line: 1, column: 35, offset: 34 }, + text: 'TypeB', + }, + parent_oid: -2089942872308770828n, + index: 0, + }, + { + oid: 2367938657243177168n, + kind: 79, + location: { + oid: 5951017278434666089n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 40, offset: 39 }, + end: { line: 1, column: 45, offset: 44 }, + text: 'TypeA', + }, + parent_oid: -3029547024041866051n, + index: 0, + }, + { + oid: 6759615643754216818n, + kind: 79, + location: { + oid: -4062249437593260602n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 37, offset: 36 }, + end: { line: 1, column: 38, offset: 37 }, + text: 'a', + }, + parent_oid: 2228158096687175487n, + index: 0, + }, + { + oid: -3029547024041866051n, + kind: 177, + location: { + oid: 5951017278434666089n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 40, offset: 39 }, + end: { line: 1, column: 45, offset: 44 }, + text: 'TypeA', + }, + parent_oid: 2228158096687175487n, + index: 1, + }, + { + oid: -2573891236790505393n, + kind: 79, + location: { + oid: 7591430583106084079n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 50, offset: 49 }, + end: { line: 1, column: 55, offset: 54 }, + text: 'TypeB', + }, + parent_oid: 2500085078171656783n, + index: 0, + }, + { + oid: 1165479732014653184n, + kind: 79, + location: { + oid: -5426973345217815856n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 47, offset: 46 }, + end: { line: 1, column: 48, offset: 47 }, + text: 'b', + }, + parent_oid: -1797287777020962552n, + index: 0, + }, + { + oid: 2500085078171656783n, + kind: 177, + location: { + oid: 7591430583106084079n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 50, offset: 49 }, + end: { line: 1, column: 55, offset: 54 }, + text: 'TypeB', + }, + parent_oid: -1797287777020962552n, + index: 1, + }, + { + oid: 2724094344577604298n, + kind: 79, + location: { + oid: -4119421251564367104n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 60, offset: 59 }, + end: { line: 1, column: 65, offset: 64 }, + text: 'TypeA', + }, + parent_oid: 4285873317815423198n, + index: 0, + }, + { + oid: 6973895616642043927n, + kind: 162, + location: { + oid: 7064993674007621562n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 23, offset: 22 }, + end: { line: 1, column: 28, offset: 27 }, + text: 'TypeA', + }, + parent_oid: 8594798307753447918n, + index: 0, + }, + { + oid: -2089942872308770828n, + kind: 162, + location: { + oid: -3359562000440708349n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 30, offset: 29 }, + end: { line: 1, column: 35, offset: 34 }, + text: 'TypeB', + }, + parent_oid: 8594798307753447918n, + index: 1, + }, + { + oid: 2228158096687175487n, + kind: 163, + location: { + oid: -7184510855000110n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 37, offset: 36 }, + end: { line: 1, column: 45, offset: 44 }, + text: 'a: TypeA', + }, + parent_oid: 8594798307753447918n, + index: 2, + }, + { + oid: -1797287777020962552n, + kind: 163, + location: { + oid: 2088001686718126815n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 47, offset: 46 }, + end: { line: 1, column: 55, offset: 54 }, + text: 'b: TypeB', + }, + parent_oid: 8594798307753447918n, + index: 3, + }, + { + oid: 4285873317815423198n, + kind: 177, + location: { + oid: -4119421251564367104n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 60, offset: 59 }, + end: { line: 1, column: 65, offset: 64 }, + text: 'TypeA', + }, + parent_oid: 8594798307753447918n, + index: 4, + }, + { + oid: -8981970962707516113n, + kind: 79, + location: { + oid: 7657318820911604652n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 18, offset: 17 }, + end: { line: 1, column: 20, offset: 19 }, + text: 'fn', + }, + parent_oid: -1686537665207166989n, + index: 0, + }, + { + oid: 8594798307753447918n, + kind: 178, + location: { + oid: -8520847449264321224n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 22, offset: 21 }, + end: { line: 1, column: 65, offset: 64 }, + text: '(a: TypeA, b: TypeB) => TypeA', + }, + parent_oid: -1686537665207166989n, + index: 1, + }, + { + oid: 6363652578236537605n, + kind: 79, + location: { + oid: 8795107253770830812n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 2, column: 3, offset: 70 }, + end: { line: 2, column: 5, offset: 72 }, + text: 'fn', + }, + parent_oid: -1253327865938107005n, + index: 0, + }, + { + oid: 8007339430606108755n, + kind: 10, + location: { + oid: -1918716483435780874n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 2, column: 6, offset: 73 }, + end: { line: 2, column: 13, offset: 80 }, + text: "'Hello'", + }, + value: 'Hello', + parent_oid: -1253327865938107005n, + index: 1, + }, + { + oid: 7929648171864929636n, + kind: 10, + location: { + oid: -7502561581766322170n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 2, column: 15, offset: 82 }, + end: { line: 2, column: 22, offset: 89 }, + text: "'World'", + }, + value: 'World', + parent_oid: -1253327865938107005n, + index: 2, + }, + { + oid: -1253327865938107005n, + kind: 207, + location: { + oid: 5132019184831181922n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 2, column: 3, offset: 70 }, + end: { line: 2, column: 23, offset: 90 }, + text: "fn('Hello', 'World')", + }, + parent_oid: -2482827858275010054n, + index: 0, + }, + { + oid: -2482827858275010054n, + kind: 237, + location: { + oid: 7797915795891074089n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 2, column: 3, offset: 70 }, + end: { line: 2, column: 24, offset: 91 }, + text: "fn('Hello', 'World');", + }, + parent_oid: 8679791000203915823n, + index: 0, + }, + { + oid: 5163095232367063200n, + kind: 79, + location: { + oid: -1121426782277898868n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 10, offset: 9 }, + end: { line: 1, column: 17, offset: 16 }, + text: 'greeter', + }, + parent_oid: -7680370939886111243n, + index: 0, + }, + { + oid: -1686537665207166989n, + kind: 163, + location: { + oid: -4954543299733418125n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 18, offset: 17 }, + end: { line: 1, column: 65, offset: 64 }, + text: 'fn: (a: TypeA, b: TypeB) => TypeA', + }, + parent_oid: -7680370939886111243n, + index: 1, + }, + { + oid: 8679791000203915823n, + kind: 234, + location: { + oid: -4450951612979824875n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 67, offset: 66 }, + end: { line: 3, column: 2, offset: 93 }, + text: "{\n fn('Hello', 'World');\n}", + }, + parent_oid: -7680370939886111243n, + index: 2, + }, + { + oid: -9063390581694204994n, + kind: 79, + location: { + oid: -62083282251606133n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 25, offset: 119 }, + end: { line: 5, column: 30, offset: 124 }, + text: 'TypeA', + }, + parent_oid: -1628888209595352149n, + index: 0, + }, + { + oid: 8345382477881568638n, + kind: 79, + location: { + oid: 5649551322094372086n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 32, offset: 126 }, + end: { line: 5, column: 37, offset: 131 }, + text: 'TypeB', + }, + parent_oid: -855113797781476234n, + index: 0, + }, + { + oid: 8580576223643738969n, + kind: 79, + location: { + oid: 3086081476862129452n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 42, offset: 136 }, + end: { line: 5, column: 47, offset: 141 }, + text: 'TypeA', + }, + parent_oid: -8086561344205881090n, + index: 0, + }, + { + oid: -8184664652604838368n, + kind: 79, + location: { + oid: -1969055667256389387n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 39, offset: 133 }, + end: { line: 5, column: 40, offset: 134 }, + text: 'a', + }, + parent_oid: 1295812419639921512n, + index: 0, + }, + { + oid: -8086561344205881090n, + kind: 177, + location: { + oid: 3086081476862129452n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 42, offset: 136 }, + end: { line: 5, column: 47, offset: 141 }, + text: 'TypeA', + }, + parent_oid: 1295812419639921512n, + index: 1, + }, + { + oid: -4199453042962313607n, + kind: 79, + location: { + oid: 953862380193077446n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 52, offset: 146 }, + end: { line: 5, column: 57, offset: 151 }, + text: 'TypeB', + }, + parent_oid: 8348450046834304261n, + index: 0, + }, + { + oid: -2902181393983496016n, + kind: 79, + location: { + oid: -3039910390643268379n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 49, offset: 143 }, + end: { line: 5, column: 50, offset: 144 }, + text: 'b', + }, + parent_oid: 5528737859027064183n, + index: 0, + }, + { + oid: 8348450046834304261n, + kind: 177, + location: { + oid: 953862380193077446n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 52, offset: 146 }, + end: { line: 5, column: 57, offset: 151 }, + text: 'TypeB', + }, + parent_oid: 5528737859027064183n, + index: 1, + }, + { + oid: 6691657021584534717n, + kind: 79, + location: { + oid: -6396569536273487952n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 60, offset: 154 }, + end: { line: 5, column: 65, offset: 159 }, + text: 'TypeA', + }, + parent_oid: -8510889848095475690n, + index: 0, + }, + { + oid: 920210705743695648n, + kind: 79, + location: { + oid: 3689983948081968499n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 3, offset: 164 }, + end: { line: 6, column: 10, offset: 171 }, + text: 'console', + }, + parent_oid: 6244429589290501003n, + index: 0, + }, + { + oid: -3766369741245341969n, + kind: 79, + location: { + oid: 3748409517658376614n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 11, offset: 172 }, + end: { line: 6, column: 14, offset: 175 }, + text: 'log', + }, + parent_oid: 6244429589290501003n, + index: 1, + }, + { + oid: 6244429589290501003n, + kind: 205, + location: { + oid: 271993367263328573n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 3, offset: 164 }, + end: { line: 6, column: 14, offset: 175 }, + text: 'console.log', + }, + parent_oid: 8607058461628105798n, + index: 0, + }, + { + oid: -2923716734602301627n, + kind: 79, + location: { + oid: 8820822088901071524n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 15, offset: 176 }, + end: { line: 6, column: 16, offset: 177 }, + text: 'a', + }, + parent_oid: 8607058461628105798n, + index: 1, + }, + { + oid: 5247794326575326074n, + kind: 79, + location: { + oid: -801133167765212734n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 18, offset: 179 }, + end: { line: 6, column: 19, offset: 180 }, + text: 'b', + }, + parent_oid: 8607058461628105798n, + index: 2, + }, + { + oid: 8607058461628105798n, + kind: 207, + location: { + oid: -741196197793289188n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 3, offset: 164 }, + end: { line: 6, column: 20, offset: 181 }, + text: 'console.log(a, b)', + }, + parent_oid: 6294499221264380554n, + index: 0, + }, + { + oid: -5053483803129262111n, + kind: 79, + location: { + oid: -8664127405547518650n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 7, column: 10, offset: 192 }, + end: { line: 7, column: 11, offset: 193 }, + text: 'a', + }, + parent_oid: 5644958383241877157n, + index: 0, + }, + { + oid: 6294499221264380554n, + kind: 237, + location: { + oid: -5321430839678656916n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 6, column: 3, offset: 164 }, + end: { line: 6, column: 21, offset: 182 }, + text: 'console.log(a, b);', + }, + parent_oid: -8652599794525726394n, + index: 0, + }, + { + oid: 5644958383241877157n, + kind: 246, + location: { + oid: -7460494315274245047n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 7, column: 3, offset: 185 }, + end: { line: 7, column: 12, offset: 194 }, + text: 'return a;', + }, + parent_oid: -8652599794525726394n, + index: 1, + }, + { + oid: 3271519559742586824n, + kind: 79, + location: { + oid: 7880650577666893787n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 10, offset: 104 }, + end: { line: 5, column: 24, offset: 118 }, + text: 'printToConsole', + }, + parent_oid: -7630378659301899856n, + index: 0, + }, + { + oid: -1628888209595352149n, + kind: 162, + location: { + oid: -62083282251606133n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 25, offset: 119 }, + end: { line: 5, column: 30, offset: 124 }, + text: 'TypeA', + }, + parent_oid: -7630378659301899856n, + index: 1, + }, + { + oid: -855113797781476234n, + kind: 162, + location: { + oid: 5649551322094372086n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 32, offset: 126 }, + end: { line: 5, column: 37, offset: 131 }, + text: 'TypeB', + }, + parent_oid: -7630378659301899856n, + index: 2, + }, + { + oid: 1295812419639921512n, + kind: 163, + location: { + oid: -4030052586247719244n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 39, offset: 133 }, + end: { line: 5, column: 47, offset: 141 }, + text: 'a: TypeA', + }, + parent_oid: -7630378659301899856n, + index: 3, + }, + { + oid: 5528737859027064183n, + kind: 163, + location: { + oid: 8776116859380195419n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 49, offset: 143 }, + end: { line: 5, column: 57, offset: 151 }, + text: 'b: TypeB', + }, + parent_oid: -7630378659301899856n, + index: 4, + }, + { + oid: -8510889848095475690n, + kind: 177, + location: { + oid: -6396569536273487952n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 60, offset: 154 }, + end: { line: 5, column: 65, offset: 159 }, + text: 'TypeA', + }, + parent_oid: -7630378659301899856n, + index: 5, + }, + { + oid: -8652599794525726394n, + kind: 234, + location: { + oid: 1505995205694275186n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 66, offset: 160 }, + end: { line: 8, column: 2, offset: 196 }, + text: '{\n console.log(a, b);\n return a;\n}', + }, + parent_oid: -7630378659301899856n, + index: 6, + }, + { + oid: -9059279700687764660n, + kind: 79, + location: { + oid: -7603929720754976545n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 10, column: 1, offset: 198 }, + end: { line: 10, column: 8, offset: 205 }, + text: 'greeter', + }, + parent_oid: 7989925055347479910n, + index: 0, + }, + { + oid: 3017513708303253096n, + kind: 79, + location: { + oid: -6597753323830715173n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 10, column: 9, offset: 206 }, + end: { line: 10, column: 23, offset: 220 }, + text: 'printToConsole', + }, + parent_oid: 7989925055347479910n, + index: 1, + }, + { + oid: 7989925055347479910n, + kind: 207, + location: { + oid: -3122855473939453161n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 10, column: 1, offset: 198 }, + end: { line: 10, column: 24, offset: 221 }, + text: 'greeter(printToConsole)', + }, + parent_oid: 7896790807836877485n, + index: 0, + }, + { + oid: -7680370939886111243n, + kind: 255, + location: { + oid: -2137023693457018946n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 3, column: 2, offset: 93 }, + text: "function greeter(fn: (a: TypeA, b: TypeB) => TypeA) {\n fn('Hello', 'World');\n}", + }, + name: 'greeter', + parent_oid: -6509463281345121482n, + index: 0, + }, + { + oid: -7630378659301899856n, + kind: 255, + location: { + oid: 7091344116805824541n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 5, column: 1, offset: 95 }, + end: { line: 8, column: 2, offset: 196 }, + text: 'function printToConsole(a: TypeA, b: TypeB): TypeA {\n console.log(a, b);\n return a;\n}', + }, + name: 'printToConsole', + parent_oid: -6509463281345121482n, + index: 1, + }, + { + oid: 7896790807836877485n, + kind: 237, + location: { + oid: 1097215747691428387n, + file: { + oid: 8515556148510554566n, + name: 'function.ts', + extension: '.ts', + relativePath: 'function.ts', + locationOid: -7138775249263850200n, + }, + start: { line: 10, column: 1, offset: 198 }, + end: { line: 10, column: 25, offset: 222 }, + text: 'greeter(printToConsole);', + }, + parent_oid: -6509463281345121482n, + index: 2, + }, +]; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/heritage-clause.ts b/language/javascript/extractor/src/__test__/core/expected-coref/heritage-clause.ts new file mode 100644 index 00000000..3563084a --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/heritage-clause.ts @@ -0,0 +1,443 @@ + + +export const heritageClauseNodes = [ + { + oid: -6393970903408236441n, + kind: 79, + location: { + oid: -2242885473958970924n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 2, column: 3, offset: 21 }, + end: { line: 2, column: 7, offset: 25 }, + text: 'name', + }, + parent_oid: -1027959748385657081n, + index: 0, + }, + { + oid: 728900584922189965n, + kind: 149, + location: { + oid: 747316934046317273n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 2, column: 9, offset: 27 }, + end: { line: 2, column: 15, offset: 33 }, + text: 'string', + }, + parent_oid: -1027959748385657081n, + index: 1, + }, + { + oid: -8461928733181809557n, + kind: 79, + location: { + oid: -5083168233150125922n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 1, column: 11, offset: 10 }, + end: { line: 1, column: 17, offset: 16 }, + text: 'Animal', + }, + parent_oid: -5481712956535062739n, + index: 0, + }, + { + oid: -1027959748385657081n, + kind: 165, + location: { + oid: -6606239372298372529n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 2, column: 3, offset: 21 }, + end: { line: 2, column: 16, offset: 34 }, + text: 'name: string;', + }, + parent_oid: -5481712956535062739n, + index: 1, + }, + { + oid: -2841117464709371051n, + kind: 79, + location: { + oid: -5062016880409412035n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 24, offset: 61 }, + end: { line: 5, column: 30, offset: 67 }, + text: 'Animal', + }, + parent_oid: -2328957270860662040n, + index: 0, + }, + { + oid: 4584300223942586319n, + kind: 94, + location: { + oid: 213784431369675660n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 16, offset: 53 }, + end: { line: 5, column: 23, offset: 60 }, + text: 'extends', + }, + parent_oid: -8679090301471196542n, + index: 0, + }, + { + oid: -2328957270860662040n, + kind: 227, + location: { + oid: -5062016880409412035n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 24, offset: 61 }, + end: { line: 5, column: 30, offset: 67 }, + text: 'Animal', + }, + parent_oid: -8679090301471196542n, + index: 1, + }, + { + oid: -5345443169734987945n, + kind: 79, + location: { + oid: -2714253665388631843n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 6, column: 3, offset: 72 }, + end: { line: 6, column: 8, offset: 77 }, + text: 'honey', + }, + parent_oid: -4912667345323779931n, + index: 0, + }, + { + oid: 2967571618219711057n, + kind: 133, + location: { + oid: 6387041363121391205n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 6, column: 10, offset: 79 }, + end: { line: 6, column: 17, offset: 86 }, + text: 'boolean', + }, + parent_oid: -4912667345323779931n, + index: 1, + }, + { + oid: 6702510511601859954n, + kind: 79, + location: { + oid: 5054160403158145152n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 11, offset: 48 }, + end: { line: 5, column: 15, offset: 52 }, + text: 'Bear', + }, + parent_oid: 6032638801610082441n, + index: 0, + }, + { + oid: -8679090301471196542n, + kind: 290, + location: { + oid: -5115746037842446713n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 16, offset: 53 }, + end: { line: 5, column: 30, offset: 67 }, + text: 'extends Animal', + }, + parent_oid: 6032638801610082441n, + index: 1, + }, + { + oid: -4912667345323779931n, + kind: 165, + location: { + oid: 6340085639743804516n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 6, column: 3, offset: 72 }, + end: { line: 6, column: 18, offset: 87 }, + text: 'honey: boolean;', + }, + parent_oid: 6032638801610082441n, + index: 2, + }, + { + oid: 8465736311936061825n, + kind: 79, + location: { + oid: -1248326512086569151n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 22, offset: 112 }, + end: { line: 9, column: 28, offset: 118 }, + text: 'Animal', + }, + parent_oid: -8399874988996655189n, + index: 0, + }, + { + oid: -1560734385902525087n, + kind: 117, + location: { + oid: -6949916864318260910n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 11, offset: 101 }, + end: { line: 9, column: 21, offset: 111 }, + text: 'implements', + }, + parent_oid: -7664430395663046677n, + index: 0, + }, + { + oid: -8399874988996655189n, + kind: 227, + location: { + oid: -1248326512086569151n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 22, offset: 112 }, + end: { line: 9, column: 28, offset: 118 }, + text: 'Animal', + }, + parent_oid: -7664430395663046677n, + index: 1, + }, + { + oid: 7249735031046781353n, + kind: 79, + location: { + oid: -6204501756675810329n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 10, column: 3, offset: 123 }, + end: { line: 10, column: 7, offset: 127 }, + text: 'name', + }, + parent_oid: -1232535619993953530n, + index: 0, + }, + { + oid: -5484637365474863201n, + kind: 10, + location: { + oid: 7978936308246177252n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 10, column: 10, offset: 130 }, + end: { line: 10, column: 15, offset: 135 }, + text: "'Cat'", + }, + value: 'Cat', + parent_oid: -1232535619993953530n, + index: 1, + }, + { + oid: -6707375136375193786n, + kind: 79, + location: { + oid: -6081973879873872143n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 7, offset: 97 }, + end: { line: 9, column: 10, offset: 100 }, + text: 'Cat', + }, + parent_oid: 4315688032718506582n, + index: 0, + }, + { + oid: -7664430395663046677n, + kind: 290, + location: { + oid: -897461146575408174n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 11, offset: 101 }, + end: { line: 9, column: 28, offset: 118 }, + text: 'implements Animal', + }, + parent_oid: 4315688032718506582n, + index: 1, + }, + { + oid: -1232535619993953530n, + kind: 166, + location: { + oid: 8760361100631246250n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 10, column: 3, offset: 123 }, + end: { line: 10, column: 16, offset: 136 }, + text: "name = 'Cat';", + }, + parent_oid: 4315688032718506582n, + index: 2, + }, + { + oid: -5481712956535062739n, + kind: 257, + location: { + oid: 5556394469566963394n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 3, column: 2, offset: 36 }, + text: 'interface Animal {\n name: string;\n}', + }, + parent_oid: 5209318333731122033n, + index: 0, + }, + { + oid: 6032638801610082441n, + kind: 257, + location: { + oid: 7720855009881864534n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 5, column: 1, offset: 38 }, + end: { line: 7, column: 2, offset: 89 }, + text: 'interface Bear extends Animal {\n honey: boolean;\n}', + }, + parent_oid: 5209318333731122033n, + index: 1, + }, + { + oid: 4315688032718506582n, + kind: 256, + location: { + oid: -1835252783442964569n, + file: { + oid: -6927688696414875654n, + name: 'heritage-clause.ts', + extension: '.ts', + relativePath: 'heritage-clause.ts', + locationOid: -2102036074626083496n, + }, + start: { line: 9, column: 1, offset: 91 }, + end: { line: 11, column: 2, offset: 138 }, + text: "class Cat implements Animal {\n name = 'Cat';\n}", + }, + name: 'Cat', + parent_oid: 5209318333731122033n, + index: 2, + }, +]; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/index.ts b/language/javascript/extractor/src/__test__/core/expected-coref/index.ts new file mode 100644 index 00000000..eb835534 --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/index.ts @@ -0,0 +1,9 @@ + + +export * from './binding-pattern'; +export * from './comment'; +export * from './for-statement'; +export * from './function'; +export * from './heritage-clause'; +export * from './meta-property'; +export * from './type-operator'; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/meta-property.ts b/language/javascript/extractor/src/__test__/core/expected-coref/meta-property.ts new file mode 100644 index 00000000..d911b485 --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/meta-property.ts @@ -0,0 +1,458 @@ + + +import { Coref } from '../../../model/coref'; + +export const metaPropertyCoref: Coref = { + topLevels: [ + { + oid: 5784071183677607882n, + kind: 0, + location: { + oid: -6543091812267392587n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 2, column: 1, offset: 17 }, + text: 'import.meta.url;\n', + }, + }, + ], + tokens: [ + { + oid: -7172402470642993085n, + kind: 100, + location: { + oid: 996756592627933966n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 7, offset: 6 }, + text: 'import', + }, + }, + { + oid: -2788496149465035573n, + kind: 24, + location: { + oid: 5484284360226258974n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 7, offset: 6 }, + end: { line: 1, column: 8, offset: 7 }, + text: '.', + }, + }, + { + oid: -6543968991563686950n, + kind: 79, + location: { + oid: -7972522156540880386n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 8, offset: 7 }, + end: { line: 1, column: 12, offset: 11 }, + text: 'meta', + }, + }, + { + oid: 6446379777316583661n, + kind: 24, + location: { + oid: 8089410590535081270n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 12, offset: 11 }, + end: { line: 1, column: 13, offset: 12 }, + text: '.', + }, + }, + { + oid: 7600795658279147985n, + kind: 79, + location: { + oid: 2656772003272749028n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 13, offset: 12 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'url', + }, + }, + { + oid: -501842068318998128n, + kind: 26, + location: { + oid: -5446367855011061545n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 16, offset: 15 }, + end: { line: 1, column: 17, offset: 16 }, + text: ';', + }, + }, + { + oid: -4761324340930236289n, + kind: 4, + location: { + oid: 289429249249168997n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 17, offset: 16 }, + end: { line: 2, column: 1, offset: 17 }, + text: '\n', + }, + }, + ], + comments: [], + nodes: [ + { + oid: -7172402470642993085n, + kind: 100, + location: { + oid: 996756592627933966n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 7, offset: 6 }, + text: 'import', + }, + parent_oid: -6571809455750521891n, + index: 0, + }, + { + oid: -6543968991563686950n, + kind: 79, + location: { + oid: -7972522156540880386n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 8, offset: 7 }, + end: { line: 1, column: 12, offset: 11 }, + text: 'meta', + }, + parent_oid: -6571809455750521891n, + index: 1, + }, + { + oid: -6571809455750521891n, + kind: 230, + location: { + oid: 771751750506473307n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 12, offset: 11 }, + text: 'import.meta', + }, + parent_oid: -2651729876839371063n, + index: 0, + }, + { + oid: 7600795658279147985n, + kind: 79, + location: { + oid: 2656772003272749028n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 13, offset: 12 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'url', + }, + parent_oid: -2651729876839371063n, + index: 1, + }, + { + oid: -2651729876839371063n, + kind: 205, + location: { + oid: 3617073062811199307n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'import.meta.url', + }, + parent_oid: 5229336219953697336n, + index: 0, + }, + { + oid: 5229336219953697336n, + kind: 237, + location: { + oid: 5747002746227836587n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 17, offset: 16 }, + text: 'import.meta.url;', + }, + parent_oid: 5784071183677607882n, + index: 0, + }, + ], + nodeComments: [], + bindingElements: [], + classLikeDeclarations: [], + functionLikeDeclarations: [], + functionEnclosingNodes: [], + literals: [], + modifiers: [], + cfgEntryNodes: [ + { + astNodeOid: 5784071183677607882n, + oid: 8098160335271270366n, + }, + ], + cfgExitNodes: [ + { + astNodeOid: 5784071183677607882n, + oid: -6505302337064541605n, + }, + ], + symbolMap: new Map([ + [ + 7831664003751408937n, + { oid: 7831664003751408937n, name: 'ImportMeta', description: '' }, + ], + [ + 1091345588120160621n, + { + oid: 1091345588120160621n, + name: 'url', + description: '(property) ImportMeta.url: string', + }, + ], + [ + 5784071183677607882n, + { + oid: 5784071183677607882n, + name: '"/Users/zhangyu/code/sparrow-cli/language/javascript/extractor/tests/ts/meta-property"', + description: + 'module "/Users/zhangyu/code/sparrow-cli/language/javascript/extractor/tests/ts/meta-property"', + }, + ], + ]), + nodeSymbolMap: new Map([ + [-6571809455750521891n, 7831664003751408937n], + [7600795658279147985n, 1091345588120160621n], + [-2651729876839371063n, 1091345588120160621n], + [5784071183677607882n, 5784071183677607882n], + ]), + callSiteMap: new Map(), + locations: [ + { + oid: -6543091812267392587n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 2, column: 1, offset: 17 }, + text: 'import.meta.url;\n', + }, + { + oid: 996756592627933966n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 7, offset: 6 }, + text: 'import', + }, + { + oid: -7972522156540880386n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 8, offset: 7 }, + end: { line: 1, column: 12, offset: 11 }, + text: 'meta', + }, + { + oid: 771751750506473307n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 12, offset: 11 }, + text: 'import.meta', + }, + { + oid: 2656772003272749028n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 13, offset: 12 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'url', + }, + { + oid: 3617073062811199307n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 16, offset: 15 }, + text: 'import.meta.url', + }, + { + oid: 5747002746227836587n, + file: { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 17, offset: 16 }, + text: 'import.meta.url;', + }, + ], + numbersOfLines: [ + { + locationOid: -6543091812267392587n, + lines: 2, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: 996756592627933966n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: -7972522156540880386n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: 771751750506473307n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: 2656772003272749028n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: 3617073062811199307n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + { + locationOid: 5747002746227836587n, + lines: 1, + codeLines: 1, + commentLines: 0, + }, + ], + files: [ + { + oid: 4506567840976601323n, + name: 'meta-property.ts', + extension: '.ts', + relativePath: 'meta-property.ts', + locationOid: -6543091812267392587n, + }, + ], +}; diff --git a/language/javascript/extractor/src/__test__/core/expected-coref/type-operator.ts b/language/javascript/extractor/src/__test__/core/expected-coref/type-operator.ts new file mode 100644 index 00000000..361a574b --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/expected-coref/type-operator.ts @@ -0,0 +1,291 @@ + + +import { Node } from '../../../model/coref'; + +export const typeOperatorNodes: Node[] = [ + { + oid: -991378629966383939n, + kind: 79, + location: { + oid: 770260757846408101n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 16, offset: 15 }, + end: { line: 1, column: 17, offset: 16 }, + text: 'x', + }, + parent_oid: 1891263938273629411n, + index: 0, + }, + { + oid: 8535225168082499623n, + kind: 146, + location: { + oid: 2679916970014127626n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 19, offset: 18 }, + end: { line: 1, column: 25, offset: 24 }, + text: 'number', + }, + parent_oid: 1891263938273629411n, + index: 1, + }, + { + oid: 443714168455559499n, + kind: 79, + location: { + oid: -5232716306128948926n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 27, offset: 26 }, + end: { line: 1, column: 28, offset: 27 }, + text: 'y', + }, + parent_oid: -6452873062317997071n, + index: 0, + }, + { + oid: 6110637335560534980n, + kind: 146, + location: { + oid: -7141822751961288969n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 30, offset: 29 }, + end: { line: 1, column: 36, offset: 35 }, + text: 'number', + }, + parent_oid: -6452873062317997071n, + index: 1, + }, + { + oid: 1891263938273629411n, + kind: 165, + location: { + oid: -500318406855226811n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 16, offset: 15 }, + end: { line: 1, column: 26, offset: 25 }, + text: 'x: number;', + }, + parent_oid: 4214811408948636644n, + index: 0, + }, + { + oid: -6452873062317997071n, + kind: 165, + location: { + oid: 3989305432470635713n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 27, offset: 26 }, + end: { line: 1, column: 36, offset: 35 }, + text: 'y: number', + }, + parent_oid: 4214811408948636644n, + index: 1, + }, + { + oid: 8426546122259581739n, + kind: 79, + location: { + oid: -3214272957191232719n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 6, offset: 5 }, + end: { line: 1, column: 11, offset: 10 }, + text: 'Point', + }, + parent_oid: 4986623752647102625n, + index: 0, + }, + { + oid: 4214811408948636644n, + kind: 181, + location: { + oid: -3888752825591456510n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 14, offset: 13 }, + end: { line: 1, column: 38, offset: 37 }, + text: '{ x: number; y: number }', + }, + parent_oid: 4986623752647102625n, + index: 1, + }, + { + oid: -4053818482475066652n, + kind: 79, + location: { + oid: 4638590487622463975n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 16, offset: 54 }, + end: { line: 2, column: 21, offset: 59 }, + text: 'Point', + }, + parent_oid: 5778966435001494756n, + index: 0, + }, + { + oid: 1387301563833670834n, + kind: 140, + location: { + oid: 7134353577249857984n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 10, offset: 48 }, + end: { line: 2, column: 15, offset: 53 }, + text: 'keyof', + }, + parent_oid: -2814869516003238219n, + index: 0, + }, + { + oid: 5778966435001494756n, + kind: 177, + location: { + oid: 4638590487622463975n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 16, offset: 54 }, + end: { line: 2, column: 21, offset: 59 }, + text: 'Point', + }, + parent_oid: -2814869516003238219n, + index: 1, + }, + { + oid: 4409746325726187520n, + kind: 79, + location: { + oid: -2440422142761778887n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 6, offset: 44 }, + end: { line: 2, column: 7, offset: 45 }, + text: 'P', + }, + parent_oid: -446872020703544099n, + index: 0, + }, + { + oid: -2814869516003238219n, + kind: 192, + location: { + oid: -253974365155189481n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 10, offset: 48 }, + end: { line: 2, column: 21, offset: 59 }, + text: 'keyof Point', + }, + parent_oid: -446872020703544099n, + index: 1, + }, + { + oid: 4986623752647102625n, + kind: 258, + location: { + oid: 8702952269692439970n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 1, column: 1, offset: 0 }, + end: { line: 1, column: 39, offset: 38 }, + text: 'type Point = { x: number; y: number };', + }, + parent_oid: 1640330227723813817n, + index: 0, + }, + { + oid: -446872020703544099n, + kind: 258, + location: { + oid: -7279172199373383799n, + file: { + oid: 6417363707865698013n, + name: 'type-operator.ts', + extension: '.ts', + relativePath: 'type-operator.ts', + locationOid: -53717676214473002n, + }, + start: { line: 2, column: 1, offset: 39 }, + end: { line: 2, column: 22, offset: 60 }, + text: 'type P = keyof Point;', + }, + parent_oid: 1640330227723813817n, + index: 1, + }, +]; diff --git a/language/javascript/extractor/src/__test__/core/index.test.ts b/language/javascript/extractor/src/__test__/core/index.test.ts new file mode 100644 index 00000000..1035bbeb --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/index.test.ts @@ -0,0 +1,110 @@ + + +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import * as path from 'path'; +import * as ts from 'typescript'; + +import * as expectedCoref from './expected-coref'; +import { extractFile } from '../../core/extractor'; +import { compilerOptions } from '../../core/extract-manager'; +import { Coref } from '../../model/coref'; + +/** + * 用于生成测试用例的结果 + * + * @param object 原始对象 + * @returns 处理了 bigint 类型的 JSON 格式字符串 + */ +function generateExpectedObject(object: any): string { + function replacer(key: string, value: any) { + if (typeof value === 'bigint') { + return value.toString() + 'n'; + } else if (value instanceof Map) { + return Array.from(value.entries()); + } else { + return value; + } + } + + return JSON.stringify(object, replacer).replace(/"-?\d+n"/g, match => + match.slice(1, -1), + ); +} + +/** + * 根据测试文件路径抽取文件 + * + * @param filePath 测试文件路径 + * @returns 抽取的 Coref 数据 + */ +function extractTestFile(filePath: string): Coref | undefined { + const program = ts.createProgram([filePath], compilerOptions); + // 使用 getTypeChecker 确保 Node 中的属性都初始化 + program.getTypeChecker(); + const sourceFile = program.getSourceFile(filePath); + + return extractFile(sourceFile as ts.SourceFile, program); +} + +describe(extractFile, () => { + const rootPath = path.dirname(path.dirname(path.dirname(__dirname))); + + test('extractFile-meta-property', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'meta-property.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData).toEqual(expectedCoref.metaPropertyCoref); + }); + + test('extractFile-type-operator', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'type-operator.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.nodes).toEqual(expectedCoref.typeOperatorNodes); + }); + + test('extractFile-heritage-clause', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'heritage-clause.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.nodes).toEqual(expectedCoref.heritageClauseNodes); + }); + + test('extractFile-function', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'function.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.callSiteMap).toEqual(expectedCoref.callSiteMap); + expect(corefData?.functionEnclosingNodes).toEqual( + expectedCoref.functionFunctionEnclosingNodes, + ); + expect(corefData?.nodes).toEqual(expectedCoref.functionNodes); + }); + + test('extractFile-for-statement', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'for-statement.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.nodes).toEqual(expectedCoref.forStatementNodes); + }); + + test('extractFile-binding-pattern', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'binding-pattern.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.nodes).toEqual(expectedCoref.bindingPatternNodes); + }); + + test('extractFile-comment', () => { + const filePath = path.join(rootPath, 'tests', 'ts', 'comment.ts'); + const corefData = extractTestFile(filePath); + + expect(corefData?.comments).toEqual(expectedCoref.commentCoref.comments); + expect(corefData?.nodes).toEqual(expectedCoref.commentCoref.nodes); + expect(corefData?.nodeComments).toEqual( + expectedCoref.commentCoref.nodeComments, + ); + }); +}); diff --git a/language/javascript/extractor/src/__test__/core/util.test.ts b/language/javascript/extractor/src/__test__/core/util.test.ts new file mode 100644 index 00000000..9775a2cc --- /dev/null +++ b/language/javascript/extractor/src/__test__/core/util.test.ts @@ -0,0 +1,31 @@ +import * as ts from 'typescript'; +import { + isKeywordSyntaxKind, + isCommentSyntaxKind, + isJsOrTsFile, +} from '../../core/util'; + +describe(isKeywordSyntaxKind, () => { + test('isKeywordSyntaxKind', () => { + expect(isKeywordSyntaxKind(ts.SyntaxKind.FirstKeyword)).toBeTruthy(); + expect(isKeywordSyntaxKind(ts.SyntaxKind.LastKeyword)).toBeTruthy(); + expect(isKeywordSyntaxKind(ts.SyntaxKind.AsyncKeyword)).toBeTruthy(); + }); +}); + +describe(isCommentSyntaxKind, () => { + test('isCommentSyntaxKind', () => { + expect( + isCommentSyntaxKind(ts.SyntaxKind.SingleLineCommentTrivia), + ).toBeTruthy(); + expect(isCommentSyntaxKind(ts.SyntaxKind.AsyncKeyword)).toBeFalsy(); + }); +}); + +describe(isJsOrTsFile, () => { + test('isJsOrTsFile', () => { + expect(isJsOrTsFile('.ts')).toBeTruthy(); + expect(isJsOrTsFile('.jsx')).toBeTruthy(); + expect(isJsOrTsFile('.java')).toBeFalsy(); + }); +}); diff --git a/language/javascript/extractor/src/__test__/util.test.ts b/language/javascript/extractor/src/__test__/util.test.ts new file mode 100644 index 00000000..5e0dfbff --- /dev/null +++ b/language/javascript/extractor/src/__test__/util.test.ts @@ -0,0 +1,8 @@ +import { hashToInt64 } from '../util'; + +describe(hashToInt64, () => { + test('hashToInt64', () => { + expect(hashToInt64('test')).toBe(2975348720976108454n); + expect(hashToInt64('jest')).toBe(-7710744583274308193n); + }); +}); diff --git a/language/javascript/extractor/src/core/extract-manager.ts b/language/javascript/extractor/src/core/extract-manager.ts new file mode 100644 index 00000000..eaf7f9cb --- /dev/null +++ b/language/javascript/extractor/src/core/extract-manager.ts @@ -0,0 +1,500 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; + +import { range } from 'lodash'; +import * as shell from 'shelljs'; +import { Pool, Worker, spawn } from 'threads'; +import * as ts from 'typescript'; + +import * as framework from './framework'; +import * as extractor from './extractor'; +import * as util from './util'; +import * as dal from '../dal/db'; +import { createPrismaClient } from '../dal/db/prisma-client'; +import { coref, extendedTs } from '../model'; +import { version } from '../../package.json'; + +// Default DB file name +export const DEFAULT_DB_FILE_NAME = 'coref_javascript_src.db'; + +export const compilerOptions: ts.CompilerOptions = { + allowJs: true, + experimentalDecorators: true, + experimentalAsyncFunctions: true, + jsx: ts.JsxEmit.Preserve, + noResolve: true, + allowNonTsExtensions: true +}; + +const DEFAULT_BLACKLIST = ['.git']; + +const CUSTOM_HANDLE_FILE_EXTENSIONS = [".ets"]; + +interface ExtractOptions { + blacklist?: string[]; + useGitignore?: boolean; + extractDist?: boolean; + extractDeps?: boolean; + fileSizeLimit?: number; +} + +/** + * Init ignore functions + * + * @param extractedPath + * @param options + * @returns + */ +function initIgnoreFunctions( + extractedPath: string, + options?: ExtractOptions, +): ((fileOrDirPath: string) => coref.IgnoredPath | null)[] { + const ignoreFunctions = []; + + // use blacklist to ignore files + let blacklist = DEFAULT_BLACKLIST; + if (options?.blacklist) { + blacklist = blacklist.concat(options.blacklist); + } + // TODO: Load or download dependencies if they don't exist. + if (!options?.extractDeps) { + blacklist.push('node_modules'); + } + + if (blacklist.length > 0) { + ignoreFunctions.push( + util.createIgnoreFunctionByBlacklist(extractedPath, blacklist), + ); + } + + if (options?.useGitignore) { + // use ".gitignore" to ignore files + // TODO: most repos only have one ".gitignore" in the root directory, thus currently only the root ".gitignore" is used. + // However, there may be more than one ".gitignore". + // ref:https://git-scm.com/docs/gitignore + const gitignorePath = path.join(extractedPath, '.gitignore'); + ignoreFunctions.push(util.createIgnoreFunctionByGitignore(gitignorePath)); + } + + if (!options?.extractDist) { + // ignore files for distribution or minified files + ignoreFunctions.push(util.distIgnoreFunction); + } + + // ignore super big files + ignoreFunctions.push( + util.createFileSizeIgnoreFunction(options?.fileSizeLimit), + ); + + return ignoreFunctions; +} + +export async function extract( + extractedPath: string, + dbPath: string, + options?: ExtractOptions, +) { + let rootPath = path.dirname(path.dirname(require.main?.filename as string)); + // 编译为 js 后代码在 dist 目录下,因此项目根目录是 dist 的父目录 + if (path.basename(rootPath) === 'dist') { + rootPath = path.dirname(rootPath); + } + + // dbPath 默认为工作目录下的 coref_js_src.db + if (!dbPath) { + dbPath = DEFAULT_DB_FILE_NAME; + } + dbPath = path.resolve(dbPath); + + if (!fs.existsSync(extractedPath)) { + console.error("The extracted path doesn't exist."); + process.exit(1); + } + extractedPath = path.resolve(extractedPath); + + const initDbPath = path.join(rootPath, 'init.db'); + + // Create the directory of db file if it doesn't exist. + const dbDirPath = path.dirname(dbPath); + const mkdirReturnValue = shell.mkdir('-p', dbDirPath); + if (mkdirReturnValue.code !== 0) { + console.error(mkdirReturnValue.stderr); + console.error(`Cannot create db file directory: ${dbDirPath}`); + process.exit(1); + } + + const cpReturnValue = shell.cp(initDbPath, dbPath); + if (cpReturnValue.code !== 0) { + console.error(cpReturnValue.stderr); + console.error(`Cannot create sqlite db file: ${dbPath}`); + process.exit(1); + } + + const prismaClient = createPrismaClient(dbPath); + + // ATTENTION: Write data with prisma in the main thread first to avoid data racing + // when loading the prisma native addon by pkg. + await dal.createMetadata(prismaClient, { + oid: 0n, + version, + created_time: new Date(), + }); + + // Due to the limitation of IO, higher concurrency does not necessarily improve performance. + // The highest concurrency is set to 6. + const cpuCount = os.cpus().length; + const threadCount = cpuCount < 6 ? cpuCount : 6; + + const tmpDbDirPath = path.join(dbDirPath, 'tmp'); + const mkTmpDbdirReturnValue = shell.mkdir('-p', tmpDbDirPath); + if (mkTmpDbdirReturnValue.code !== 0) { + console.error(mkdirReturnValue.stderr); + console.error(`Cannot create tmp db file directory: ${tmpDbDirPath}`); + process.exit(1); + } + + const tmpDbPaths = range(0, threadCount).map(id => + path.join(tmpDbDirPath, `${id}.db`), + ); + + // Initialize all workers first, + // since lazy initialization may cause timeout when spawning threads. + const workers = await Promise.all( + range(0, threadCount).map(async i => { + const tmpDbPath = tmpDbPaths[i]; + const worker = await spawn(new Worker('./worker')); + // A worker can only be used after initializing the prisma client + await fs.promises.copyFile(initDbPath, tmpDbPath); + await worker.initPrismaClient(tmpDbPath); + return worker; + }), + ); + + /** + * Create the spawn-worker function + * + * @returns the spawn-worker function + */ + function createSpawnWorkerFunction() { + let i = 0; + return async () => workers[i++]; + } + + // Pool size must be the same with the count of tmp db files. + const pool = Pool(createSpawnWorkerFunction(), threadCount); + + const extractedPathStat = fs.statSync(extractedPath); + let extractedFilePaths: string[] = []; + let ignoredPaths: coref.IgnoredPath[] = []; + let projectPath: string | undefined; + if (extractedPathStat.isDirectory()) { + try { + let fileExtensions: string[] = Object.values(ts.Extension).concat(CUSTOM_HANDLE_FILE_EXTENSIONS); + const ignoreFunctions = initIgnoreFunctions(extractedPath, options); + ({ filePaths: extractedFilePaths, ignoredPaths } = util.listAllFiles( + extractedPath, + /*extensions*/ fileExtensions, + ignoreFunctions, + )); + } catch (e) { + console.error(e); + console.error( + `Fail to list files in the extracted directory: ${extractedPath}`, + ); + process.exit(1); + } + + const ignoredPathCreations = dal.createIgnoredPaths( + prismaClient, + ignoredPaths, + ); + await dal.transaction(prismaClient, ignoredPathCreations); + + projectPath = extractedPath; + } else { + extractedFilePaths = [extractedPath]; + projectPath = undefined; + } + + const program = ts.createProgram(extractedFilePaths, compilerOptions); + // 使用 getTypeChecker 确保 Node 中的属性都初始化 + program.getTypeChecker(); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + // let creations: PrismaPromise[] = []; + const projectSymbolOidSet = new Set(); + const projectNodeSymbolOidSet = new Set(); + const projectCallSiteOidSet = new Set(); + + function extractFileTask( + filePath: string, + enabledFrameworkExtractors: framework.FrameworkExtractorBase[], + ): dal.Coref | undefined { + let dalCoref: dal.Coref | undefined; + + const sourceFile = program.getSourceFile(filePath) as extendedTs.SourceFile; + if (!sourceFile) { + return dalCoref; + } + + console.log(`Extracting ${filePath}...`); + + let success = true; + try { + const corefData = extractor.extractFile(sourceFile, program, projectPath); + const frameworkCorefData = extractor.extractFileFrameworks( + enabledFrameworkExtractors, + sourceFile, + program, + projectPath, + ); + + // creations 中加入抽取本文件后所有的数据创建,等达到一定数量后一起提交 + // const corefCreations = dal.createCoref(prismaClient, corefData); + + // Collect new symbols + const symbols: coref.Symbol[] = []; + const symbolMap = new Map([ + ...corefData.symbolMap, + ...frameworkCorefData.symbolMap, + ]); + symbolMap.forEach((symbol, oid) => { + if (!projectSymbolOidSet.has(oid)) { + symbols.push(symbol); + projectSymbolOidSet.add(oid); + } + }); + + const nodeSymbolMap = new Map( + [ + ...corefData.nodeSymbolMap, + ...frameworkCorefData.nodeSymbolMap, + ].filter( + // No need to update projectNodeSymbolOidSet, + // since the node_oids in the nodeSymbolMaps of different files wouldn't be duplicate. + ([node_oid]) => !projectNodeSymbolOidSet.has(node_oid), + ), + ); + + const callSiteMap = new Map( + [...corefData.callSiteMap, ...frameworkCorefData.callSiteMap].filter( + // No need to update projectCallSiteOidSet, + // since the invoke_expression_oid in the callSiteMaps of different files wouldn't be duplicate. + ([invoke_expression_oid]) => + !projectCallSiteOidSet.has(invoke_expression_oid), + ), + ); + + dalCoref = { + topLevels: corefData.topLevels.map(topLevel => ({ + oid: topLevel.oid, + kind: topLevel.kind, + location_oid: topLevel.location.oid, + })), + nodes: corefData.nodes.map(node => ({ + oid: node.oid, + kind: node.kind, + parent_oid: node.parent_oid as bigint, + index: node.index as number, + location_oid: node.location.oid, + })), + comments: corefData.comments.map(comment => ({ + oid: comment.oid, + kind: comment.commentKind, + location_oid: comment.location.oid, + })), + nodeComments: corefData.nodeComments.map(nodeComment => ({ + oid: nodeComment.oid, + node_oid: nodeComment.nodeOid, + comment_oid: nodeComment.commentOid, + type: nodeComment.type, + })), + bindingElementPropertyNames: corefData.bindingElements + .filter( + bindingElement => bindingElement.propertyNameOid !== undefined, + ) + .map(bindingElement => ({ + oid: bindingElement.oid, + property_name_oid: bindingElement.propertyNameOid as bigint, + })), + bindingElementNames: corefData.bindingElements.map(bindingElement => ({ + oid: bindingElement.oid, + name_oid: bindingElement.nameOid, + })), + bindingElementInitializers: corefData.bindingElements + .filter(bindingElement => bindingElement.initializerOid !== undefined) + .map(bindingElement => ({ + oid: bindingElement.oid, + initializer_oid: bindingElement.initializerOid as bigint, + })), + classLikeDeclarations: corefData.classLikeDeclarations.map( + classLikeDeclaration => ({ + oid: classLikeDeclaration.oid, + kind: classLikeDeclaration.kind, + name: classLikeDeclaration.name as string, + }), + ), + functionLikeDeclarations: corefData.functionLikeDeclarations.map( + functionLikeDeclaration => ({ + oid: functionLikeDeclaration.oid, + kind: functionLikeDeclaration.kind, + name: functionLikeDeclaration.name as string, + }), + ), + functionEnclosingNodes: corefData.functionEnclosingNodes.map( + functionEnclosingNode => ({ + node_oid: functionEnclosingNode.nodeOid, + function_oid: functionEnclosingNode.functionOid, + }), + ), + literals: corefData.literals.map(literal => ({ + oid: literal.oid, + value: literal.value, + })), + modifiers: corefData.modifiers.map(modifier => ({ + oid: modifier.oid, + index: modifier.modifierIndex, + })), + cfgEntryNodes: corefData.cfgEntryNodes.map(({ oid, astNodeOid }) => ({ + oid, + ast_node_oid: astNodeOid, + })), + cfgExitNodes: corefData.cfgExitNodes.map(({ oid, astNodeOid }) => ({ + oid, + ast_node_oid: astNodeOid, + })), + locations: corefData.locations.map(location => ({ + oid: location.oid, + file_oid: location.file.oid, + start_line_number: location.start.line, + start_column_number: location.start.column, + end_line_number: location.end.line, + end_column_number: location.end.column, + text: location.text, + })), + files: corefData.files.map(file => ({ + oid: file.oid, + name: file.name, + extension: file.extension, + relative_path: file.relativePath, + location_oid: file.locationOid as bigint, + })), + numbersOfLines: corefData.numbersOfLines.map(numberOfLines => ({ + location_oid: numberOfLines.locationOid, + lines: numberOfLines.lines, + code_lines: numberOfLines.codeLines, + comment_lines: numberOfLines.commentLines, + })), + symbols, + nodeSymbols: Array.from(nodeSymbolMap.entries()).map( + ([node_oid, symbol_oid]) => ({ node_oid, symbol_oid }), + ), + shorthandAssignmentValueSymbols: Array.from( + corefData.shorthandAssignmentValueSymbolMap.entries(), + ).map(([node_oid, symbol_oid]) => ({ node_oid, symbol_oid })), + callSites: Array.from(callSiteMap.entries()).map( + ([invoke_expression_oid, callee_oid]) => ({ + invoke_expression_oid, + callee_oid, + }), + ), + }; + } catch (e) { + console.error(e); + success = false; + } + + if (success) { + console.log(`Finished ${filePath}`); + } else { + console.error(`Fail to extract ${filePath}`); + } + + return dalCoref; + } + + const enabledFrameworkExtractors = projectPath + ? await framework.getEnabledFrameworkExtractors( + framework.frameworkExtractors, + projectPath, + ) + : []; + + let projectDalCoref: dal.Coref | undefined; + + // Extract project COREF from frameworks. + if (projectPath && enabledFrameworkExtractors) { + const frameworkCoref = extractor.extractProjectFrameworks( + enabledFrameworkExtractors, + program, + projectPath, + ); + + if (frameworkCoref) { + for (const oid of frameworkCoref.symbolMap.keys()) { + projectSymbolOidSet.add(oid); + } + for (const node_oid of frameworkCoref.nodeSymbolMap.keys()) { + projectNodeSymbolOidSet.add(node_oid); + } + for (const invoke_expression_oid of frameworkCoref.callSiteMap.keys()) { + projectCallSiteOidSet.add(invoke_expression_oid); + } + + projectDalCoref = { + symbols: Array.from(frameworkCoref.symbolMap.values()), + nodeSymbols: Array.from(frameworkCoref.nodeSymbolMap.entries()).map( + ([node_oid, symbol_oid]) => ({ node_oid, symbol_oid }), + ), + callSites: Array.from(frameworkCoref.callSiteMap.entries()).map( + ([invoke_expression_oid, callee_oid]) => ({ + invoke_expression_oid, + callee_oid, + }), + ), + }; + } + } + + const executingTasks: Promise[] = []; + + async function submitPersistTasks(dalCoref: dal.Coref | undefined) { + const splitCorefs = dalCoref ? dal.splitCoref(dalCoref) : []; + for (const splitCoref of splitCorefs) { + while (executingTasks.length >= threadCount) { + await Promise.race(executingTasks); + } + + const task = pool.queue(worker => { + return worker.persistCoref(splitCoref); + }); + executingTasks.push(task as any); + task.then(() => + executingTasks.splice(executingTasks.indexOf(task as any), 1), + ); + } + } + + if (projectDalCoref) { + await submitPersistTasks(projectDalCoref); + } + + for (const filePath of extractedFilePaths) { + const dalCoref = extractFileTask(filePath, enabledFrameworkExtractors); + await submitPersistTasks(dalCoref); + } + + await pool.settled(true); + await pool.terminate(); + + // Merge db files + console.log('Merging db files...'); + for (const tmpDbPath of tmpDbPaths) { + await dal.mergeDb(prismaClient, tmpDbPath); + } + + // Remove the tmp db directory + await fs.promises.rm(tmpDbDirPath, { recursive: true, force: true }); +} diff --git a/language/javascript/extractor/src/core/extractor.ts b/language/javascript/extractor/src/core/extractor.ts new file mode 100644 index 00000000..6225cd5d --- /dev/null +++ b/language/javascript/extractor/src/core/extractor.ts @@ -0,0 +1,917 @@ + + +import * as path from 'path'; + +import { range } from 'lodash'; +import * as ts from 'typescript'; + +import * as framework from './framework'; +import * as util from './util'; +import { coref, extendedTs } from '../model'; + +export const compilerOptions: ts.CompilerOptions = { + allowJs: true, + experimentalDecorators: true, + experimentalAsyncFunctions: true, + jsx: ts.JsxEmit.Preserve, + noResolve: true, +}; + +// Default DB file name +export const DEFAULT_DB_FILE_NAME = 'coref_javascript_src.db'; + +type ReScanFunction = () => ts.SyntaxKind; + +interface ReScanItem { + pos: number; + callback: ReScanFunction; +} + +/** + * 抽取 Tokens 和 Comments + * 因为抽取的 AST 中 不包含 Tokens 和 Comments 信息,因此需要使用 Scanner 重新解析代码来抽取 + * + * @param tsSourceFile + */ +function extractTokensAndComments(tsSourceFile: extendedTs.SourceFile) { + const code = tsSourceFile.text; + const scanner = ts.createScanner( + ts.ScriptTarget.Latest, + /*skipTrivia*/ false, + ts.LanguageVariant.JSX, + code, + ); + const reScanGreaterToken: ReScanFunction = + scanner.reScanGreaterToken.bind(scanner); + const reScanSlashToken: ReScanFunction = + scanner.reScanSlashToken.bind(scanner); + const reScanTemplateToken: ReScanFunction = scanner.reScanTemplateToken.bind( + scanner, + ) as ReScanFunction; + + const reScanItems: ReScanItem[] = []; + + if ( + !tsSourceFile.parseDiagnostics || + tsSourceFile.parseDiagnostics.length === 0 + ) { + util.forEachNode(tsSourceFile, node => { + if (util.shouldReScanGreaterThanToken(node)) { + reScanItems.push({ + pos: node.getStart(tsSourceFile, false), + callback: reScanGreaterToken, + }); + } else if (util.shouldReScanSlashToken(node)) { + reScanItems.push({ + pos: node.getStart(tsSourceFile, false), + callback: reScanSlashToken, + }); + } else if (util.shouldReScanTemplateToken(node)) { + reScanItems.push({ + pos: node.getStart(tsSourceFile, false), + callback: reScanTemplateToken, + }); + } + }); + } + + const tokens: coref.Token[] = []; + const comments: coref.Comment[] = []; + const locationMap = new Map(); + + let tokenSyntaxKind: ts.SyntaxKind; + let reScanItemIndex = 0; + do { + tokenSyntaxKind = scanner.scan(); + if (scanner.getTokenPos() === reScanItems[reScanItemIndex]?.pos) { + reScanItems[reScanItemIndex].callback(); + reScanItemIndex++; + } + + const startPos = scanner.getTokenPos(); + const text = scanner.getTokenText(); + const width = text.length; + const endPos = startPos + width; + + // skip broken token + if (width === 0) { + continue; + } + + const location = util.createLocationByPosition( + tsSourceFile, + startPos, + endPos, + text, + ); + + // 暂时只将 comment 入库,只记录 comment 的 location 到 locationMap + if (util.isCommentSyntaxKind(tokenSyntaxKind)) { + // 处理 comments + const comment = coref.createComment( + tokenSyntaxKind as coref.CommentSyntaxKind, + location, + ); + comments.push(comment); + + locationMap.set(location.oid, location); + } else if (ts.isTokenKind(tokenSyntaxKind)) { + // 处理 tokens,除了 comments ( comments 也属于 tokens ) + const token = coref.createToken( + tokenSyntaxKind as ts.TokenSyntaxKind, + location, + ); + tokens.push(token); + } + } while (tokenSyntaxKind !== ts.SyntaxKind.EndOfFileToken); + + return { + tokens, + comments, + locationMap, + }; +} + +/** + * 访问 sourceFile 节点,并返回对应的 TopLevel 对象 + * + * @param tsSourceFile + * @returns TopLevel 对象 + */ +function visitTopLevel(tsSourceFile: extendedTs.SourceFile): coref.TopLevel { + return util.ensureCorefAstNode(tsSourceFile) as coref.TopLevel; +} + +/** + * 处理普通节点的子节点,记录子节点的父节点,index 等信息 + * 按子节点顺序记录 index + * + * @param tsNode 父节点 + * @returns 子节点数组 + */ +function processCommonChildNodes(tsNode: extendedTs.Node): coref.Node[] { + const node = util.ensureCorefAstNode(tsNode); + + let index = 0; + const childNodes: coref.Node[] = []; + util.forEachChild(tsNode, (childTsNode: extendedTs.Node) => { + const childNode = childTsNode.$corefModel as coref.Node; + childNode.parent_oid = node.oid; + childNode.index = index; + childNodes.push(childNode); + index++; + }); + + return childNodes; +} + +/** + * 收集 COREF 子节点 + * 如果该子节点存在,则保存到 childNodes 中 + * + * @param childNodes COREF 子节点数组 + * @param tsNode extendedTs 子节点 + * @param extra_desc 子节点额外的信息 + * @returns + */ +function collectChildNodes( + childNodes: coref.Node[], + tsNode: extendedTs.Node | undefined, + extra_desc: { parent_oid: bigint; index: number }, +) { + const node = tsNode?.$corefModel as coref.Node | undefined; + if (node) { + childNodes.push({ ...node, ...extra_desc }); + } + + return childNodes; +} + +/** + * 处理 ForStatement 的子节点,记录子节点的父节点,index 等信息 + * 4 种子节点 initializer, condition, incrementor 和 statement 的 index 固定为 0, 1, 2, 3, + * 以便在 Godel 库中可以区分。 + * + * @param tsForStatement + * @returns + */ +function processForStatementChildNodes( + tsForStatement: extendedTs.ForStatement, +): coref.Node[] { + const node = util.ensureCorefAstNode(tsForStatement); + + const childNodes: coref.Node[] = []; + + collectChildNodes(childNodes, tsForStatement.initializer, { + parent_oid: node.oid, + index: 0, + }); + collectChildNodes(childNodes, tsForStatement.condition, { + parent_oid: node.oid, + index: 1, + }); + collectChildNodes(childNodes, tsForStatement.incrementor, { + parent_oid: node.oid, + index: 2, + }); + collectChildNodes(childNodes, tsForStatement.statement, { + parent_oid: node.oid, + index: 3, + }); + + return childNodes; +} + +/** + * 访问一个 AST Node 节点,记录其所有子节点与之的父子关系,并返回全部子节点 + * + * @param tsNode AST Node 节点,增加了自定义属性的 ts.Node 对象 + * @returns 该节点所有直接子节点对应的 COREF 对象 + */ +function visitNode(tsNode: extendedTs.Node): coref.Node[] { + switch (tsNode.kind) { + case ts.SyntaxKind.ForStatement: + return processForStatementChildNodes(tsNode as extendedTs.ForStatement); + default: + return processCommonChildNodes(tsNode); + } +} + +/** + * 访问 ClassLikeDeclaration 节点,返回对应的 COREF 对象 + * + * @param tsClassLikeDeclaration extendedTs.ClassLikeDeclaration 节点,增加了自定义属性的 ts.ClassLikeDeclaration 对象 + * @returns COREF ClassLikeDeclaration 对象 + * + * @todo 处理 classLikeDeclaration 的 members, modifiers, heritageClauses, decorators, typeParameters 等 + */ +function visitClassLikeDeclaration( + tsClassLikeDeclaration: extendedTs.ClassLikeDeclaration, +): coref.ClassLikeDeclaration { + const classLikeDeclaration = util.ensureCorefAstNode( + tsClassLikeDeclaration, + ) as coref.ClassLikeDeclaration; + classLikeDeclaration.name = tsClassLikeDeclaration.name?.text || ''; + return classLikeDeclaration; +} + +/** + * 访问 FunctionLikeDeclaration 节点,返回对应的 COREF 对象 + * @param tsFunctionLikeDeclaration extendedTs.FunctionLikeDeclaration 节点,增加了自定义属性的 ts.FunctionLikeDeclaration 对象 + * @returns COREF FunctionLikeDeclaration 对象 + * + * @todo 处理除了 name,其他的 FunctionLikeDeclaration 的属性 + */ +function visitFunctionLikeDeclaration( + tsFunctionLikeDeclaration: extendedTs.FunctionLikeDeclaration, +) { + const functionLikeDeclaration = util.ensureCorefAstNode( + tsFunctionLikeDeclaration, + ) as coref.FunctionLikeDeclaration; + + switch (functionLikeDeclaration.kind) { + case ts.SyntaxKind.FunctionDeclaration: + functionLikeDeclaration.name = + (tsFunctionLikeDeclaration as extendedTs.FunctionDeclaration).name + ?.text || ''; + break; + case ts.SyntaxKind.Constructor: + functionLikeDeclaration.name = ''; + break; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + functionLikeDeclaration.name = ( + tsFunctionLikeDeclaration as + | extendedTs.MethodDeclaration + | extendedTs.GetAccessorDeclaration + | extendedTs.SetAccessorDeclaration + ).name.getText(); + break; + case ts.SyntaxKind.FunctionExpression: + functionLikeDeclaration.name = + (tsFunctionLikeDeclaration as extendedTs.FunctionExpression).name + ?.text || ''; + break; + case ts.SyntaxKind.ArrowFunction: + functionLikeDeclaration.name = ''; + break; + } + + const functionEnclosingNodes: coref.FunctionEnclosingNode[] = []; + // 不遍历 tsFunctionLikeDeclaration 本身 + util.forEachChild(tsFunctionLikeDeclaration, childNode => { + util.forEachNode( + childNode, + (tsNode: extendedTs.Node) => { + const node = util.ensureCorefAstNode(tsNode); + functionEnclosingNodes.push({ + nodeOid: node.oid, + functionOid: functionLikeDeclaration.oid, + }); + + if (util.isFunctionLikeDeclaration(tsNode)) { + // 不再遍历 FunctionLikeDeclaration 的子节点 + return false; + } + }, + /*childFirst*/ false, + ); + }); + + return { + functionLikeDeclaration, + functionEnclosingNodes, + }; +} + +function visitMayInvokeExpression( + program: ts.Program, + mayInvokeExpression: extendedTs.MayInvokeExpression, + projectPath?: string, +): coref.CallSite | undefined { + const callee = util.getCallee(program, mayInvokeExpression); + + function createCallSite( + caller: extendedTs.Node, + callee: extendedTs.Node, + ): coref.CallSite { + const corefCaller = util.ensureCorefAstNode(caller); + const calleeSourceFile = callee.getSourceFile(); + // 初始化 callee 所在的 sourceFile 对应的 COREF file + util.ensureCorefFile( + calleeSourceFile as extendedTs.SourceFile, + projectPath, + ); + const corefCallee = util.ensureCorefAstNode(callee); + return coref.createCallSite( + corefCaller as coref.Node, + corefCallee as coref.Node, + ); + } + + let isValidCallSite = false; + if (callee) { + const calleeFileName = callee.getSourceFile().fileName; + if (projectPath == undefined) { + // 抽取单文件 + if (calleeFileName === mayInvokeExpression.getSourceFile().fileName) { + // 只抽取调用本文件函数的 call site + isValidCallSite = true; + } + } else { + // 抽取项目 + if (calleeFileName.startsWith(projectPath + path.sep)) { + // 只抽取调用本项目函数的 call site + isValidCallSite = true; + } + } + } + + return isValidCallSite + ? createCallSite(mayInvokeExpression, callee as util.Callee) + : undefined; +} + +/** + * 抽取节点与注释的关系 + * + * @todo 目前有一种特殊情况没有抽取:一行行内的多行注释,而且该注释不在所在行的开头或结尾。 + * 原因是,通过 typescript API (ts.getLeadingCommentRanges 和 ts.getTrailingCommentRanges) + * 获取 AST 节点与注释的关系,这种特殊类型的注释会关联到一些只有语法意义的 Token 节点上 + * (如 PunctuationToken标点符号, keyword 等),后续应把注释关联到他们前后更有意义的节点上, + * 如 Identifier,Expression等。 + * + * @param tsNode TsNode 节点,增加了自定义属性的 ts.Node 对象 + * @returns 节点与注释关系的 NodeComment 数组 + */ +function visitNodeComments(tsNode: extendedTs.Node): coref.NodeComment[] { + const sourceFile = tsNode.getSourceFile(); + const node = tsNode.$corefModel as coref.Node; + const leadingCommentRanges = util.getLeadingCommentRangesOfNode( + tsNode, + sourceFile, + ); + const trailingCommentRanges = util.getTrailingCommentRangesOfNode( + tsNode, + sourceFile, + ); + const nodeComments: coref.NodeComment[] = []; + + /** + * 根据 ts.CommentRange 和 NodeCommentType 创建 NodeComment 对象 + * + * @param commentRange ts.CommentRange 对象 + * @param nodeCommentType 节点注释关联类型 NodeCommentType.LEADING 或 NodeCommentType.TRAILING + * @returns NodeComment 对象 + */ + function createNodeComment( + commentRange: ts.CommentRange, + nodeCommentType: coref.NodeCommentType, + ): coref.NodeComment { + const commentStartPos = commentRange.pos; + const commentEndPos = commentRange.end; + const commentText = sourceFile.text.substring( + commentStartPos, + commentEndPos, + ); + const commentLocation = util.createLocationByPosition( + sourceFile, + commentStartPos, + commentEndPos, + commentText, + ); + const commentOid = coref.computeNodeOid(commentRange.kind, commentLocation); + return coref.createNodeComment(node.oid, commentOid, nodeCommentType); + } + + leadingCommentRanges?.forEach(commentRange => { + const nodeComment = createNodeComment( + commentRange, + coref.NodeCommentType.LEADING, + ); + nodeComments.push(nodeComment); + }); + + trailingCommentRanges?.forEach(commentRange => { + const nodeComment = createNodeComment( + commentRange, + coref.NodeCommentType.TRAILING, + ); + nodeComments.push(nodeComment); + }); + + return nodeComments; +} + +/** + * 访问 TypeScript literal-like node + * @param literalLikeNode literal-like node + * @returns 该 literal-like node 对应的 coref.Literal 对象 + */ +function visitLiteralLikeNode(literalLikeNode: extendedTs.Node): coref.Literal { + const literal = literalLikeNode.$corefModel as coref.Literal; + + /** + * 如果 literal 的值中存在未成对的 UTF-16 代理对(Surrogate Pair)范围的字符, + * 则这些字符是非法字符,不对应任何 Unicode 标准中的字符,插入数据库时会报错,需保存转译后的值 + */ + + /** + * 找到单独出现代理字符的正则表达式, + * 即后面没有 [\uDC00-\uDFFF] 的 [\uD800-\uDBFF] , + * 或前面没有 [\uD800-\uDBFF] 的 [\uDC00-\uDFFF] + */ + const singleSurrogateRegex = + /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(? { + const modifier = (tsModifier as extendedTs.Modifier).$corefModel; + modifier.modifierIndex = modifierIndex; + return modifier; + }) + : []; +} + +/** + * 抽取 AST 节点数据 + * + * @param tsSourceFile + * @returns 一个 SourceFile 中 AST 相关的数据 + */ +function extractAstNodes(tsSourceFile: extendedTs.SourceFile) { + let nodes: coref.Node[] = []; + let nodeComments: coref.NodeComment[] = []; + const bindingElements: coref.BindingElement[] = []; + const classLikeDeclarations: coref.ClassLikeDeclaration[] = []; + const functionLikeDeclarations: coref.FunctionLikeDeclaration[] = []; + let functionEnclosingNodes: coref.FunctionEnclosingNode[] = []; + const topLevel = visitTopLevel(tsSourceFile); + const literals: coref.Literal[] = []; + let modifiers: coref.Modifier[] = []; + const cfgEntryNodes: coref.SyntheticCfgNode[] = [ + coref.createCfgEntryNode(topLevel.oid), + ]; + const cfgExitNodes: coref.SyntheticCfgNode[] = [ + coref.createCfgExitNode(topLevel.oid), + ]; + + util.forEachNode(tsSourceFile, (tsNode: extendedTs.Node) => { + const childNodes = visitNode(tsNode); + nodes = nodes.concat(childNodes); + + const currentNodeComments = visitNodeComments(tsNode); + nodeComments = nodeComments.concat(currentNodeComments); + + if (tsNode.kind === ts.SyntaxKind.BindingElement) { + bindingElements.push( + extractBindingElement(tsNode as extendedTs.BindingElement), + ); + } else if (ts.isClassLike(tsNode)) { + const classLikeDeclaration = visitClassLikeDeclaration(tsNode); + classLikeDeclarations.push(classLikeDeclaration); + } else if (ts.isFunctionLike(tsNode)) { + if (util.isFunctionLikeDeclaration(tsNode)) { + const { + functionLikeDeclaration, + functionEnclosingNodes: currentFunctionEnclosingNodes, + } = visitFunctionLikeDeclaration(tsNode); + functionEnclosingNodes = functionEnclosingNodes.concat( + currentFunctionEnclosingNodes, + ); + functionLikeDeclarations.push(functionLikeDeclaration); + + cfgEntryNodes.push( + coref.createCfgEntryNode(functionLikeDeclaration.oid), + ); + cfgExitNodes.push(coref.createCfgExitNode(functionLikeDeclaration.oid)); + } + } else if (util.isLiteralLikeNode(tsNode)) { + const literal = visitLiteralLikeNode(tsNode); + literals.push(literal); + } + + if (util.canHaveModifiers(tsNode)) { + const extractedModifiers = extractModifiers(tsNode); + if (extractedModifiers.length > 0) { + modifiers = modifiers.concat(extractedModifiers); + } + } + }); + + const locationMap = new Map(); + // TopLevel 的范围不包含文件开头的注释,因此其 location 信息需要单独记录 + locationMap.set(topLevel.location.oid, topLevel.location); + nodes.forEach(node => { + const location = node.location; + locationMap.set(location.oid, location); + }); + + return { + topLevel, + nodes, + nodeComments, + bindingElements, + classLikeDeclarations, + functionLikeDeclarations, + functionEnclosingNodes, + literals, + modifiers, + cfgEntryNodes, + cfgExitNodes, + locationMap, + }; +} + +/** + * Extract symbols and node symbol relations + * + * @param tsSourceFile + * @param projectPath + * @returns { symbolMap, nodeSymbols } + */ +function extractSymbols( + tsSourceFile: extendedTs.SourceFile, + typeChecker: ts.TypeChecker, + projectPath?: string | undefined, +) { + const symbolMap = new Map(); + const nodeSymbolMap = new Map(); + const shorthandAssignmentValueSymbolMap = new Map(); + + util.forEachNode(tsSourceFile, (tsNode: extendedTs.Node) => { + const symbol = util.createSymbol(tsNode, typeChecker, projectPath); + if (symbol === undefined) { + return; + } + + symbolMap.set(symbol.oid, symbol); + nodeSymbolMap.set((tsNode.$corefModel as coref.Node).oid, symbol.oid); + + if (tsNode.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { + const valueSymbolOid = util.getShortHandAssignmentValueSymbolOid( + tsNode, + typeChecker, + projectPath, + ); + if (valueSymbolOid !== undefined) { + shorthandAssignmentValueSymbolMap.set( + (tsNode.$corefModel as coref.Node).oid, + valueSymbolOid, + ); + } + } + }); + + return { + symbolMap, + nodeSymbolMap, + shorthandAssignmentValueSymbolMap, + }; +} + +/** + * Extract call sites and the corresponding callees + */ +function extractCallSites( + program: ts.Program, + tsSourceFile: extendedTs.SourceFile, + projectPath?: string | undefined, +) { + const callSiteMap = new Map(); + + util.forEachNode(tsSourceFile, (tsNode: extendedTs.Node) => { + if (util.isMayInvokeExpression(tsNode)) { + const callSite = visitMayInvokeExpression( + program, + tsNode as extendedTs.MayInvokeExpression, + projectPath, + ); + if (callSite) { + callSiteMap.set(callSite.invokeExpression.oid, callSite.callee.oid); + } + } + }); + + return callSiteMap; +} + +/** + * 抽取每个 Location 对应的行数,代码行数和注释行数 + * + * @param tokens + * @param comments + * @param locations + * @returns NumberOfLines 对象数组 + */ +function extractNumberOfLines( + tokens: coref.Token[], + comments: coref.Comment[], + locations: coref.Location[], +): coref.NumberOfLines[] { + const numberOfLinesArray: coref.NumberOfLines[] = []; + const codeLineSet = new Set(); + const commentLineSet = new Set(); + + // 使用 tokens 统计代码行数,因为上层的 AST node 可能包含一整行的内容只存在非代码的 Token + for (const token of tokens) { + // 非代码的 Token + if (util.isNonCodeTokenSyntaxKind(token.kind)) { + continue; + } + + // 除了非代码的Token,如果一行存在 Token,则认为该行为代码行 + const startLine = token.location.start.line; + const endLine = token.location.end.line; + range(startLine, endLine + 1).forEach(value => { + codeLineSet.add(value); + }); + } + + // 使用 comments 统计代码行数,如果一行存在 comment,则认为该行为注释行 + for (const comment of comments) { + const startLine = comment.location.start.line; + const endLine = comment.location.end.line; + range(startLine, endLine + 1).forEach(value => { + commentLineSet.add(value); + }); + } + + for (const location of locations) { + const startLine = location.start.line; + const endLine = location.end.line; + + const lines = endLine - startLine + 1; + + const codeLines = range(startLine, endLine + 1).reduce( + (previousValue, currentValue) => { + return codeLineSet.has(currentValue) + ? previousValue + 1 + : previousValue; + }, + 0, + ); + + const commentLines = range(startLine, endLine + 1).reduce( + (previousValue, currentValue) => { + return commentLineSet.has(currentValue) + ? previousValue + 1 + : previousValue; + }, + 0, + ); + + numberOfLinesArray.push({ + locationOid: location.oid, + lines, + codeLines, + commentLines, + }); + } + + return numberOfLinesArray; +} + +/** + * 抽取一个文件的信息 + * + * @param program + * @param filePath + * @param projectPath + * @returns 该文件的 Coref 数据 + */ +export function extractFile( + sourceFile: extendedTs.SourceFile, + program: ts.Program, + projectPath?: string | undefined, +): coref.Coref { + const relativePath = util.getRelativePath(sourceFile.fileName, projectPath); + + sourceFile.$file = coref.createFile(relativePath); + + const { + tokens, + comments, + locationMap: tokenLocationMap, + } = extractTokensAndComments(sourceFile); + + const { + topLevel, + nodes, + nodeComments, + bindingElements, + classLikeDeclarations, + functionLikeDeclarations, + functionEnclosingNodes, + literals, + modifiers, + cfgEntryNodes, + cfgExitNodes, + locationMap: astLocationMap, + } = extractAstNodes(sourceFile); + const topLevels: coref.TopLevel[] = [topLevel]; + + const { symbolMap, nodeSymbolMap, shorthandAssignmentValueSymbolMap } = + extractSymbols(sourceFile, program.getTypeChecker(), projectPath); + + const callSiteMap = extractCallSites(program, sourceFile, projectPath); + + const locationMap = new Map([...tokenLocationMap, ...astLocationMap]); + + // 增加文件对应的 Location + const fileLocation = util.createLocationByPosition( + sourceFile, + 0, + sourceFile.end, + sourceFile.text, + ); + (sourceFile.$file as coref.File).locationOid = fileLocation.oid; + locationMap.set(fileLocation.oid, fileLocation); + + const locations = Array.from(locationMap.values()); + + const numberOfLinesArray = extractNumberOfLines(tokens, comments, locations); + + return { + topLevels, + tokens, + comments, + nodes, + nodeComments, + bindingElements, + classLikeDeclarations, + functionLikeDeclarations, + functionEnclosingNodes, + literals, + modifiers, + cfgEntryNodes, + cfgExitNodes, + symbolMap, + nodeSymbolMap, + shorthandAssignmentValueSymbolMap, + callSiteMap, + locations, + numbersOfLines: numberOfLinesArray, + files: [sourceFile.$file], + }; +} + +/** + * Extract framework coref data of the project + * + * @param program + * @param projectPath + * @returns the project framework COREF + */ +export function extractProjectFrameworks( + enabledFrameworkExtractors: framework.FrameworkExtractorBase[], + program: ts.Program, + projectPath: string, +): coref.CrossFileCoref { + let symbolMap = new Map(); + let nodeSymbolMap = new Map(); + let callSiteMap = new Map(); + + for (const extractor of enabledFrameworkExtractors) { + console.log(`Extracting framework COREF: ${extractor.name}`); + + if (extractor.extractProjectCoref) { + const frameworkCoref = extractor.extractProjectCoref( + program, + projectPath, + ); + symbolMap = new Map([...symbolMap, ...frameworkCoref.symbolMap]); + nodeSymbolMap = new Map([ + ...nodeSymbolMap, + ...frameworkCoref.nodeSymbolMap, + ]); + callSiteMap = new Map([...callSiteMap, ...frameworkCoref.callSiteMap]); + } + } + + return { + symbolMap, + nodeSymbolMap, + callSiteMap, + }; +} + +/** + * Extract the framework coref data of a file + * + * @param enabledFrameworkExtractors + * @param tsSourceFile + * @param program + * @param projectPath + * @returns the file framework COREF + */ +export function extractFileFrameworks( + enabledFrameworkExtractors: framework.FrameworkExtractorBase[], + tsSourceFile: extendedTs.SourceFile, + program: ts.Program, + projectPath: string | undefined, +): coref.CrossFileCoref { + let symbolMap = new Map(); + let nodeSymbolMap = new Map(); + let callSiteMap = new Map(); + + for (const extractor of enabledFrameworkExtractors) { + if (extractor.extractFileCoref) { + const { + symbolMap: frameworkSymbolMap, + nodeSymbolMap: frameworkNodeSymbolMap, + callSiteMap: frameworkCallSiteMap, + } = extractor.extractFileCoref(tsSourceFile, program, projectPath); + + symbolMap = new Map([...symbolMap, ...frameworkSymbolMap]); + nodeSymbolMap = new Map([...nodeSymbolMap, ...frameworkNodeSymbolMap]); + callSiteMap = new Map([...callSiteMap, ...frameworkCallSiteMap]); + } + } + + return { + symbolMap, + nodeSymbolMap, + callSiteMap, + }; +} diff --git a/language/javascript/extractor/src/core/framework/chair.ts b/language/javascript/extractor/src/core/framework/chair.ts new file mode 100644 index 00000000..b18f126b --- /dev/null +++ b/language/javascript/extractor/src/core/framework/chair.ts @@ -0,0 +1,690 @@ +import * as path from 'path'; + +import * as ts from 'typescript'; +import type { PackageJson } from 'type-fest'; +import { camelCase } from 'lodash'; + +import { FrameworkCoref, FrameworkExtractorBase } from './type'; +import { coref, extendedTs } from '../../model'; +import * as util from '../util'; + +/** + * Get router SourceFiles + * + * @param program + * @param projectPath + * @returns + */ +function getRouterSourceFiles( + program: ts.Program, + projectPath: string, +): ts.SourceFile[] { + return program + .getSourceFiles() + .filter( + x => + path + .relative(projectPath, x.fileName) + .match(/^app\/router(\.[jt]s|\/.+\.[jt]s)$/g) !== null, + ); +} + +/** + * Get a map of controller qualified module name and corresponding ts SourceFile + * @param program + * @param projectPath + * @returns + */ +function getControllerModuleSourceFileMap( + program: ts.Program, + projectPath: string, +): Map { + const controllerPathPrefixes = ['app/controller/', 'app/controllers/'].map( + x => path.join(projectPath, x), + ); + + function convertControllerPathToModule(filePath: string): string { + const relativePath = path.relative(projectPath, filePath); + const pathParts = relativePath.split('.')[0].split('/').slice(2); + return pathParts.map(x => camelCase(x)).join('.'); + } + + const controllerModuleSourceFiles = program + .getSourceFiles() + .map(sourceFile => ({ path: sourceFile.fileName, sourceFile })) + .filter(x => + controllerPathPrefixes.some(prefix => x.path.startsWith(prefix)), + ) + .map(x => ({ + module: convertControllerPathToModule(x.path), + sourceFile: x.sourceFile, + })); + + return new Map( + controllerModuleSourceFiles.map(x => [x.module, x.sourceFile]), + ); +} + +/** + * Get a map of service qualified module name and corresponding ts SourceFile + * + * @param program + * @param projectPath + * @returns + */ +function getServiceModuleSourceFileMap( + program: ts.Program, + projectPath: string, +): Map { + const servicePathPrefix = path.join(projectPath, 'app/service/'); + + function convertServicePathToModule(filePath: string): string { + const relativePath = path.relative(projectPath, filePath); + const pathParts = relativePath.split('.')[0].split('/').slice(2); + return pathParts.map(x => camelCase(x)).join('.'); + } + + const serviceModuleSourceFiles = program + .getSourceFiles() + .map(sourceFile => ({ path: sourceFile.fileName, sourceFile })) + .filter(x => x.path.startsWith(servicePathPrefix)) + .map(x => ({ + module: convertServicePathToModule(x.path), + sourceFile: x.sourceFile, + })); + + return new Map(serviceModuleSourceFiles.map(x => [x.module, x.sourceFile])); +} + +function extractRouterSymbols( + routerSourceFile: ts.SourceFile, + typeChecker: ts.TypeChecker, + controllerModuleSourceFileMap: Map, + projectPath: string, +): { + symbolMap: Map; + nodeSymbolMap: Map; +} { + const symbolMap = new Map(); + const nodeSymbolMap = new Map(); + + // The router method names that may use controller functions. + // Therefore, `redirect` is not included in the array. + const routerMethodNames = [ + // HTTP + 'head', + 'get', + 'put', + 'post', + 'patch', + 'delete', + 'del', + 'options', + 'all', + // RPC + 'rpc', + 'rpcAndGet', + 'rpcAndPost', + ]; + + util.ensureCorefFile(routerSourceFile, projectPath); + util.forEachNode(routerSourceFile, (tsNode: extendedTs.Node) => { + if (!ts.isCallExpression(tsNode)) { + return; + } + + const expression = tsNode.expression; + const routerMethodName = util.isAccessExpression(expression) + ? util.getAccessExpressionPropertyName(expression) + : undefined; + + // Process router methods that may use controller functions. + if (!(routerMethodName && routerMethodNames.includes(routerMethodName))) { + return; + } + + const routerArguments = tsNode.arguments; + const lastArgument = routerArguments[routerArguments.length - 1]; + if (!lastArgument) { + return; + } + + let funcQualifiedName: string | undefined = undefined; + if (util.isAccessExpression(lastArgument)) { + const accessExpressionText = util.getAccessExpressionText(lastArgument); + const re = /(app\.)?controller\.(.+)/; + funcQualifiedName = accessExpressionText.match(re)?.[2]; + } else if (ts.isStringLiteral(lastArgument)) { + funcQualifiedName = lastArgument.text; + } + + if (!funcQualifiedName) { + return; + } + + let symbol: coref.Symbol | undefined; + + if (controllerModuleSourceFileMap.has(funcQualifiedName)) { + // router use the module default function (function qualified name === module qualified name) + const controllerSourceFile = + controllerModuleSourceFileMap.get(funcQualifiedName); + + controllerSourceFile?.forEachChild((childNode: ts.Node) => { + switch (childNode.kind) { + case ts.SyntaxKind.ExportAssignment: { + // export default xxx; + const exportExpression = (childNode as ts.ExportAssignment) + .expression; + symbol = util.createSymbol( + exportExpression, + typeChecker, + projectPath, + ); + break; + } + case ts.SyntaxKind.FunctionDeclaration: { + // export default function xxx() {...} + const modifiers = childNode.modifiers; + if ( + modifiers?.[0].kind === ts.SyntaxKind.ExportKeyword && + modifiers?.[1].kind === ts.SyntaxKind.DefaultKeyword + ) { + symbol = util.createSymbol(childNode, typeChecker, projectPath); + } + break; + } + case ts.SyntaxKind.ExpressionStatement: { + // module.exports = xxx + const binaryExpression = (childNode as ts.ExpressionStatement) + .expression as ts.BinaryExpression; + if ( + binaryExpression?.operatorToken?.kind !== + ts.SyntaxKind.EqualsToken + ) { + return; + } + + const leftExpression = binaryExpression?.left; + const accessExpressionText = + util.getAccessExpressionText(leftExpression); + if (accessExpressionText !== 'module.exports') { + return; + } + + const funcNode = binaryExpression.right; + symbol = util.createSymbol(funcNode, typeChecker, projectPath); + + break; + } + } + }); + } else { + // function qualified name !== module qualified name + const nameParts = funcQualifiedName.split('.'); + const moduleQualifiedName = nameParts.slice(0, -1).join('.'); + + if (controllerModuleSourceFileMap.has(moduleQualifiedName)) { + const funcName = nameParts[nameParts.length - 1]; + const controllerSourceFile = + controllerModuleSourceFileMap.get(moduleQualifiedName); + controllerSourceFile?.forEachChild((childNode: ts.Node) => { + // TODO: other style controller functions + if (ts.isExpressionStatement(childNode)) { + const binaryExpression = + childNode.expression as ts.BinaryExpression; + if ( + binaryExpression?.operatorToken?.kind !== + ts.SyntaxKind.EqualsToken + ) { + return; + } + + const leftExpression = binaryExpression.left; + + if (!util.isAccessExpression(leftExpression)) { + return; + } + + const accessExpressionLeftText = + leftExpression.expression.getText(controllerSourceFile); + if (accessExpressionLeftText === 'exports') { + // exports.xxx = xx + // xx might be a function expression, arrow function, or function identifier + + const exportsPropName = + util.getAccessExpressionPropertyName(leftExpression); + if (exportsPropName !== funcName) { + return; + } + + const funcNode = binaryExpression.right; + symbol = util.createSymbol(funcNode, typeChecker, projectPath); + } else if ( + accessExpressionLeftText === 'module' && + util.getAccessExpressionPropertyName(leftExpression) === 'exports' + ) { + // module.exports = xxx + // xxx might be a class expression or class identifier + const rightNode = binaryExpression.right; + const classLikeDeclaration = util.getClassOfExpression( + rightNode, + typeChecker, + ); + + if (classLikeDeclaration !== undefined) { + symbol = createClassMemberSymbolByName( + classLikeDeclaration, + funcName, + typeChecker, + projectPath, + ); + } + } + } else if (ts.isClassDeclaration(childNode)) { + // export default class xxx {} + if (!util.isExportDefaultDeclaration(childNode)) { + return; + } + + symbol = createClassMemberSymbolByName( + childNode as ts.ClassDeclaration, + funcName, + typeChecker, + projectPath, + ); + } + }); + } + } + + if (symbol !== undefined) { + const corefNode = util.ensureCorefAstNode(lastArgument); + symbolMap.set(symbol.oid, symbol); + nodeSymbolMap.set(corefNode.oid, symbol.oid); + + if (util.isAccessExpression(lastArgument)) { + const funcIdentifierNode = + util.getAccessExpressionPropertyNode(lastArgument); + const funcIdentifierCorefNode = + util.ensureCorefAstNode(funcIdentifierNode); + nodeSymbolMap.set(funcIdentifierCorefNode.oid, symbol.oid); + } + } + }); + + return { + symbolMap, + nodeSymbolMap, + }; +} + +function createClassMemberSymbolByName( + classLikeDeclaration: ts.ClassLikeDeclaration, + funcName: string, + typeChecker: ts.TypeChecker, + projectPath: string, +) { + const member = util.getClassMemberByName(classLikeDeclaration, funcName); + return member + ? util.createSymbol(member, typeChecker, projectPath) + : undefined; +} + +interface ServiceAccessExpressionInfo { + accessExpression: ts.AccessExpression; + serviceModuleQualifiedName: string; + functionName: string; + serviceSourceFile: ts.SourceFile; +} + +/** + * Get service access expression information. + * + * @param sourceFile + * @param serviceModuleSourceFileMap + * @returns + */ +function getServiceAccessExpressionInfos( + sourceFile: ts.SourceFile, + serviceModuleSourceFileMap: Map, +) { + const re = /^(this\.|ctx\.|this\.ctx\.)?service\.(.+)$/; + const serviceAccessExpressionInfos: ServiceAccessExpressionInfo[] = []; + util.forEachNode(sourceFile, (node: ts.Node) => { + if ( + !util.isAccessExpression(node) || + util.isAccessExpression(node.parent) + ) { + return; + } + + const propertyAccessText = util.getAccessExpressionText(node); + const matchArray = propertyAccessText.match(re); + const serviceFuncQualifiedName = matchArray?.[2]; + if (!serviceFuncQualifiedName) { + return; + } + + const nameParts = serviceFuncQualifiedName.split('.'); + const serviceModuleQualifiedName = nameParts.slice(0, -1).join('.'); + if (!serviceModuleSourceFileMap.has(serviceModuleQualifiedName)) { + return; + } + + const functionName = nameParts[nameParts.length - 1]; + const serviceSourceFile = serviceModuleSourceFileMap.get( + serviceModuleQualifiedName, + ) as ts.SourceFile; + + serviceAccessExpressionInfos.push({ + accessExpression: node, + serviceModuleQualifiedName, + functionName, + serviceSourceFile, + }); + }); + + return serviceAccessExpressionInfos; +} + +/** + * Extract the COREF for a service property access by the specified service class + * + * @param serviceAccessExpressionInfo + * @param serviceClass + * @param typeChecker + * @param projectPath + * @returns + */ +function extractServiceAccessCorefByServiceClass( + serviceAccessExpressionInfo: ServiceAccessExpressionInfo, + serviceClass: ts.ClassLikeDeclaration, + typeChecker: ts.TypeChecker, + projectPath: string, +): { + symbol: coref.Symbol | undefined; + nodeSymbols: coref.NodeSymbol[]; + callSite: coref.CallSite | undefined; +} { + const { accessExpression, functionName } = serviceAccessExpressionInfo; + const member = util.getClassMemberByName(serviceClass, functionName); + const tsSymbol = member && util.getSymbol(member, typeChecker); + const declaration = tsSymbol && util.getSymbolDeclaration(tsSymbol); + + // Symbol + const symbol = + tsSymbol && + util.createSymbolFromTsSymbol(tsSymbol, typeChecker, projectPath); + const nodeSymbols: coref.NodeSymbol[] = symbol + ? [ + { + node: util.ensureCorefAstNode( + util.getAccessExpressionPropertyNode(accessExpression), + ) as coref.Node, + symbol, + }, + { + node: util.ensureCorefAstNode(accessExpression) as coref.Node, + symbol, + }, + ] + : []; + + // Call site + let callSite: coref.CallSite | undefined; + // TODO: getter and setter + const corefInvokeExpression = ts.isCallLikeExpression(accessExpression.parent) + ? (util.ensureCorefAstNode(accessExpression.parent) as coref.Node) + : undefined; + if (corefInvokeExpression && declaration) { + if (ts.isMethodDeclaration(declaration)) { + callSite = { + invokeExpression: corefInvokeExpression, + callee: util.ensureCorefAstNode(declaration) as coref.Node, + }; + } else if (ts.isPropertyDeclaration(declaration)) { + const functionNode = declaration.initializer; + if ( + functionNode && + (ts.isFunctionExpression(functionNode) || + ts.isArrowFunction(functionNode)) + ) { + callSite = { + invokeExpression: corefInvokeExpression, + callee: util.ensureCorefAstNode(functionNode) as coref.Node, + }; + } + } + } + + return { + symbol, + nodeSymbols, + callSite, + }; +} + +/** + * Get the service class from the expression. + * + * @param expression + * @param typeChecker + * @returns + */ +function getServiceClass( + expression: ts.Expression, + typeChecker: ts.TypeChecker, +) { + // Resolve service class from the expression + const classLikeDeclaration = util.getClassOfExpression( + expression, + typeChecker, + ); + + if (classLikeDeclaration) { + return classLikeDeclaration; + } + + // Resolve service class from return value of the default function + const functionLikeDeclaration = util.getFunctionOfExpression( + expression, + typeChecker, + ); + + return ( + functionLikeDeclaration && + functionLikeDeclaration.body?.forEachChild(funcChildNode => { + if (ts.isReturnStatement(funcChildNode)) { + const returnExpression = funcChildNode.expression; + // console.log(typeChecker.getSymbolAtLocation(returnExpression as ts.Node)); + return returnExpression + ? util.getClassOfExpression(returnExpression, typeChecker) + : undefined; + } + }) + ); +} + +/** + * Extract the COREF for a service property access. + * + * @param serviceAccessExpressionInfo + * @param typeChecker + * @param projectPath + * @returns + */ +function extractServiceAccessCoref( + serviceAccessExpressionInfo: ServiceAccessExpressionInfo, + typeChecker: ts.TypeChecker, + projectPath: string, +): { + symbol: coref.Symbol | undefined; + nodeSymbols: coref.NodeSymbol[]; + callSite: coref.CallSite | undefined; +} { + const result = serviceAccessExpressionInfo.serviceSourceFile.forEachChild( + topNode => { + if (ts.isExpressionStatement(topNode)) { + // module.exports = xxxClass + const expression = topNode.expression; + if (util.isModuleExportsAssignExpression(expression)) { + const serviceClass = getServiceClass( + (expression as ts.BinaryExpression).right, + typeChecker, + ); + return ( + serviceClass && + extractServiceAccessCorefByServiceClass( + serviceAccessExpressionInfo, + serviceClass, + typeChecker, + projectPath, + ) + ); + } + } else if (ts.isExportAssignment(topNode)) { + // export default xxxClass; + const expression = topNode.expression; + const serviceClass = getServiceClass(expression, typeChecker); + return ( + serviceClass && + extractServiceAccessCorefByServiceClass( + serviceAccessExpressionInfo, + serviceClass, + typeChecker, + projectPath, + ) + ); + } else if (ts.isClassDeclaration(topNode)) { + // export default class xxx {} + if (util.isExportDefaultDeclaration(topNode)) { + return extractServiceAccessCorefByServiceClass( + serviceAccessExpressionInfo, + topNode, + typeChecker, + projectPath, + ); + } + } + }, + ); + + return ( + result ?? { + symbol: undefined, + nodeSymbols: [], + callSite: undefined, + } + ); +} + +export interface ChairExtractor extends FrameworkExtractorBase { + controllerModuleSourceFileMap?: Map; + serviceModuleSourceFileMap?: Map; +} + +export const chairExtractor: ChairExtractor = { + name: 'chair', + + detectByPackageJson(packageJson: PackageJson): boolean { + return Object.prototype.hasOwnProperty.call( + packageJson?.dependencies ?? {}, + 'chair', + ); + }, + + /** + * Extract chair symbols + * + * @param program + * @param projectPath + * @returns + */ + extractProjectCoref(program, projectPath?): FrameworkCoref { + const symbolMap = new Map(); + const nodeSymbolMap = new Map(); + const callSiteMap = new Map(); + + const chairCoref = { + symbolMap, + nodeSymbolMap, + callSiteMap, + }; + + if (!projectPath) { + return chairCoref; + } + + const routerSourceFiles = getRouterSourceFiles(program, projectPath); + const controllerModuleSourceFileMap = getControllerModuleSourceFileMap( + program, + projectPath, + ); + + routerSourceFiles.forEach(routerSourceFile => { + const result = extractRouterSymbols( + routerSourceFile, + program.getTypeChecker(), + controllerModuleSourceFileMap, + projectPath, + ); + for (const [oid, symbol] of result.symbolMap.entries()) { + symbolMap.set(oid, symbol); + } + for (const [node_oid, symbol_oid] of result.nodeSymbolMap.entries()) { + nodeSymbolMap.set(node_oid, symbol_oid); + } + }); + + return chairCoref; + }, + + extractFileCoref(sourceFile, program, projectPath?): FrameworkCoref { + const symbolMap = new Map(); + const nodeSymbolMap = new Map(); + const callSiteMap = new Map(); + const chairCoref = { + symbolMap, + nodeSymbolMap, + callSiteMap, + }; + + if (!projectPath) { + return chairCoref; + } + + if (!this.serviceModuleSourceFileMap) { + this.serviceModuleSourceFileMap = getServiceModuleSourceFileMap( + program, + projectPath, + ); + } + + const typeChecker = program.getTypeChecker(); + const serviceAccessExpressionInfos = getServiceAccessExpressionInfos( + sourceFile, + this.serviceModuleSourceFileMap, + ); + serviceAccessExpressionInfos.forEach(serviceAccessExpressionInfo => { + const { symbol, nodeSymbols, callSite } = extractServiceAccessCoref( + serviceAccessExpressionInfo, + typeChecker, + projectPath, + ); + + if (symbol) { + symbolMap.set(symbol.oid, symbol); + } + + nodeSymbols.forEach(nodeSymbol => { + nodeSymbolMap.set(nodeSymbol.node.oid, nodeSymbol.symbol.oid); + }); + + if (callSite) { + callSiteMap.set(callSite.invokeExpression.oid, callSite.callee.oid); + } + }); + + return chairCoref; + }, +}; diff --git a/language/javascript/extractor/src/core/framework/index.ts b/language/javascript/extractor/src/core/framework/index.ts new file mode 100644 index 00000000..ea0ab525 --- /dev/null +++ b/language/javascript/extractor/src/core/framework/index.ts @@ -0,0 +1,6 @@ +import { chairExtractor } from './chair'; +import { FrameworkExtractorBase } from './type'; +export { FrameworkCoref, FrameworkExtractorBase } from './type'; +export { getEnabledFrameworkExtractors } from './util'; + +export const frameworkExtractors: FrameworkExtractorBase[] = [chairExtractor]; diff --git a/language/javascript/extractor/src/core/framework/type.ts b/language/javascript/extractor/src/core/framework/type.ts new file mode 100644 index 00000000..6baa792f --- /dev/null +++ b/language/javascript/extractor/src/core/framework/type.ts @@ -0,0 +1,26 @@ +import * as ts from 'typescript'; +import { PackageJson } from 'type-fest'; +import { coref, extendedTs } from '../../model'; + +export interface FrameworkCoref { + symbolMap: Map; + nodeSymbolMap: Map; + callSiteMap: Map; +} + +export interface FrameworkExtractorBase { + name: string; + + detectByPackageJson(packageJson: PackageJson): boolean; + + extractProjectCoref?( + program: ts.Program, + projectPath?: string, + ): FrameworkCoref; + + extractFileCoref?( + sourceFile: extendedTs.SourceFile, + program: ts.Program, + projectPath?: string | undefined, + ): FrameworkCoref; +} diff --git a/language/javascript/extractor/src/core/framework/util.ts b/language/javascript/extractor/src/core/framework/util.ts new file mode 100644 index 00000000..4d01d7cc --- /dev/null +++ b/language/javascript/extractor/src/core/framework/util.ts @@ -0,0 +1,30 @@ +import * as path from 'path'; + +import type { PackageJson } from 'type-fest'; + +import { FrameworkExtractorBase } from './type'; + +/** + * Get enabled framework extractors + * + * @param frameworkExtractors + * @param projectPath + * @returns + */ +export async function getEnabledFrameworkExtractors( + frameworkExtractors: FrameworkExtractorBase[], + projectPath: string, +): Promise { + const packageJsonPath = path.join(projectPath, 'package.json'); + let packageJson: PackageJson | undefined; + try { + packageJson = await import(packageJsonPath); + } catch (e) { + console.log(`Could not find "package.json": ${packageJsonPath}.`); + return []; + } + + return frameworkExtractors.filter(extractor => + packageJson ? extractor.detectByPackageJson(packageJson) : false, + ); +} diff --git a/language/javascript/extractor/src/core/index.ts b/language/javascript/extractor/src/core/index.ts new file mode 100644 index 00000000..f8a6a45b --- /dev/null +++ b/language/javascript/extractor/src/core/index.ts @@ -0,0 +1,3 @@ + + +export { extract } from './extract-manager'; diff --git a/language/javascript/extractor/src/core/util.ts b/language/javascript/extractor/src/core/util.ts new file mode 100644 index 00000000..b74e9615 --- /dev/null +++ b/language/javascript/extractor/src/core/util.ts @@ -0,0 +1,2159 @@ + + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import * as fs from 'fs'; +import * as path from 'path'; + +import ignore from 'ignore'; +import * as ts from 'typescript'; + +import { coref, extendedTs } from '../model'; + +export function isKeywordSyntaxKind( + syntaxKind: ts.SyntaxKind, +): syntaxKind is ts.KeywordSyntaxKind { + return ( + ts.SyntaxKind.FirstKeyword <= syntaxKind && + syntaxKind <= ts.SyntaxKind.LastKeyword + ); +} + +export function isCommentSyntaxKind(syntaxKind: ts.SyntaxKind): boolean { + return ( + syntaxKind === ts.SyntaxKind.SingleLineCommentTrivia || + syntaxKind === ts.SyntaxKind.MultiLineCommentTrivia + ); +} + +export function isTriviaSyntaxKind( + syntaxKind: ts.SyntaxKind, +): syntaxKind is ts.TriviaSyntaxKind { + return ( + ts.SyntaxKind.FirstTriviaToken <= syntaxKind && + syntaxKind <= ts.SyntaxKind.LastTriviaToken + ); +} + +export function isNonCodeTokenSyntaxKind(syntaxKind: ts.SyntaxKind) { + return ( + syntaxKind === ts.SyntaxKind.Unknown || + syntaxKind === ts.SyntaxKind.EndOfFileToken || + isTriviaSyntaxKind(syntaxKind) + ); +} + +export function isBrokenNode(node: ts.Node | undefined) { + return !node || node.getStart() === node.getEnd(); +} + +export function isExpression(node: ts.Node | coref.Node) { + return ( + (ts.SyntaxKind.Identifier <= node.kind && + node.kind <= ts.SyntaxKind.PrivateIdentifier) || + (ts.SyntaxKind.QualifiedName <= node.kind && + node.kind <= ts.SyntaxKind.SyntheticExpression) + ); +} + +export function isInvokeExpression(node: ts.Node) { + return ( + node.kind === ts.SyntaxKind.CallExpression || + node.kind === ts.SyntaxKind.NewExpression + ); +} + +export function isStatement(node: ts.Node | coref.Node) { + return ( + ts.SyntaxKind.Block <= node.kind && + node.kind <= ts.SyntaxKind.MissingDeclaration + ); +} + +export function isLiteralLikeNode(node: ts.Node) { + return ( + (ts.SyntaxKind.FirstLiteralToken <= node.kind && + node.kind <= ts.SyntaxKind.LastLiteralToken) || + (ts.SyntaxKind.FirstTemplateToken <= node.kind && + node.kind <= ts.SyntaxKind.LastTemplateToken) + ); +} + +export function getLeadingCommentRangesOfNode( + node: ts.Node, + sourceFileOfNode: ts.SourceFile, +): ts.CommentRange[] | undefined { + return node.kind !== ts.SyntaxKind.JsxText + ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) + : undefined; +} + +export function getTrailingCommentRangesOfNode( + node: ts.Node, + sourceFileOfNode: ts.SourceFile, +): ts.CommentRange[] | undefined { + return node.kind !== ts.SyntaxKind.JsxText + ? ts.getTrailingCommentRanges(sourceFileOfNode.text, node.end) + : undefined; +} + +/** + * 根据源码 string 的位置 index 获取行号 + * + * @param pos 在源码 string 中的 index + * @param lineStarts 每行代码开始的 index + * @returns 行号 + */ +function getLineFromPos(pos: number, lineStarts: readonly number[]): number { + let low = 0, + high = lineStarts.length - 1; + while (low < high) { + const mid = high - ((high - low) >> 1); // Get middle, rounding up. + const startOfLine = lineStarts[mid]; + if (startOfLine <= pos) { + low = mid; + } else { + high = mid - 1; + } + } + return low; +} + +function getColumnFromLinePos( + line: number, + pos: number, + lineStarts: readonly number[], +): number { + return pos - lineStarts[line]; +} + +export function getPosition( + pos: number, + lineStarts: readonly number[], +): coref.Position { + const line = getLineFromPos(pos, lineStarts); + const column = getColumnFromLinePos(line, pos, lineStarts); + return { + line: line + 1, + column: column + 1, + offset: pos, + }; +} + +export function shouldReScanGreaterThanToken(node: ts.Node): boolean { + switch (node.kind) { + case ts.SyntaxKind.GreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + return true; + } + + return false; +} + +export function shouldReScanSlashToken(container: ts.Node): boolean { + return container.kind === ts.SyntaxKind.RegularExpressionLiteral; +} + +export function shouldReScanTemplateToken(container: ts.Node): boolean { + return ( + container.kind === ts.SyntaxKind.TemplateMiddle || + container.kind === ts.SyntaxKind.TemplateTail + ); +} + +function isFunctionLikeDeclarationKind(kind: ts.SyntaxKind): boolean { + switch (kind) { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + return true; + default: + return false; + } +} + +export function isFunctionLikeDeclaration( + node: ts.Node, +): node is ts.FunctionLikeDeclaration { + return node && isFunctionLikeDeclarationKind(node.kind); +} + +export function fileExtensionIs(path: string, extension: string): boolean { + return path.endsWith(extension); +} + +export function fileExtensionIsOneOf( + path: string, + extensions: readonly string[], +): boolean { + for (const extension of extensions) { + if (fileExtensionIs(path, extension)) { + return true; + } + } + + return false; +} + +export function isJsOrTsFile(path: string): boolean { + return fileExtensionIsOneOf(path, /*extensions*/ Object.values(ts.Extension)); +} + +/** + * 根据 .gitignore 文件生成一个函数作为 listAllFiles 的 ignoreFunction + * + * @param gitignorePath .gitignore 文件绝对路径 + * @returns ignoreFunction + */ +export function createIgnoreFunctionByGitignore( + gitignorePath: string, +): (fileOrDirPath: string) => coref.IgnoredPath | null { + const rootPath = path.resolve(path.dirname(gitignorePath)); + + if (!fs.existsSync(gitignorePath)) { + // 不忽略任何文件 + return () => null; + } + + const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8'); + const ig = ignore().add(gitignoreContent); + + return (fileOrDirPath: string) => { + let relativePath = path.relative(rootPath, fileOrDirPath); + const isDirectory = fs.statSync(fileOrDirPath).isDirectory(); + if (isDirectory) { + relativePath = relativePath + path.sep; + } + + if (ig.test(relativePath).ignored) { + return coref.createIgnoredPath( + isDirectory ? coref.PathKind.DIRECTORY : coref.PathKind.FILE, + fileOrDirPath, + coref.IgnoreKind.DOT_GITIGNORE, + ); + } else { + return null; + } + }; +} + +/** + * 一个 listAllFiles 的 ignoreFunction,根据路径是否是用于发布的压缩后的 js 文件或放置这类 js 文件的目录来判断是否需要忽略 + * @param fileOrDirPath 文件/目录路径 + * @returns 忽略的路径对象或 null(代表不被忽略) + */ +export function distIgnoreFunction( + fileOrDirPath: string, +): coref.IgnoredPath | null { + const stat = fs.statSync(fileOrDirPath); + const name = path.basename(fileOrDirPath); + if (stat.isDirectory()) { + const dirDenylist = ['dist']; + if (dirDenylist.includes(name)) { + return coref.createIgnoredPath( + coref.PathKind.DIRECTORY, + fileOrDirPath, + coref.IgnoreKind.DIST_DIR, + ); + } + } else if (stat.isFile()) { + if (name.endsWith('.min.js')) { + return coref.createIgnoredPath( + coref.PathKind.DIRECTORY, + fileOrDirPath, + coref.IgnoreKind.DIST_FILE, + ); + } + } + return null; +} + +/** + * Create an ignoreFunction for listAllFiles, which ignore files according to the specified `fileSizeLimit` + * + * @param fileSizeLimitInKb file size limit in KB + * @returns ignoreFunction + */ +export function createFileSizeIgnoreFunction( + fileSizeLimitInKb: number | undefined, +): (fileOrDirPath: string) => coref.IgnoredPath | null { + const sizeLimit = + fileSizeLimitInKb && fileSizeLimitInKb > 0 + ? fileSizeLimitInKb * 1024 + : 1048576; /* 1MB */ + return (fileOrDirPath: string) => { + const direntStat = fs.statSync(fileOrDirPath); + // 目录的 size 不可能超过 sizeLimit + return direntStat.size > sizeLimit + ? coref.createIgnoredPath( + coref.PathKind.FILE, + fileOrDirPath, + coref.IgnoreKind.FILE_SIZE_LIMIT, + ) + : null; + }; +} + +/** + * 根据 blacklist 列表过滤文件 + * + * @param gitignorePath .gitignore 文件绝对路径 + * @returns ignoreFunction + */ +export function createIgnoreFunctionByBlacklist( + rootPath: string, + blacklist: string[] | undefined, +): (fileOrDirPath: string) => coref.IgnoredPath | null { + if (!blacklist || blacklist.length == 0) { + // 不忽略任何文件 + return () => null; + } + + const ig = ignore(); + for (const item of blacklist) { + ig.add(item); + } + + return (fileOrDirPath: string) => { + let relativePath = path.relative(rootPath, fileOrDirPath); + if (path.isAbsolute(relativePath)) { + return null; + } + const isDirectory = fs.statSync(fileOrDirPath).isDirectory(); + if (isDirectory) { + relativePath = relativePath + path.sep; + } + + if (ig.test(relativePath).ignored) { + return coref.createIgnoredPath( + isDirectory ? coref.PathKind.DIRECTORY : coref.PathKind.FILE, + fileOrDirPath, + coref.IgnoreKind.BLACK_LIST, + ); + } + + return null; + }; +} + +/** + * 遍历目录下的全部文件,返回一个文件列表。过滤掉由于链接失效等原因导致的不存在的文件。 + * + * @param dirPath 目录 + * @param extensions 文件后缀列表 + * @param ignoreFunctions 忽略函数列表 + * @returns 该目录下全部文件的列表 + */ +export function listAllFiles( + dirPath: string, + extensions?: readonly string[], + ignoreFunctions?: readonly (( + fileOrDirPath: string, + ) => coref.IgnoredPath | null)[], +): { filePaths: string[]; ignoredPaths: coref.IgnoredPath[] } { + const filePaths: string[] = []; + const ignoredPaths: coref.IgnoredPath[] = []; + + dirPath = path.resolve(dirPath); + const queue: string[] = [dirPath]; + const visitedDirSet = new Set(); + + while (queue.length !== 0) { + dirPath = queue.shift() as string; + + const realPath = fs.realpathSync(dirPath); + // 避免循环链接 + if (visitedDirSet.has(realPath)) { + continue; + } + visitedDirSet.add(realPath); + + for (const name of fs.readdirSync(dirPath)) { + const direntPath = path.join(dirPath, name); + + if (!fs.existsSync(direntPath)) { + continue; + } + + if (ignoreFunctions) { + let ignoredPath: coref.IgnoredPath | null = null; + for (const ignoreFunction of ignoreFunctions) { + ignoredPath = ignoreFunction(direntPath); + if (ignoredPath) { + break; + } + } + + if (ignoredPath) { + console.log(`Ignore ${direntPath}`); + ignoredPaths.push(ignoredPath); + continue; + } + } + + const direntStat = fs.statSync(direntPath); + if (direntStat.isFile()) { + if (extensions && extensions.length > 0) { + // 如果指定了 extensions,判断该文件是否符合指定的 extensions + if (fileExtensionIsOneOf(direntPath, extensions)) { + filePaths.push(direntPath); + } + } else { + // 否则直接加入 filePaths 中 + filePaths.push(direntPath); + } + } else if (direntStat.isDirectory()) { + queue.push(direntPath); + } + } + } + + return { + filePaths, + ignoredPaths, + }; +} + +/** + * typescript 内部方法 visitNode + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/parser.ts#L38 + */ +function visitNode( + cbNode: (node: ts.Node) => T, + node: ts.Node | undefined, +): T | undefined { + if (isBrokenNode(node)) { + return; + } + return node && cbNode(node); +} + +/** + * typescript 内部方法 visitNodes + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/parser.ts#L42 + */ +function visitNodes( + cbNode: (node: ts.Node) => T, + cbNodes: ((node: ts.NodeArray) => T | undefined) | undefined, + nodes: ts.NodeArray | undefined, +): T | undefined { + if (nodes) { + if (cbNodes) { + return cbNodes(nodes); + } + for (const node of nodes) { + const result = cbNode(node); + if (result) { + return result; + } + } + } +} + +/** + * typescript 内部方法 forEach + * + * Iterates through 'array' by index and performs the callback on each element of array until the callback + * returns a truthy value, then returns that value. + * If no such value is found, the callback is applied to each element of array and undefined is returned. + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/core.ts#L63 + */ +function forEach( + array: readonly T[] | undefined, + callback: (element: T, index: number) => U | undefined, +): U | undefined { + if (array) { + for (let i = 0; i < array.length; i++) { + const result = callback(array[i], i); + if (result) { + return result; + } + } + } + return undefined; +} + +/** + * 根据 TypeScript 原生的 forEachChild 方法,自定义了需要遍历的 AST 节点 + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/parser.ts#L76 + * + * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes + * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, + * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns + * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. + * + * @param node a given node to visit its children + * @param cbNode a callback to be invoked for all child nodes + * @param cbNodes a callback to be invoked for embedded array + * + * @remarks `forEachChild` must visit the children of a node in the order + * that they appear in the source code. The language service depends on this property to locate nodes by position. + */ +export function forEachChild( + node: ts.Node, + cbNode: (node: ts.Node) => T | undefined, + cbNodes?: (nodes: ts.NodeArray) => T | undefined, +): T | undefined { + if (!node || node.kind <= ts.SyntaxKind.LastToken) { + return; + } + switch (node.kind) { + case ts.SyntaxKind.QualifiedName: + return ( + visitNode(cbNode, (node as ts.QualifiedName).left) || + visitNode(cbNode, (node as ts.QualifiedName).right) + ); + case ts.SyntaxKind.TypeParameter: + return ( + visitNode(cbNode, (node as ts.TypeParameterDeclaration).name) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).constraint) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).default) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).expression) + ); + case ts.SyntaxKind.ShorthandPropertyAssignment: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).name) || + visitNode( + cbNode, + (node as ts.ShorthandPropertyAssignment).questionToken, + ) || + visitNode( + cbNode, + (node as ts.ShorthandPropertyAssignment).exclamationToken, + ) || + visitNode( + cbNode, + (node as ts.ShorthandPropertyAssignment).equalsToken, + ) || + visitNode( + cbNode, + (node as ts.ShorthandPropertyAssignment).objectAssignmentInitializer, + ) + ); + case ts.SyntaxKind.SpreadAssignment: + return visitNode(cbNode, (node as ts.SpreadAssignment).expression); + case ts.SyntaxKind.Parameter: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ParameterDeclaration).dotDotDotToken) || + visitNode(cbNode, (node as ts.ParameterDeclaration).name) || + visitNode(cbNode, (node as ts.ParameterDeclaration).questionToken) || + visitNode(cbNode, (node as ts.ParameterDeclaration).type) || + visitNode(cbNode, (node as ts.ParameterDeclaration).initializer) + ); + case ts.SyntaxKind.PropertyDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.PropertyDeclaration).name) || + visitNode(cbNode, (node as ts.PropertyDeclaration).questionToken) || + visitNode(cbNode, (node as ts.PropertyDeclaration).exclamationToken) || + visitNode(cbNode, (node as ts.PropertyDeclaration).type) || + visitNode(cbNode, (node as ts.PropertyDeclaration).initializer) + ); + case ts.SyntaxKind.PropertySignature: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.PropertySignature).name) || + visitNode(cbNode, (node as ts.PropertySignature).questionToken) || + visitNode(cbNode, (node as ts.PropertySignature).type) || + visitNode(cbNode, (node as ts.PropertySignature).initializer) + ); + case ts.SyntaxKind.PropertyAssignment: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.PropertyAssignment).name) || + visitNode(cbNode, (node as ts.PropertyAssignment).questionToken) || + visitNode(cbNode, (node as ts.PropertyAssignment).initializer) + ); + case ts.SyntaxKind.VariableDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.VariableDeclaration).name) || + visitNode(cbNode, (node as ts.VariableDeclaration).exclamationToken) || + visitNode(cbNode, (node as ts.VariableDeclaration).type) || + visitNode(cbNode, (node as ts.VariableDeclaration).initializer) + ); + case ts.SyntaxKind.BindingElement: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.BindingElement).dotDotDotToken) || + visitNode(cbNode, (node as ts.BindingElement).propertyName) || + visitNode(cbNode, (node as ts.BindingElement).name) || + visitNode(cbNode, (node as ts.BindingElement).initializer) + ); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.IndexSignature: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNodes( + cbNode, + cbNodes, + (node as ts.SignatureDeclaration).typeParameters, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.SignatureDeclaration).parameters, + ) || + visitNode(cbNode, (node as ts.SignatureDeclaration).type) + ); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ArrowFunction: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).asteriskToken) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).name) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).questionToken) || + visitNode( + cbNode, + (node as ts.FunctionLikeDeclaration).exclamationToken, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.FunctionLikeDeclaration).typeParameters, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.FunctionLikeDeclaration).parameters, + ) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).type) || + // No need to traverse equalsGreaterThanToken + // visitNode(cbNode, (node as ts.ArrowFunction).equalsGreaterThanToken) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).body) + ); + case ts.SyntaxKind.ClassStaticBlockDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ClassStaticBlockDeclaration).body) + ); + case ts.SyntaxKind.TypeReference: + return ( + visitNode(cbNode, (node as ts.TypeReferenceNode).typeName) || + visitNodes( + cbNode, + cbNodes, + (node as ts.TypeReferenceNode).typeArguments, + ) + ); + case ts.SyntaxKind.TypePredicate: + return ( + visitNode(cbNode, (node as ts.TypePredicateNode).assertsModifier) || + visitNode(cbNode, (node as ts.TypePredicateNode).parameterName) || + visitNode(cbNode, (node as ts.TypePredicateNode).type) + ); + case ts.SyntaxKind.TypeQuery: + return visitNode(cbNode, (node as ts.TypeQueryNode).exprName); + case ts.SyntaxKind.TypeLiteral: + return visitNodes(cbNode, cbNodes, (node as ts.TypeLiteralNode).members); + case ts.SyntaxKind.ArrayType: + return visitNode(cbNode, (node as ts.ArrayTypeNode).elementType); + case ts.SyntaxKind.TupleType: + return visitNodes(cbNode, cbNodes, (node as ts.TupleTypeNode).elements); + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + return visitNodes( + cbNode, + cbNodes, + (node as ts.UnionOrIntersectionTypeNode).types, + ); + case ts.SyntaxKind.ConditionalType: + return ( + visitNode(cbNode, (node as ts.ConditionalTypeNode).checkType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).extendsType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).trueType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).falseType) + ); + case ts.SyntaxKind.InferType: + return visitNode(cbNode, (node as ts.InferTypeNode).typeParameter); + case ts.SyntaxKind.ImportType: + return ( + visitNode(cbNode, (node as ts.ImportTypeNode).argument) || + visitNode(cbNode, (node as ts.ImportTypeNode).qualifier) || + visitNodes(cbNode, cbNodes, (node as ts.ImportTypeNode).typeArguments) + ); + case ts.SyntaxKind.ParenthesizedType: + return visitNode(cbNode, (node as ts.ParenthesizedTypeNode).type); + case ts.SyntaxKind.TypeOperator: + // 增加了对 operator 的遍历 + return forEach(node.getChildren(), cbNode); + case ts.SyntaxKind.IndexedAccessType: + return ( + visitNode(cbNode, (node as ts.IndexedAccessTypeNode).objectType) || + visitNode(cbNode, (node as ts.IndexedAccessTypeNode).indexType) + ); + case ts.SyntaxKind.MappedType: + return ( + visitNode(cbNode, (node as ts.MappedTypeNode).readonlyToken) || + visitNode(cbNode, (node as ts.MappedTypeNode).typeParameter) || + visitNode(cbNode, (node as ts.MappedTypeNode).nameType) || + visitNode(cbNode, (node as ts.MappedTypeNode).questionToken) || + visitNode(cbNode, (node as ts.MappedTypeNode).type) || + visitNodes(cbNode, cbNodes, (node as ts.MappedTypeNode).members) + ); + case ts.SyntaxKind.LiteralType: + return visitNode(cbNode, (node as ts.LiteralTypeNode).literal); + case ts.SyntaxKind.NamedTupleMember: + return ( + visitNode(cbNode, (node as ts.NamedTupleMember).dotDotDotToken) || + visitNode(cbNode, (node as ts.NamedTupleMember).name) || + visitNode(cbNode, (node as ts.NamedTupleMember).questionToken) || + visitNode(cbNode, (node as ts.NamedTupleMember).type) + ); + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + return visitNodes(cbNode, cbNodes, (node as ts.BindingPattern).elements); + case ts.SyntaxKind.ArrayLiteralExpression: + return visitNodes( + cbNode, + cbNodes, + (node as ts.ArrayLiteralExpression).elements, + ); + case ts.SyntaxKind.ObjectLiteralExpression: + return visitNodes( + cbNode, + cbNodes, + (node as ts.ObjectLiteralExpression).properties, + ); + case ts.SyntaxKind.PropertyAccessExpression: + return ( + visitNode(cbNode, (node as ts.PropertyAccessExpression).expression) || + visitNode( + cbNode, + (node as ts.PropertyAccessExpression).questionDotToken, + ) || + visitNode(cbNode, (node as ts.PropertyAccessExpression).name) + ); + case ts.SyntaxKind.ElementAccessExpression: + return ( + visitNode(cbNode, (node as ts.ElementAccessExpression).expression) || + visitNode( + cbNode, + (node as ts.ElementAccessExpression).questionDotToken, + ) || + visitNode( + cbNode, + (node as ts.ElementAccessExpression).argumentExpression, + ) + ); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + return ( + visitNode(cbNode, (node as ts.CallExpression).expression) || + visitNode(cbNode, (node as ts.CallExpression).questionDotToken) || + visitNodes( + cbNode, + cbNodes, + (node as ts.CallExpression).typeArguments, + ) || + visitNodes(cbNode, cbNodes, (node as ts.CallExpression).arguments) + ); + case ts.SyntaxKind.TaggedTemplateExpression: + return ( + visitNode(cbNode, (node as ts.TaggedTemplateExpression).tag) || + // visitNode(cbNode, (node as ts.TaggedTemplateExpression).questionDotToken) || + // 此处不需要遍历 questionDotToken, questionDotToken 是 TaggedTemplateExpression 内部属性,而且也是不合法的语法 + visitNodes( + cbNode, + cbNodes, + (node as ts.TaggedTemplateExpression).typeArguments, + ) || + visitNode(cbNode, (node as ts.TaggedTemplateExpression).template) + ); + case ts.SyntaxKind.TypeAssertionExpression: + return ( + visitNode(cbNode, (node as ts.TypeAssertion).type) || + visitNode(cbNode, (node as ts.TypeAssertion).expression) + ); + case ts.SyntaxKind.ParenthesizedExpression: + return visitNode(cbNode, (node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.DeleteExpression: + return visitNode(cbNode, (node as ts.DeleteExpression).expression); + case ts.SyntaxKind.TypeOfExpression: + return visitNode(cbNode, (node as ts.TypeOfExpression).expression); + case ts.SyntaxKind.VoidExpression: + return visitNode(cbNode, (node as ts.VoidExpression).expression); + case ts.SyntaxKind.PrefixUnaryExpression: + // 除了原本对 operand 的遍历,增加了对 operator 的遍历 + return forEach(node.getChildren(), cbNode); + case ts.SyntaxKind.YieldExpression: + return ( + visitNode(cbNode, (node as ts.YieldExpression).asteriskToken) || + visitNode(cbNode, (node as ts.YieldExpression).expression) + ); + case ts.SyntaxKind.AwaitExpression: + return visitNode(cbNode, (node as ts.AwaitExpression).expression); + case ts.SyntaxKind.PostfixUnaryExpression: + // 除了原本对 operand 的遍历,增加了对 operator 的遍历 + return forEach(node.getChildren(), cbNode); + case ts.SyntaxKind.BinaryExpression: + return ( + visitNode(cbNode, (node as ts.BinaryExpression).left) || + visitNode(cbNode, (node as ts.BinaryExpression).operatorToken) || + visitNode(cbNode, (node as ts.BinaryExpression).right) + ); + case ts.SyntaxKind.AsExpression: + return ( + visitNode(cbNode, (node as ts.AsExpression).expression) || + visitNode(cbNode, (node as ts.AsExpression).type) + ); + case ts.SyntaxKind.NonNullExpression: + return visitNode(cbNode, (node as ts.NonNullExpression).expression); + case ts.SyntaxKind.MetaProperty: + return ( + // 增加了对第 0 个子节点 keyword 的遍历,可能是 NewKeyword 或 ImportKeyword + visitNode(cbNode, (node as ts.MetaProperty).getChildAt(0)) || + visitNode(cbNode, (node as ts.MetaProperty).name) + ); + case ts.SyntaxKind.ConditionalExpression: + return ( + visitNode(cbNode, (node as ts.ConditionalExpression).condition) || + visitNode(cbNode, (node as ts.ConditionalExpression).questionToken) || + visitNode(cbNode, (node as ts.ConditionalExpression).whenTrue) || + visitNode(cbNode, (node as ts.ConditionalExpression).colonToken) || + visitNode(cbNode, (node as ts.ConditionalExpression).whenFalse) + ); + case ts.SyntaxKind.SpreadElement: + return visitNode(cbNode, (node as ts.SpreadElement).expression); + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + return visitNodes(cbNode, cbNodes, (node as ts.Block).statements); + case ts.SyntaxKind.SourceFile: + return ( + visitNodes(cbNode, cbNodes, (node as ts.SourceFile).statements) || + visitNode(cbNode, (node as ts.SourceFile).endOfFileToken) + ); + case ts.SyntaxKind.VariableStatement: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.VariableStatement).declarationList) + ); + case ts.SyntaxKind.VariableDeclarationList: + return visitNodes( + cbNode, + cbNodes, + (node as ts.VariableDeclarationList).declarations, + ); + case ts.SyntaxKind.ExpressionStatement: + return visitNode(cbNode, (node as ts.ExpressionStatement).expression); + case ts.SyntaxKind.IfStatement: + return ( + visitNode(cbNode, (node as ts.IfStatement).expression) || + visitNode(cbNode, (node as ts.IfStatement).thenStatement) || + visitNode(cbNode, (node as ts.IfStatement).elseStatement) + ); + case ts.SyntaxKind.DoStatement: + return ( + visitNode(cbNode, (node as ts.DoStatement).statement) || + visitNode(cbNode, (node as ts.DoStatement).expression) + ); + case ts.SyntaxKind.WhileStatement: + return ( + visitNode(cbNode, (node as ts.WhileStatement).expression) || + visitNode(cbNode, (node as ts.WhileStatement).statement) + ); + case ts.SyntaxKind.ForStatement: + return ( + visitNode(cbNode, (node as ts.ForStatement).initializer) || + visitNode(cbNode, (node as ts.ForStatement).condition) || + visitNode(cbNode, (node as ts.ForStatement).incrementor) || + visitNode(cbNode, (node as ts.ForStatement).statement) + ); + case ts.SyntaxKind.ForInStatement: + return ( + visitNode(cbNode, (node as ts.ForInStatement).initializer) || + visitNode(cbNode, (node as ts.ForInStatement).expression) || + visitNode(cbNode, (node as ts.ForInStatement).statement) + ); + case ts.SyntaxKind.ForOfStatement: + return ( + visitNode(cbNode, (node as ts.ForOfStatement).awaitModifier) || + visitNode(cbNode, (node as ts.ForOfStatement).initializer) || + visitNode(cbNode, (node as ts.ForOfStatement).expression) || + visitNode(cbNode, (node as ts.ForOfStatement).statement) + ); + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.BreakStatement: + return visitNode(cbNode, (node as ts.BreakOrContinueStatement).label); + case ts.SyntaxKind.ReturnStatement: + return visitNode(cbNode, (node as ts.ReturnStatement).expression); + case ts.SyntaxKind.WithStatement: + return ( + visitNode(cbNode, (node as ts.WithStatement).expression) || + visitNode(cbNode, (node as ts.WithStatement).statement) + ); + case ts.SyntaxKind.SwitchStatement: + return ( + visitNode(cbNode, (node as ts.SwitchStatement).expression) || + visitNode(cbNode, (node as ts.SwitchStatement).caseBlock) + ); + case ts.SyntaxKind.CaseBlock: + return visitNodes(cbNode, cbNodes, (node as ts.CaseBlock).clauses); + case ts.SyntaxKind.CaseClause: + return ( + visitNode(cbNode, (node as ts.CaseClause).expression) || + visitNodes(cbNode, cbNodes, (node as ts.CaseClause).statements) + ); + case ts.SyntaxKind.DefaultClause: + return visitNodes(cbNode, cbNodes, (node as ts.DefaultClause).statements); + case ts.SyntaxKind.LabeledStatement: + return ( + visitNode(cbNode, (node as ts.LabeledStatement).label) || + visitNode(cbNode, (node as ts.LabeledStatement).statement) + ); + case ts.SyntaxKind.ThrowStatement: + return visitNode(cbNode, (node as ts.ThrowStatement).expression); + case ts.SyntaxKind.TryStatement: + return ( + visitNode(cbNode, (node as ts.TryStatement).tryBlock) || + visitNode(cbNode, (node as ts.TryStatement).catchClause) || + visitNode(cbNode, (node as ts.TryStatement).finallyBlock) + ); + case ts.SyntaxKind.CatchClause: + return ( + visitNode(cbNode, (node as ts.CatchClause).variableDeclaration) || + visitNode(cbNode, (node as ts.CatchClause).block) + ); + case ts.SyntaxKind.Decorator: + return visitNode(cbNode, (node as ts.Decorator).expression); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ClassLikeDeclaration).name) || + visitNodes( + cbNode, + cbNodes, + (node as ts.ClassLikeDeclaration).typeParameters, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.ClassLikeDeclaration).heritageClauses, + ) || + visitNodes(cbNode, cbNodes, (node as ts.ClassLikeDeclaration).members) + ); + case ts.SyntaxKind.InterfaceDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.InterfaceDeclaration).name) || + visitNodes( + cbNode, + cbNodes, + (node as ts.InterfaceDeclaration).typeParameters, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.ClassDeclaration).heritageClauses, + ) || + visitNodes(cbNode, cbNodes, (node as ts.InterfaceDeclaration).members) + ); + case ts.SyntaxKind.TypeAliasDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.TypeAliasDeclaration).name) || + visitNodes( + cbNode, + cbNodes, + (node as ts.TypeAliasDeclaration).typeParameters, + ) || + visitNode(cbNode, (node as ts.TypeAliasDeclaration).type) + ); + case ts.SyntaxKind.EnumDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.EnumDeclaration).name) || + visitNodes(cbNode, cbNodes, (node as ts.EnumDeclaration).members) + ); + case ts.SyntaxKind.EnumMember: + return ( + visitNode(cbNode, (node as ts.EnumMember).name) || + visitNode(cbNode, (node as ts.EnumMember).initializer) + ); + case ts.SyntaxKind.ModuleDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ModuleDeclaration).name) || + visitNode(cbNode, (node as ts.ModuleDeclaration).body) + ); + case ts.SyntaxKind.ImportEqualsDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ImportEqualsDeclaration).name) || + visitNode(cbNode, (node as ts.ImportEqualsDeclaration).moduleReference) + ); + case ts.SyntaxKind.ImportDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ImportDeclaration).importClause) || + visitNode(cbNode, (node as ts.ImportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ts.ImportDeclaration).assertClause) + ); + case ts.SyntaxKind.ImportClause: + return ( + visitNode(cbNode, (node as ts.ImportClause).name) || + visitNode(cbNode, (node as ts.ImportClause).namedBindings) + ); + case ts.SyntaxKind.AssertClause: + return visitNodes(cbNode, cbNodes, (node as ts.AssertClause).elements); + case ts.SyntaxKind.AssertEntry: + return ( + visitNode(cbNode, (node as ts.AssertEntry).name) || + visitNode(cbNode, (node as ts.AssertEntry).value) + ); + case ts.SyntaxKind.NamespaceExportDeclaration: + return visitNode(cbNode, (node as ts.NamespaceExportDeclaration).name); + case ts.SyntaxKind.NamespaceImport: + return visitNode(cbNode, (node as ts.NamespaceImport).name); + case ts.SyntaxKind.NamespaceExport: + return visitNode(cbNode, (node as ts.NamespaceExport).name); + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.NamedExports: + return visitNodes( + cbNode, + cbNodes, + (node as ts.NamedImportsOrExports).elements, + ); + case ts.SyntaxKind.ExportDeclaration: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ExportDeclaration).exportClause) || + visitNode(cbNode, (node as ts.ExportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ts.ExportDeclaration).assertClause) + ); + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + return ( + visitNode(cbNode, (node as ts.ImportOrExportSpecifier).propertyName) || + visitNode(cbNode, (node as ts.ImportOrExportSpecifier).name) + ); + case ts.SyntaxKind.ExportAssignment: + return ( + visitNodes(cbNode, cbNodes, node.decorators) || + visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, (node as ts.ExportAssignment).expression) + ); + case ts.SyntaxKind.TemplateExpression: + return ( + visitNode(cbNode, (node as ts.TemplateExpression).head) || + visitNodes( + cbNode, + cbNodes, + (node as ts.TemplateExpression).templateSpans, + ) + ); + case ts.SyntaxKind.TemplateSpan: + return ( + visitNode(cbNode, (node as ts.TemplateSpan).expression) || + visitNode(cbNode, (node as ts.TemplateSpan).literal) + ); + case ts.SyntaxKind.TemplateLiteralType: + return ( + visitNode(cbNode, (node as ts.TemplateLiteralTypeNode).head) || + visitNodes( + cbNode, + cbNodes, + (node as ts.TemplateLiteralTypeNode).templateSpans, + ) + ); + case ts.SyntaxKind.TemplateLiteralTypeSpan: + return ( + visitNode(cbNode, (node as ts.TemplateLiteralTypeSpan).type) || + visitNode(cbNode, (node as ts.TemplateLiteralTypeSpan).literal) + ); + case ts.SyntaxKind.ComputedPropertyName: + return visitNode(cbNode, (node as ts.ComputedPropertyName).expression); + case ts.SyntaxKind.HeritageClause: + return ( + // ExtendsKeyword or ImplementsKeyword + visitNode(cbNode, node.getChildAt(0)) || + visitNodes(cbNode, cbNodes, (node as ts.HeritageClause).types) + ); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return ( + visitNode( + cbNode, + (node as ts.ExpressionWithTypeArguments).expression, + ) || + visitNodes( + cbNode, + cbNodes, + (node as ts.ExpressionWithTypeArguments).typeArguments, + ) + ); + case ts.SyntaxKind.ExternalModuleReference: + return visitNode(cbNode, (node as ts.ExternalModuleReference).expression); + case ts.SyntaxKind.MissingDeclaration: + return visitNodes(cbNode, cbNodes, node.decorators); + case ts.SyntaxKind.CommaListExpression: + return visitNodes( + cbNode, + cbNodes, + (node as ts.CommaListExpression).elements, + ); + + case ts.SyntaxKind.JsxElement: + return ( + visitNode(cbNode, (node as ts.JsxElement).openingElement) || + visitNodes(cbNode, cbNodes, (node as ts.JsxElement).children) || + visitNode(cbNode, (node as ts.JsxElement).closingElement) + ); + case ts.SyntaxKind.JsxFragment: + return ( + visitNode(cbNode, (node as ts.JsxFragment).openingFragment) || + visitNodes(cbNode, cbNodes, (node as ts.JsxFragment).children) || + visitNode(cbNode, (node as ts.JsxFragment).closingFragment) + ); + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxOpeningElement: + return ( + visitNode(cbNode, (node as ts.JsxOpeningLikeElement).tagName) || + visitNodes( + cbNode, + cbNodes, + (node as ts.JsxOpeningLikeElement).typeArguments, + ) || + visitNode(cbNode, (node as ts.JsxOpeningLikeElement).attributes) + ); + case ts.SyntaxKind.JsxAttributes: + return visitNodes(cbNode, cbNodes, (node as ts.JsxAttributes).properties); + case ts.SyntaxKind.JsxAttribute: + return ( + visitNode(cbNode, (node as ts.JsxAttribute).name) || + visitNode(cbNode, (node as ts.JsxAttribute).initializer) + ); + case ts.SyntaxKind.JsxSpreadAttribute: + return visitNode(cbNode, (node as ts.JsxSpreadAttribute).expression); + case ts.SyntaxKind.JsxExpression: + return ( + visitNode(cbNode, (node as ts.JsxExpression).dotDotDotToken) || + visitNode(cbNode, (node as ts.JsxExpression).expression) + ); + case ts.SyntaxKind.JsxClosingElement: + return visitNode(cbNode, (node as ts.JsxClosingElement).tagName); + + case ts.SyntaxKind.OptionalType: + case ts.SyntaxKind.RestType: + case ts.SyntaxKind.JSDocTypeExpression: + case ts.SyntaxKind.JSDocNonNullableType: + case ts.SyntaxKind.JSDocNullableType: + case ts.SyntaxKind.JSDocOptionalType: + case ts.SyntaxKind.JSDocVariadicType: + return visitNode( + cbNode, + ( + node as + | ts.OptionalTypeNode + | ts.RestTypeNode + | ts.JSDocTypeExpression + | ts.JSDocTypeReferencingNode + ).type, + ); + case ts.SyntaxKind.JSDocFunctionType: + return ( + visitNodes( + cbNode, + cbNodes, + (node as ts.JSDocFunctionType).parameters, + ) || visitNode(cbNode, (node as ts.JSDocFunctionType).type) + ); + case ts.SyntaxKind.JSDocComment: + return ( + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) || visitNodes(cbNode, cbNodes, (node as ts.JSDoc).tags) + ); + case ts.SyntaxKind.JSDocSeeTag: + return ( + visitNode(cbNode, (node as ts.JSDocSeeTag).tagName) || + visitNode(cbNode, (node as ts.JSDocSeeTag).name) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocNameReference: + return visitNode(cbNode, (node as ts.JSDocNameReference).name); + case ts.SyntaxKind.JSDocMemberName: + return ( + visitNode(cbNode, (node as ts.JSDocMemberName).left) || + visitNode(cbNode, (node as ts.JSDocMemberName).right) + ); + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocPropertyTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + ((node as ts.JSDocPropertyLikeTag).isNameFirst + ? visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).name) || + visitNode( + cbNode, + (node as ts.JSDocPropertyLikeTag).typeExpression, + ) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + : visitNode( + cbNode, + (node as ts.JSDocPropertyLikeTag).typeExpression, + ) || + visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).name) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + ))) + ); + case ts.SyntaxKind.JSDocAuthorTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocImplementsTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocImplementsTag).class) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocAugmentsTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocAugmentsTag).class) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocTemplateTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocTemplateTag).constraint) || + visitNodes( + cbNode, + cbNodes, + (node as ts.JSDocTemplateTag).typeParameters, + ) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocTypedefTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + ((node as ts.JSDocTypedefTag).typeExpression && + (node as ts.JSDocTypedefTag).typeExpression?.kind === + ts.SyntaxKind.JSDocTypeExpression + ? visitNode(cbNode, (node as ts.JSDocTypedefTag).typeExpression) || + visitNode(cbNode, (node as ts.JSDocTypedefTag).fullName) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + : visitNode(cbNode, (node as ts.JSDocTypedefTag).fullName) || + visitNode(cbNode, (node as ts.JSDocTypedefTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + ))) + ); + case ts.SyntaxKind.JSDocCallbackTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocCallbackTag).fullName) || + visitNode(cbNode, (node as ts.JSDocCallbackTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocReturnTag: + case ts.SyntaxKind.JSDocTypeTag: + case ts.SyntaxKind.JSDocThisTag: + case ts.SyntaxKind.JSDocEnumTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode( + cbNode, + ( + node as + | ts.JSDocReturnTag + | ts.JSDocTypeTag + | ts.JSDocThisTag + | ts.JSDocEnumTag + ).typeExpression, + ) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.JSDocSignature: + return ( + forEach((node as ts.JSDocSignature).typeParameters, cbNode) || + forEach((node as ts.JSDocSignature).parameters, cbNode) || + visitNode(cbNode, (node as ts.JSDocSignature).type) + ); + case ts.SyntaxKind.JSDocLink: + case ts.SyntaxKind.JSDocLinkCode: + case ts.SyntaxKind.JSDocLinkPlain: + return visitNode( + cbNode, + (node as ts.JSDocLink | ts.JSDocLinkCode | ts.JSDocLinkPlain).name, + ); + case ts.SyntaxKind.JSDocTypeLiteral: + return forEach((node as ts.JSDocTypeLiteral).jsDocPropertyTags, cbNode); + case ts.SyntaxKind.JSDocTag: + case ts.SyntaxKind.JSDocClassTag: + case ts.SyntaxKind.JSDocPublicTag: + case ts.SyntaxKind.JSDocPrivateTag: + case ts.SyntaxKind.JSDocProtectedTag: + case ts.SyntaxKind.JSDocReadonlyTag: + case ts.SyntaxKind.JSDocDeprecatedTag: + return ( + visitNode(cbNode, (node as ts.JSDocTag).tagName) || + (typeof (node as ts.JSDoc).comment === 'string' + ? undefined + : visitNodes( + cbNode, + cbNodes, + (node as ts.JSDoc).comment as + | ts.NodeArray + | undefined, + )) + ); + case ts.SyntaxKind.PartiallyEmittedExpression: + return visitNode( + cbNode, + (node as ts.PartiallyEmittedExpression).expression, + ); + } +} + +/** + * Traverse all child nodes on the AST and call the callback + * + * @param ast Typescript AST + * @param callback The callback function executed during traversal. If `childFirst` is false (the parent node is traversed first), and callback returns false, then the child nodes of the current node will no longer be traversed + * @param childFirst Determine whether to traverse child nodes first, the default is true. + */ +export function forEachNode( + ast: ts.Node, + callback: (node: ts.Node) => void | boolean, + childFirst = true, +) { + function visit(node: ts.Node) { + let returnValue = undefined; + if (!childFirst) { + returnValue = callback(node); + } + if (returnValue !== false) { + forEachChild(node, visit); + } + if (childFirst) { + callback(node); + } + } + visit(ast); +} + +/** + * 调用 TypeScript 内部函数 GoToDefinition.getDefinitionAtPosition,根据位置获取定义 + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/services/goToDefinition.ts#L3 + * + * @param program + * @param sourceFile + * @param position + * @returns DefinitionInfo 数组 + */ +export function getDefinitionAtPosition( + program: ts.Program, + sourceFile: ts.SourceFile, + position: number, +): readonly ts.DefinitionInfo[] | undefined { + try { + return (ts as any).GoToDefinition.getDefinitionAtPosition( + program, + sourceFile, + position, + ); + } catch (err) { + const filePath = sourceFile.fileName; + const message = `message: ${err}\nfile: ${filePath}\noffset: ${position}`; + + console.log('Get definition failed:\n%s', message); + } +} + +/** + * TypeScript 内部函数 getTouchingPropertyName + * + * Gets the token whose text has range [start, end) and + * position >= start and (position < end or (position === end && token is literal or keyword or identifier)) + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/services/utilities.ts#L1107 + * + * @param sourceFile + * @param position + * @returns 该位置对应的 node + */ +export function getTouchingPropertyName( + sourceFile: ts.SourceFile, + position: number, +): ts.Node { + return (ts as any).getTouchingPropertyName(sourceFile, position); +} + +/** + * Get the invoked expression of a CallLikeExpression. + * + * @param node + * @returns the invoked expression + */ +export function getInvokedExpression( + node: ts.CallLikeExpression, +): ts.Expression { + switch (node.kind) { + case ts.SyntaxKind.TaggedTemplateExpression: + return node.tag; + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxSelfClosingElement: + return node.tagName; + default: + return node.expression; + } +} + +export type NamedExpression = + | (ts.ClassExpression & { name: ts.Identifier }) + | (ts.FunctionExpression & { name: ts.Identifier }); + +/** + * 判断一个节点是否是 NamedDeclaration + * @param node + * @returns 该 node 是否为 NamedDeclaration + */ +export function isNamedDeclaration( + node: ts.Node, +): node is ts.NamedDeclaration & { name: ts.DeclarationName } { + return !!(node as ts.NamedDeclaration).name; // A 'name' property should always be a DeclarationName. +} + +/** + * Indicates whether a node is named function or class expression. + * + * @param node + * @returns whether a node is NamedExpression + */ +export function isNamedExpression(node: ts.Node): node is NamedExpression { + return ( + (ts.isFunctionExpression(node) || ts.isClassExpression(node)) && + isNamedDeclaration(node) + ); +} + +export type ConstNamedExpression = + | (ts.ClassExpression & { + name: undefined; + parent: ts.VariableDeclaration & { name: ts.Identifier }; + }) + | (ts.FunctionExpression & { + name: undefined; + parent: ts.VariableDeclaration & { name: ts.Identifier }; + }) + | (ts.ArrowFunction & { + name: undefined; + parent: ts.VariableDeclaration & { name: ts.Identifier }; + }); + +export type CallHierarchyDeclaration = + | ts.SourceFile + | (ts.ModuleDeclaration & { name: ts.Identifier }) + | ts.FunctionDeclaration + | ts.ClassDeclaration + | ts.ClassStaticBlockDeclaration + | ts.MethodDeclaration + | ts.GetAccessorDeclaration + | ts.SetAccessorDeclaration + | NamedExpression + | ConstNamedExpression; + +export type Callee = + | ts.FunctionDeclaration + | ts.ClassDeclaration + | ts.MethodDeclaration + | ts.GetAccessorDeclaration + | ts.SetAccessorDeclaration + | NamedExpression + | ConstNamedExpression; + +/** + * TypeScript 内部函数 CallHierarchy.resolveCallHierarchyDeclaration + * + * Resolves the call hierarchy declaration for a node. + * + * 参考: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/services/callHierarchy.ts#L225 + */ +export function resolveCallHierarchyDeclaration( + program: ts.Program, + location: ts.Node, +): CallHierarchyDeclaration | CallHierarchyDeclaration[] | undefined { + return (ts as any).CallHierarchy.resolveCallHierarchyDeclaration( + program, + location, + ); +} + +type MayInvokeExpression = ts.CallLikeExpression | ts.AccessExpression; + +/** + * 判断一个节点是否为 AccessExpression + * + * @param node + * @returns 该 node 是否是 AccessExpression + */ +export function isAccessExpression(node: ts.Node): node is ts.AccessExpression { + return ( + node?.kind === ts.SyntaxKind.PropertyAccessExpression || + node?.kind === ts.SyntaxKind.ElementAccessExpression + ); +} + +/** + * 判断一个节点是否是“可能调用了函数”的表达式,可以是 CallLikeExpression 或 AccessExpression。其中: + * CallLikeExpression: 一定会调用一个函数 + * AccessExpression: 有可能调用一个 GetAccessor 或 SetAccessor + * + * @param node + * @returns 该 node 是否为 MayInvokeExpression + */ +export function isMayInvokeExpression( + node: ts.Node, +): node is MayInvokeExpression { + return ts.isCallLikeExpression(node) || isAccessExpression(node); +} + +/** + * 判断一个值是否为数组. + */ +export function isArray(value: any): value is readonly any[] { + return Array.isArray ? Array.isArray(value) : value instanceof Array; +} + +/** + * 根据可能的调用表达式获取被调用的函数 + * + * @param program + * @param node + * @returns 被调用的函数,如果没有则返回 undefined + */ +export function getCallee( + program: ts.Program, + node: MayInvokeExpression, +): Callee | undefined { + const target = ts.isCallLikeExpression(node) + ? getInvokedExpression(node) + : node; + + // 调用 TypeScript 内部 API resolveCallHierarchyDeclaration 函数,resolve 出被调用的函数 + const declaration = resolveCallHierarchyDeclaration(program, target); + // 如果 declaration 是数组,说明没有 resolve 出实现,只有声明,这里认为没有 resolve 出 callee + return isArray(declaration) ? undefined : (declaration as Callee | undefined); +} + +/** + * Get relative path by project path. + * If there is no project path, the relative path is the basename of file path. + * + * @param filePath file absolute path + * @param projectPath project path + * @returns relative path + */ +export function getRelativePath( + filePath: string, + projectPath?: string | undefined, +): string { + return projectPath + ? filePath.startsWith(projectPath + path.sep) + ? path.relative(projectPath, filePath) + : filePath + : path.basename(filePath); +} + +/** + * Ensure the sourceFile has $file property, which is the COREF File object. + * + * @param sourceFile + * @param projectPath + * @returns the COREF file object + */ +export function ensureCorefFile( + sourceFile: extendedTs.SourceFile, + projectPath?: string | undefined, +): coref.File { + if (!sourceFile.$file) { + const relativePath = getRelativePath(sourceFile.fileName, projectPath); + sourceFile.$file = coref.createFile(relativePath); + } + + return sourceFile.$file; +} + +/** + * Create location by position. + * + * @param sourceFile + * @param startPos + * @param endPos + * @param text + * @returns + */ +export function createLocationByPosition( + sourceFile: extendedTs.SourceFile, + startPos: number, + endPos: number, + text: string, +) { + const lineStarts = sourceFile.getLineStarts(); + const start = getPosition(startPos, lineStarts); + const end = getPosition(endPos, lineStarts); + return coref.createLocation(sourceFile.$file as coref.File, start, end, text); +} + +/** + * 根据 AST Node 创建对应的 COREF Location 对象 + * + * @param tsNode AST Node 节点 + * @returns 该 AST Node 对应的 COREF Location 对象 + */ +export function createNodeLocation(tsNode: extendedTs.Node): coref.Location { + const sourceFile = tsNode.getSourceFile(); + const startPos = tsNode.getStart(); + const endPos = tsNode.end; + const text = tsNode.getText(); + + return createLocationByPosition( + sourceFile as extendedTs.SourceFile, + startPos, + endPos, + text, + ); +} + +/** + * Ensure the extendedTs.Node has the $corefModel property, and return it. Generate the $corefModel if not exists. + * + * @param tsNode extendedTs.Node + * @returns the $corefModel of this node + */ +export function ensureCorefAstNode(tsNode: extendedTs.Node): coref.BaseModel { + if (!tsNode.$corefModel) { + const location = createNodeLocation(tsNode); + + tsNode.$corefModel = + tsNode.kind === ts.SyntaxKind.SourceFile + ? coref.createTopLevel(coref.TopLevelKind.SCRIPT, location) + : coref.createNode(tsNode.kind, location); + } + + return tsNode.$corefModel; +} + +/** + * Get the symbol of the node. + * + * @param node + * @param typeChecker + * @returns + */ +export function getSymbol( + node: ts.Node, + typeChecker: ts.TypeChecker, +): ts.Symbol | undefined { + return ( + (node as extendedTs.Node).symbol ?? typeChecker.getSymbolAtLocation(node) + ); +} + +/** + * Get the first value declaration or the first declaration of the symbol, + * if no value declaration exists. + * + * @param symbol + * @returns + */ +export function getSymbolDeclaration( + symbol: ts.Symbol, +): ts.Declaration | undefined { + return symbol.valueDeclaration ?? symbol.declarations?.[0]; +} + +/** + * Get symbol description. + * + * @param node + * @param symbol + * @param typeChecker + * @returns + */ +export function getSymbolDescription( + node: ts.Node, + symbol: ts.Symbol, + typeChecker: ts.TypeChecker, +) { + // `getSymbolDisplayPartsDocumentationAndSymbolKind` may throw failed assertions. + // Return an empty string if `getSymbolDisplayPartsDocumentationAndSymbolKind` throws a failed assertion. + try { + const { displayParts } = + (ts as any).SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( + typeChecker, + symbol, + node.getSourceFile(), + (ts as any).getContainerNode(node), + node, + ) ?? {}; + return ts.displayPartsToString(displayParts); + } catch (e) { + console.log(e); + return ''; + } +} + +/** + * Get the COREF node oid from the typescript node. + * + * @param node + * @param projectPath + * @returns + */ +export function getOidFromTsNode( + node: extendedTs.Node, + projectPath?: string | undefined, +) { + ensureCorefFile(node.getSourceFile() as extendedTs.SourceFile, projectPath); + return ensureCorefAstNode(node).oid; +} + +/** + * Create a COREF Symbol from a typescript Symbol. + * + * @param tsSymbol + * @param projectPath + * @returns + */ +export function createSymbolFromTsSymbol( + tsSymbol: ts.Symbol, + typeChecker: ts.TypeChecker, + projectPath?: string | undefined, +) { + const declaration: extendedTs.Node | undefined = + getSymbolDeclaration(tsSymbol); + + // Do not extract the symbol if there is no associated declaration + if (declaration === undefined) { + return undefined; + } + + // Use the oid of the first declaration node as the symbol oid + const oid = getOidFromTsNode(declaration, projectPath); + const description = getSymbolDescription(declaration, tsSymbol, typeChecker); + return coref.createSymbol(oid, tsSymbol, description); +} + +/** + * Create symbol + * + * @param tsNode + * @param projectPath + * @returns COREF symbol + */ +export function createSymbol( + tsNode: extendedTs.Node, + typeChecker: ts.TypeChecker, + projectPath?: string | undefined, +): coref.Symbol | undefined { + const tsSymbol = getSymbol(tsNode, typeChecker); + return ( + tsSymbol && createSymbolFromTsSymbol(tsSymbol, typeChecker, projectPath) + ); +} + +/** + * Get the value symbol oid of the shorthand property assignment. + * + * @param tsNode + * @param typeChecker + * @param projectPath + * @returns + */ +export function getShortHandAssignmentValueSymbolOid( + tsNode: extendedTs.Node, + typeChecker: ts.TypeChecker, + projectPath?: string | undefined, +): bigint | undefined { + const tsSymbol = typeChecker.getShorthandAssignmentValueSymbol(tsNode); + const declaration = tsSymbol && getSymbolDeclaration(tsSymbol); + return declaration && getOidFromTsNode(declaration, projectPath); +} + +/** + * Get the property node of an access expression. + * + * @param accessExpression + * @returns + */ +export function getAccessExpressionPropertyNode( + accessExpression: ts.AccessExpression, +): ts.Expression { + if (ts.isPropertyAccessExpression(accessExpression)) { + return accessExpression.name; + } else if (ts.isElementAccessExpression(accessExpression)) { + // ts.isElementAccessExpression(accessExpression) + return (accessExpression as ts.ElementAccessExpression).argumentExpression; + } else { + throw new Error('Invalid accessExpression'); + } +} + +/** + * Get the property name of a property-access expression or element-access expression. + * + * For element-access expressions, This function doesn't resolve the argument expression. + * It only handle the case that the argument expression is a string literal and return the value of the string. + * In other cases, it returns undefined. + * + * @param accessExpression + * @param sourceFile + * @returns + */ +export function getAccessExpressionPropertyName( + accessExpression: ts.AccessExpression, +): string | undefined { + const propertyNode = getAccessExpressionPropertyNode(accessExpression); + if (propertyNode === undefined) { + return undefined; + } + + switch (propertyNode.kind) { + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.StringLiteral: + return (propertyNode as ts.MemberName | ts.StringLiteral).text; + default: + return undefined; + } +} + +/** + * Get names of an access expression. + * @param node + * @param sourceFile + * @returns name array + */ +export function getAccessExpressionNames(node: ts.Node | undefined): string[] { + if (node === undefined) { + return []; + } else if (ts.isIdentifier(node)) { + return [node.text]; + } else if (isAccessExpression(node)) { + const name = getAccessExpressionPropertyName(node); + return name === undefined + ? [] + : [...getAccessExpressionNames(node.expression), name]; + } else { + return []; + } +} + +export function getAccessExpressionText(node: ts.Node | undefined): string { + return getAccessExpressionNames(node).join('.'); +} + +/** + * Get the class member by the name. + * + * ComputedPropertyName is not handled. + * + * @param classLikeDeclaration + * @param name + * @returns + */ +export function getClassMemberByName( + classLikeDeclaration: ts.ClassLikeDeclaration, + name: string, +): ts.ClassElement | undefined { + const members = classLikeDeclaration.members; + for (const member of members) { + if (!ts.isPropertyDeclaration(member) && !ts.isMethodDeclaration(member)) { + continue; + } + + const nameNode = member.name; + // Do not handle ComputedPropertyName + if (!ts.isComputedPropertyName(nameNode) && nameNode.text === name) { + return member; + } + } + + return undefined; +} + +/** + * Get the underlying ClassLikeDeclaration of an expression. + * + * Only handle the cases that the expression is an Identifier or ClassExpression. + * + * @param expression + * @returns + */ +export function getClassOfExpression( + expression: ts.Expression, + typeChecker: ts.TypeChecker, +): ts.ClassLikeDeclaration | undefined { + let classLikeDeclaration: ts.ClassLikeDeclaration | undefined = undefined; + + if (ts.isIdentifier(expression)) { + const symbol = getSymbol(expression, typeChecker); + const declaration = symbol && getSymbolDeclaration(symbol); + if (declaration?.kind === ts.SyntaxKind.ClassDeclaration) { + classLikeDeclaration = declaration as ts.ClassDeclaration; + } else if (declaration?.kind === ts.SyntaxKind.VariableDeclaration) { + const initializer = (declaration as ts.VariableDeclaration).initializer; + if (initializer?.kind === ts.SyntaxKind.ClassExpression) { + classLikeDeclaration = initializer as ts.ClassExpression; + } + } + } else if (ts.isClassExpression(expression)) { + classLikeDeclaration = expression; + } + + return classLikeDeclaration; +} + +/** + * Get the underlying FunctionLikeDeclaration of an expression. + * + * @param expression + * @returns + */ +export function getFunctionOfExpression( + expression: ts.Expression, + typeChecker: ts.TypeChecker, +): ts.FunctionLikeDeclaration | undefined { + let functionLikeDeclaration: ts.FunctionLikeDeclaration | undefined = + undefined; + if (ts.isIdentifier(expression)) { + const symbol = getSymbol(expression, typeChecker); + const declaration = symbol && getSymbolDeclaration(symbol); + + if (declaration?.kind === ts.SyntaxKind.FunctionDeclaration) { + functionLikeDeclaration = declaration as ts.FunctionDeclaration; + } else if (declaration?.kind === ts.SyntaxKind.VariableDeclaration) { + const initializer = (declaration as ts.VariableDeclaration).initializer; + switch (initializer?.kind) { + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: { + functionLikeDeclaration = initializer as ts.FunctionLikeDeclaration; + } + } + } + } else if ( + ts.isFunctionExpression(expression) || + ts.isArrowFunction(expression) + ) { + functionLikeDeclaration = expression; + } + + return functionLikeDeclaration; +} + +export function isExportDefaultDeclaration( + declaration: ts.FunctionDeclaration | ts.ClassDeclaration, +): boolean { + const modifiers = declaration.modifiers; + return ( + modifiers?.[0].kind === ts.SyntaxKind.ExportKeyword && + modifiers?.[1].kind === ts.SyntaxKind.DefaultKeyword + ); +} + +export function isModuleExportsAssignExpression(expression: ts.Expression) { + if (!ts.isBinaryExpression(expression)) { + return false; + } + + return getAccessExpressionText(expression.left) === 'module.exports'; +} + +/** + * Ref: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/types.ts#L981 + */ +export type HasModifiers = + | ts.ParameterDeclaration + | ts.PropertySignature + | ts.PropertyDeclaration + | ts.MethodSignature + | ts.MethodDeclaration + | ts.ConstructorDeclaration + | ts.GetAccessorDeclaration + | ts.SetAccessorDeclaration + | ts.IndexSignatureDeclaration + | ts.FunctionExpression + | ts.ArrowFunction + | ts.ClassExpression + | ts.VariableStatement + | ts.FunctionDeclaration + | ts.ClassDeclaration + | ts.InterfaceDeclaration + | ts.TypeAliasDeclaration + | ts.EnumDeclaration + | ts.ModuleDeclaration + | ts.ImportEqualsDeclaration + | ts.ImportDeclaration + | ts.ExportAssignment + | ts.ExportDeclaration; + +/** + * Determine whether a node can have modifiers. + * + * Ref: https://github.com/microsoft/TypeScript/blob/v4.5.5/src/compiler/factory/utilities.ts#L868 + * + * @param node + * @returns node is HasModifiers + */ +export function canHaveModifiers(node: ts.Node): node is HasModifiers { + const kind = node.kind; + return ( + kind === ts.SyntaxKind.Parameter || + kind === ts.SyntaxKind.PropertySignature || + kind === ts.SyntaxKind.PropertyDeclaration || + kind === ts.SyntaxKind.MethodSignature || + kind === ts.SyntaxKind.MethodDeclaration || + kind === ts.SyntaxKind.Constructor || + kind === ts.SyntaxKind.GetAccessor || + kind === ts.SyntaxKind.SetAccessor || + kind === ts.SyntaxKind.IndexSignature || + kind === ts.SyntaxKind.FunctionExpression || + kind === ts.SyntaxKind.ArrowFunction || + kind === ts.SyntaxKind.ClassExpression || + kind === ts.SyntaxKind.VariableStatement || + kind === ts.SyntaxKind.FunctionDeclaration || + kind === ts.SyntaxKind.ClassDeclaration || + kind === ts.SyntaxKind.InterfaceDeclaration || + kind === ts.SyntaxKind.TypeAliasDeclaration || + kind === ts.SyntaxKind.EnumDeclaration || + kind === ts.SyntaxKind.ModuleDeclaration || + kind === ts.SyntaxKind.ImportEqualsDeclaration || + kind === ts.SyntaxKind.ImportDeclaration || + kind === ts.SyntaxKind.ExportAssignment || + kind === ts.SyntaxKind.ExportDeclaration + ); +} diff --git a/language/javascript/extractor/src/core/worker.ts b/language/javascript/extractor/src/core/worker.ts new file mode 100644 index 00000000..195d452b --- /dev/null +++ b/language/javascript/extractor/src/core/worker.ts @@ -0,0 +1,38 @@ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { PrismaClient } from '@prisma/client'; +import { expose } from 'threads/worker'; + +import { Coref, createPrismaClient, persistCoref } from '../dal/db'; + +let prismaClient: PrismaClient | undefined; + +expose({ + /** + * Init the prisma client of this writer thread. + * This method must be called first before other methods of the writer. + * + * @param dbPath the db file path + */ + initPrismaClient(dbPath: string) { + if (!prismaClient) { + prismaClient = createPrismaClient(dbPath); + } + }, + + /** + * Persist the coref data + * + * @param corefData + * @returns + */ + async persistCoref(corefData: Coref) { + if (!prismaClient) { + return; + } + + const creations = persistCoref(prismaClient, corefData); + await prismaClient.$transaction(creations); + }, +}); diff --git a/language/javascript/extractor/src/dal/db/index.ts b/language/javascript/extractor/src/dal/db/index.ts new file mode 100644 index 00000000..e5776f2a --- /dev/null +++ b/language/javascript/extractor/src/dal/db/index.ts @@ -0,0 +1,7 @@ + + +export * from './merge-db'; +export * from './model'; +export * from './persist'; +export * from './prisma-client'; +export * from './transaction'; diff --git a/language/javascript/extractor/src/dal/db/merge-db.ts b/language/javascript/extractor/src/dal/db/merge-db.ts new file mode 100644 index 00000000..9b6ef0ea --- /dev/null +++ b/language/javascript/extractor/src/dal/db/merge-db.ts @@ -0,0 +1,37 @@ + + +import { PrismaClient, Prisma } from '@prisma/client'; + +const ATTACHED_DB_NAME = 'attached_db'; +let tableNames: string[] | undefined; + +/** + * Merge a tmp db file + * + * @param prismaClient + * @param mergedDbPath + */ +export async function mergeDb( + prismaClient: PrismaClient, + mergedDbPath: string, +) { + if (tableNames === undefined) { + const tableNameDenySet = new Set(['ignored_path', 'metadata']); + tableNames = Object.keys(Prisma.ModelName).filter( + tableName => !tableNameDenySet.has(tableName), + ); + } + + const insertSqls = tableNames.map( + tableName => + `insert into ${tableName} select * from ${ATTACHED_DB_NAME}.${tableName};`, + ); + + await prismaClient.$executeRawUnsafe( + `attach '${mergedDbPath}' as ${ATTACHED_DB_NAME};`, + ); + await prismaClient.$transaction([ + ...insertSqls.map(insertSql => prismaClient.$executeRawUnsafe(insertSql)), + ]); + await prismaClient.$executeRawUnsafe(`detach ${ATTACHED_DB_NAME};`); +} diff --git a/language/javascript/extractor/src/dal/db/model.ts b/language/javascript/extractor/src/dal/db/model.ts new file mode 100644 index 00000000..52dd5fc4 --- /dev/null +++ b/language/javascript/extractor/src/dal/db/model.ts @@ -0,0 +1,112 @@ + +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import * as prisma from '@prisma/client'; + +export type TopLevel = prisma.top_level; +export type Node = prisma.node; +export type Comment = prisma.comment; +export type NodeComment = prisma.node_comment; +export type BindingElementPropertyName = prisma.binding_element_property_name; +export type BindingElementName = prisma.binding_element_name; +export type BindingElementInitializer = prisma.binding_element_initializer; +export type ClassLikeDeclaration = prisma.class_like_declaration; +export type FunctionLikeDeclaration = prisma.function_like_declaration; +export type FunctionEnclosingNode = prisma.function_enclosing_node; +export type Literal = prisma.literal; +export type Modifier = prisma.modifier; +export type CfgEntryNode = prisma.cfg_entry_node; +export type CfgExitNode = prisma.cfg_exit_node; +export type Location = prisma.location; +export type File = prisma.file; +export type NumberOfLines = prisma.number_of_lines; +export type Symbol = prisma.symbol_; +export type NodeSymbol = prisma.node_symbol; +export type ShorthandAssignmentValueSymbol = + prisma.shorthand_assignment_value_symbol; +export type CallSite = prisma.call_site; +export type Metadata = prisma.metadata; + +export interface Coref { + topLevels?: TopLevel[]; + nodes?: Node[]; + comments?: Comment[]; + nodeComments?: NodeComment[]; + bindingElementPropertyNames?: BindingElementPropertyName[]; + bindingElementNames?: BindingElementName[]; + bindingElementInitializers?: BindingElementInitializer[]; + classLikeDeclarations?: ClassLikeDeclaration[]; + functionLikeDeclarations?: FunctionLikeDeclaration[]; + functionEnclosingNodes?: FunctionEnclosingNode[]; + literals?: Literal[]; + modifiers?: Modifier[]; + cfgEntryNodes?: CfgEntryNode[]; + cfgExitNodes?: CfgExitNode[]; + locations?: Location[]; + files?: File[]; + numbersOfLines?: NumberOfLines[]; + symbols?: Symbol[]; + nodeSymbols?: NodeSymbol[]; + shorthandAssignmentValueSymbols?: ShorthandAssignmentValueSymbol[]; + callSites?: CallSite[]; +} + +type CorefProperty = keyof Coref; + +const CHUNK_SIZE = 1000; + +/** + * Split one big COREF to multiple small COREFs + * + * @param coref the big COREF + * @returns the split COREFs + */ +export function splitCoref(coref: Coref): Coref[] { + const splitCorefs: Coref[] = []; + let currentCoref: Coref = {}; + let currentLength = 0; + + for (const property of Object.keys(coref) as CorefProperty[]) { + let corefObjects = coref[property]; + if (!(corefObjects && corefObjects.length > 0)) { + continue; + } + + let totalLength = currentLength + corefObjects.length; + + while (totalLength > CHUNK_SIZE) { + let splitCoref: Coref; + let chunkSize: number; + if (currentLength === 0) { + chunkSize = CHUNK_SIZE; + splitCoref = { + [property]: corefObjects.slice(0, chunkSize), + }; + } else { + splitCoref = currentCoref; + currentCoref = {}; + currentLength = 0; + + chunkSize = CHUNK_SIZE - currentLength; + (splitCoref[property] as any) = corefObjects.slice(0, chunkSize); + } + + corefObjects = corefObjects.slice(chunkSize); + splitCorefs.push(splitCoref); + + totalLength = corefObjects.length; + } + + if (corefObjects.length > 0) { + (currentCoref[property] as any) = corefObjects; + currentLength = currentLength + corefObjects.length; + } + } + + if (currentLength > 0) { + splitCorefs.push(currentCoref); + } + + return splitCorefs; +} diff --git a/language/javascript/extractor/src/dal/db/persist.ts b/language/javascript/extractor/src/dal/db/persist.ts new file mode 100644 index 00000000..1082b189 --- /dev/null +++ b/language/javascript/extractor/src/dal/db/persist.ts @@ -0,0 +1,576 @@ + +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { coref } from '../../model'; +import { + TopLevel, + Node, + Comment, + NodeComment, + BindingElementPropertyName, + BindingElementName, + BindingElementInitializer, + ClassLikeDeclaration, + FunctionLikeDeclaration, + FunctionEnclosingNode, + Literal, + Location, + NumberOfLines, + File, + Symbol, + NodeSymbol, + CallSite, + Coref, + Metadata, + Modifier, + CfgEntryNode, + CfgExitNode, + ShorthandAssignmentValueSymbol, +} from './model'; + +import { PrismaClient, PrismaPromise } from '@prisma/client'; + +/** + * 创建 comments + * + * @param prismaClient + * @param comments + * @returns + */ +export function createComments( + prismaClient: PrismaClient, + comments: Comment[], +) { + return comments.map(data => + prismaClient.comment.create({ + data, + }), + ); +} + +/** + * 创建 locations + * + * @param prismaClient + * @param locations + * @returns + */ +export function createLocations( + prismaClient: PrismaClient, + locations: Location[], +) { + return locations.map(data => + prismaClient.location.create({ + data, + }), + ); +} + +/** + * 创建 files + * + * @param prismaClient + * @param files + * @returns + */ +export function createFiles(prismaClient: PrismaClient, files: File[]) { + return files.map(data => + prismaClient.file.create({ + data, + }), + ); +} + +/** + * 创建 nodes + * + * @param prismaClient + * @param nodes + * @returns + */ +export function createNodes(prismaClient: PrismaClient, nodes: Node[]) { + const promises = nodes.map(data => + prismaClient.node.create({ + data, + }), + ); + return promises; +} + +/** + * 创建 class-like declarations + * + * @param prismaClient + * @param classLikeDeclarations + * @returns + */ +export function createClassLikeDeclarations( + prismaClient: PrismaClient, + classLikeDeclarations: ClassLikeDeclaration[], +) { + return classLikeDeclarations.map(data => + prismaClient.class_like_declaration.create({ + data, + }), + ); +} + +/** + * 创建 function-like declarations + * @param prismaClient + * @param functionLikeDeclarations + * @returns + */ +export function createFunctionLikeDeclarations( + prismaClient: PrismaClient, + functionLikeDeclarations: FunctionLikeDeclaration[], +) { + return functionLikeDeclarations.map(data => + prismaClient.function_like_declaration.create({ + data, + }), + ); +} + +/** + * 创建 literals + * @param prismaClient + * @param literals + * @returns + */ +export function createLiterals( + prismaClient: PrismaClient, + literals: Literal[], +) { + return literals.map(data => + prismaClient.literal.create({ + data, + }), + ); +} + +/** + * 创建节点与注释的关联关系 + * + * @param prismaClient + * @param nodeComments + * @returns + */ +export function createNodeComments( + prismaClient: PrismaClient, + nodeComments: NodeComment[], +) { + return nodeComments.map(data => + prismaClient.node_comment.create({ + data, + }), + ); +} + +/** + * 创建函数与其包含的节点的关联关系 + * + * @param prismaClient + * @param functionEnclosingNodes + * @returns + */ +export function createFunctionEnclosingNodes( + prismaClient: PrismaClient, + functionEnclosingNodes: FunctionEnclosingNode[], +) { + return functionEnclosingNodes.map(data => + prismaClient.function_enclosing_node.create({ + data, + }), + ); +} + +/** + * 创建 top-levels + * + * @param prismaClient + * @param topLevels + * @returns + */ +export function createTopLevels( + prismaClient: PrismaClient, + topLevels: TopLevel[], +) { + return topLevels.map(data => + prismaClient.top_level.create({ + data, + }), + ); +} + +/** + * 创建每个 locatable 元素对应的 number-of-lines 数据 + * + * @param prismaClient + * @param numbersOfLines + * @returns + */ +export function createNumbersOfLines( + prismaClient: PrismaClient, + numbersOfLines: NumberOfLines[], +) { + return numbersOfLines.map(data => + prismaClient.number_of_lines.create({ + data, + }), + ); +} + +/** + * Create symbols + * + * @param prismaClient + * @param symbols + * @returns + */ +export function createSymbols(prismaClient: PrismaClient, symbols: Symbol[]) { + return symbols.map(data => + prismaClient.symbol_.create({ + data, + }), + ); +} + +/** + * Create node symbol relations + * + * @param prismaClient + * @param nodeSymbols + * @returns + */ +export function createNodeSymbols( + prismaClient: PrismaClient, + nodeSymbols: NodeSymbol[], +) { + return nodeSymbols.map(data => + prismaClient.node_symbol.create({ + data, + }), + ); +} + +/** + * Create shorthand assignment value symbol relations. + * + * @param prismaClient + * @param shorthandAssignmentValueSymbols + * @returns + */ +export function createShorthandAssignmentValueSymbols( + prismaClient: PrismaClient, + shorthandAssignmentValueSymbols: ShorthandAssignmentValueSymbol[], +) { + return shorthandAssignmentValueSymbols.map(data => + prismaClient.shorthand_assignment_value_symbol.create({ data }), + ); +} + +/** + * 创建 call sites + * + * @param prismaClient + * @param callSites + * @returns + */ +export function createCallSites( + prismaClient: PrismaClient, + callSites: CallSite[], +) { + return callSites.map(data => + prismaClient.call_site.create({ + data, + }), + ); +} + +export function createIgnoredPaths( + prismaClient: PrismaClient, + ignoredPaths: coref.IgnoredPath[], +) { + return ignoredPaths.map(ignoredPath => + prismaClient.ignored_path.create({ + data: { + oid: ignoredPath.oid, + path_kind: ignoredPath.pathKind, + path: ignoredPath.path, + ignore_kind: ignoredPath.ignoreKind, + }, + }), + ); +} + +/** + * Create bindingElementPropertyNames + * + * @param prismaClient + * @param bindingElementPropertyNames + * @returns + */ +export function createBindingElementPropertyNames( + prismaClient: PrismaClient, + bindingElementPropertyNames: BindingElementPropertyName[], +) { + return bindingElementPropertyNames.map(data => + prismaClient.binding_element_property_name.create({ + data, + }), + ); +} + +/** + * Create bindingElementNames + * + * @param prismaClient + * @param bindingElementNames + * @returns + */ +export function createBindingElementNames( + prismaClient: PrismaClient, + bindingElementNames: BindingElementName[], +) { + return bindingElementNames.map(data => + prismaClient.binding_element_name.create({ + data, + }), + ); +} + +/** + * Create bindingElementInitializers + * + * @param prismaClient + * @param bindingElementInitializers + * @returns + */ +export function createBindingElementInitializers( + prismaClient: PrismaClient, + bindingElementInitializers: BindingElementInitializer[], +) { + return bindingElementInitializers.map(data => + prismaClient.binding_element_initializer.create({ + data, + }), + ); +} + +/** + * Create cfgEntryNodes + * + * @param prismaClient + * @param cfgEntryNodes + * @returns + */ +export function createCfgEntryNodes( + prismaClient: PrismaClient, + cfgEntryNodes: CfgEntryNode[], +) { + return cfgEntryNodes.map(data => + prismaClient.cfg_entry_node.create({ + data, + }), + ); +} + +/** + * Create cfgExitNodes + * @param prismaClient + * @param cfgExitNodes + * @returns + */ +export function createCfgExitNodes( + prismaClient: PrismaClient, + cfgExitNodes: CfgExitNode[], +) { + return cfgExitNodes.map(data => + prismaClient.cfg_exit_node.create({ + data, + }), + ); +} + +/** + * Create a metadata + * + * @param prismaClient + * @param metadata + * @returns + */ +export function createMetadata(prismaClient: PrismaClient, metadata: Metadata) { + return prismaClient.metadata.create({ + data: metadata, + }); +} + +/** + * Create modifiers + * + * @param prismaClient + * @param modifiers + * @returns + */ +export function createModifiers( + prismaClient: PrismaClient, + modifiers: Modifier[], +) { + return modifiers.map(data => + prismaClient.modifier.create({ + data, + }), + ); +} + +/** + * Persist the coref data + * + * @param prismaClient + * @param corefData + * @returns + */ +export function persistCoref(prismaClient: PrismaClient, corefData: Coref) { + let creations: PrismaPromise[] = []; + if (corefData.topLevels) { + creations = createTopLevels(prismaClient, corefData.topLevels); + } + + if (corefData.nodes) { + creations = creations.concat(createNodes(prismaClient, corefData.nodes)); + } + + if (corefData.comments) { + creations = creations.concat( + createComments(prismaClient, corefData.comments), + ); + } + + if (corefData.nodeComments) { + creations = creations.concat( + createNodeComments(prismaClient, corefData.nodeComments), + ); + } + + if (corefData.bindingElementPropertyNames) { + creations = creations.concat( + createBindingElementPropertyNames( + prismaClient, + corefData.bindingElementPropertyNames, + ), + ); + } + + if (corefData.bindingElementNames) { + creations = creations.concat( + createBindingElementNames(prismaClient, corefData.bindingElementNames), + ); + } + + if (corefData.bindingElementInitializers) { + creations = creations.concat( + createBindingElementInitializers( + prismaClient, + corefData.bindingElementInitializers, + ), + ); + } + + if (corefData.classLikeDeclarations) { + creations = creations.concat( + createClassLikeDeclarations( + prismaClient, + corefData.classLikeDeclarations, + ), + ); + } + + if (corefData.functionLikeDeclarations) { + creations = creations.concat( + createFunctionLikeDeclarations( + prismaClient, + corefData.functionLikeDeclarations, + ), + ); + } + + if (corefData.functionEnclosingNodes) { + creations = creations.concat( + createFunctionEnclosingNodes( + prismaClient, + corefData.functionEnclosingNodes, + ), + ); + } + + if (corefData.literals) { + creations = creations.concat( + createLiterals(prismaClient, corefData.literals), + ); + } + + if (corefData.modifiers) { + creations = creations.concat( + createModifiers(prismaClient, corefData.modifiers), + ); + } + + if (corefData.cfgEntryNodes) { + creations = creations.concat( + createCfgEntryNodes(prismaClient, corefData.cfgEntryNodes), + ); + } + + if (corefData.cfgExitNodes) { + creations = creations.concat( + createCfgExitNodes(prismaClient, corefData.cfgExitNodes), + ); + } + + if (corefData.locations) { + creations = creations.concat( + createLocations(prismaClient, corefData.locations), + ); + } + + if (corefData.files) { + creations = creations.concat(createFiles(prismaClient, corefData.files)); + } + + if (corefData.numbersOfLines) { + creations = creations.concat( + createNumbersOfLines(prismaClient, corefData.numbersOfLines), + ); + } + + if (corefData.symbols) { + creations = creations.concat( + createSymbols(prismaClient, corefData.symbols), + ); + } + + if (corefData.nodeSymbols) { + creations = creations.concat( + createNodeSymbols(prismaClient, corefData.nodeSymbols), + ); + } + + if (corefData.shorthandAssignmentValueSymbols) { + creations = creations.concat( + createShorthandAssignmentValueSymbols( + prismaClient, + corefData.shorthandAssignmentValueSymbols, + ), + ); + } + + if (corefData.callSites) { + creations = creations.concat( + createCallSites(prismaClient, corefData.callSites), + ); + } + + return creations; +} diff --git a/language/javascript/extractor/src/dal/db/prisma-client.ts b/language/javascript/extractor/src/dal/db/prisma-client.ts new file mode 100644 index 00000000..52c81820 --- /dev/null +++ b/language/javascript/extractor/src/dal/db/prisma-client.ts @@ -0,0 +1,19 @@ + + +import { PrismaClient } from '@prisma/client'; + +/** + * 根据指定的 db 文件路径,创建 sqlite 的 prisma client + * + * @param dbPath db 文件路径 + * @returns prisma client + */ +export function createPrismaClient(dbPath?: string) { + return new PrismaClient({ + datasources: { + db: { + url: `file:${dbPath}`, + }, + }, + }); +} diff --git a/language/javascript/extractor/src/dal/db/transaction.ts b/language/javascript/extractor/src/dal/db/transaction.ts new file mode 100644 index 00000000..aee671db --- /dev/null +++ b/language/javascript/extractor/src/dal/db/transaction.ts @@ -0,0 +1,17 @@ + + +import { PrismaClient, PrismaPromise } from '@prisma/client'; + +/** + * 执行 transaction + * + * @param prismaClient + * @param operations + */ +export async function transaction( + prismaClient: PrismaClient, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + operations: PrismaPromise[], +) { + await prismaClient.$transaction(operations); +} diff --git a/language/javascript/extractor/src/index.ts b/language/javascript/extractor/src/index.ts new file mode 100755 index 00000000..0bd900fb --- /dev/null +++ b/language/javascript/extractor/src/index.ts @@ -0,0 +1,80 @@ +#! npx ts-node + +/** + * Copyright 2022-2023 Ant Group CO., Ltd. + * + * @file 命令行入口 + * @author 张玉 + */ + +import { Command, InvalidArgumentError } from 'commander'; + +import { extract } from './core/index'; +import { version } from '../package.json'; + +const program = new Command(); + +const DEFAULT_DB_FILE_PATH = 'coref_javascript_src.db'; +const DEFAULT_FILE_SIZE_LIMIT = 1024; + +/** + * Custom float options or arguments parser + * + * @param value + * @param previous + * @returns + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function customParseFloat(value: string, previous: number): number { + const parsedValue = parseFloat(value); + + if (isNaN(parsedValue)) { + throw new InvalidArgumentError('Not a number.'); + } + + return parsedValue; +} + +/** + * Parse file size limit + * + * @param value + * @param previous + * @returns + */ +function parseFileSizeLimit(value: string, previous: number): number { + const parsedValue = customParseFloat(value, previous); + if (parsedValue <= 0) { + throw new InvalidArgumentError( + "The 'fileSizeLimit' should be greater than 0.", + ); + } + + return parsedValue; +} + +program.name('coref-js-src-extractor').version(version); + +program + .command('extract') + .alias('e') + .requiredOption('-s --src ', 'the source path to extract') + .option('-d --db ', 'the db file path', DEFAULT_DB_FILE_PATH) + .option( + '-b --blacklist ', + 'the source path blacklist, which will be ignored when extracting', + ) + .option('--use-gitignore', 'use the gitignore file to filter source files') + .option('--extract-dist', 'extract dist files') + .option('--extract-deps', 'extract dependencies') + .option( + '--file-size-limit ', + 'the source file size limit in KB', + parseFileSizeLimit, + DEFAULT_FILE_SIZE_LIMIT, + ) + .action(options => { + extract(options.src, options.db, options); + }); + +program.parse(process.argv); diff --git a/language/javascript/extractor/src/model/coref/base-model.ts b/language/javascript/extractor/src/model/coref/base-model.ts new file mode 100644 index 00000000..0ae51f13 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/base-model.ts @@ -0,0 +1,5 @@ + + +export interface BaseModel { + oid: bigint; +} diff --git a/language/javascript/extractor/src/model/coref/binding-element.ts b/language/javascript/extractor/src/model/coref/binding-element.ts new file mode 100644 index 00000000..8e902cdd --- /dev/null +++ b/language/javascript/extractor/src/model/coref/binding-element.ts @@ -0,0 +1,9 @@ + + +import { Node } from './node'; + +export interface BindingElement extends Node { + propertyNameOid?: bigint; + nameOid: bigint; + initializerOid?: bigint; +} diff --git a/language/javascript/extractor/src/model/coref/class.ts b/language/javascript/extractor/src/model/coref/class.ts new file mode 100644 index 00000000..a3eaac57 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/class.ts @@ -0,0 +1,5 @@ + + +import { NamedDeclaration } from './declaration'; + +export interface ClassLikeDeclaration extends NamedDeclaration {} diff --git a/language/javascript/extractor/src/model/coref/comment.ts b/language/javascript/extractor/src/model/coref/comment.ts new file mode 100644 index 00000000..cb78f237 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/comment.ts @@ -0,0 +1,69 @@ + + +import * as ts from 'typescript'; + +import { Location } from './location'; +import { Node, createNode } from './node'; +import { hashToInt64 } from '../../util'; + +export enum CommentKind { + /** A C++-style line comment starting with two slashes. */ + LINE, + + /** A C-style block comment starting with slash-star and ending with star-slash. */ + BLOCK, + + /** The start of an HTML comment (<!--). */ + HTML_START, + + /** The end of an HTML comment (-->). */ + HTML_END, +} + +export type CommentSyntaxKind = + | ts.SyntaxKind.SingleLineCommentTrivia + | ts.SyntaxKind.MultiLineCommentTrivia; + +export interface Comment extends Node { + kind: CommentSyntaxKind; + commentKind: CommentKind; +} + +export enum NodeCommentType { + LEADING = 0, + TRAILING = 1, +} + +export interface NodeComment { + oid: bigint; + nodeOid: bigint; + commentOid: bigint; + type: NodeCommentType; +} + +export function createComment( + kind: CommentSyntaxKind, + location: Location, +): Comment { + const comment = createNode(kind, location) as Comment; + comment.commentKind = + kind === ts.SyntaxKind.SingleLineCommentTrivia + ? CommentKind.LINE + : CommentKind.BLOCK; + return comment; +} + +export function createNodeComment( + nodeOid: bigint, + commentOid: bigint, + type: NodeCommentType, +): NodeComment { + const uri = `${nodeOid}:${commentOid}:${type}`; + const oid = hashToInt64(uri); + return { + oid, + nodeOid, + commentOid, + type, + }; +} diff --git a/language/javascript/extractor/src/model/coref/coref.ts b/language/javascript/extractor/src/model/coref/coref.ts new file mode 100644 index 00000000..0f9dd249 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/coref.ts @@ -0,0 +1,56 @@ + + +import * as coref from './index'; + +/** + * The COREF + */ +export interface Coref { + topLevels: coref.TopLevel[]; + tokens: coref.Token[]; + comments: coref.Comment[]; + nodes: coref.Node[]; + nodeComments: coref.NodeComment[]; + bindingElements: coref.BindingElement[]; + classLikeDeclarations: coref.ClassLikeDeclaration[]; + functionLikeDeclarations: coref.FunctionLikeDeclaration[]; + functionEnclosingNodes: coref.FunctionEnclosingNode[]; + literals: coref.Literal[]; + modifiers: coref.Modifier[]; + cfgEntryNodes: coref.SyntheticCfgNode[]; + cfgExitNodes: coref.SyntheticCfgNode[]; + symbolMap: Map; + nodeSymbolMap: Map; + shorthandAssignmentValueSymbolMap: Map; + callSiteMap: Map; + locations: coref.Location[]; + numbersOfLines: coref.NumberOfLines[]; + files: coref.File[]; +} + +/** + * The COREF extracted from the single file + */ +export interface SingleFileCoref { + topLevels: coref.TopLevel[]; + tokens: coref.Token[]; + comments: coref.Comment[]; + nodes: coref.Node[]; + nodeComments: coref.NodeComment[]; + classLikeDeclarations: coref.ClassLikeDeclaration[]; + functionLikeDeclarations: coref.FunctionLikeDeclaration[]; + functionEnclosingNodes: coref.FunctionEnclosingNode[]; + literals: coref.Literal[]; + locations: coref.Location[]; + numbersOfLines: coref.NumberOfLines[]; + files: coref.File[]; +} + +/** + * The COREF of a file that contains the data related to other files. + */ +export interface CrossFileCoref { + symbolMap: Map; + nodeSymbolMap: Map; + callSiteMap: Map; +} diff --git a/language/javascript/extractor/src/model/coref/declaration.ts b/language/javascript/extractor/src/model/coref/declaration.ts new file mode 100644 index 00000000..690d206c --- /dev/null +++ b/language/javascript/extractor/src/model/coref/declaration.ts @@ -0,0 +1,9 @@ + + +import { Node } from './node'; + +export interface Declaration extends Node {} + +export interface NamedDeclaration extends Declaration { + name?: string; +} diff --git a/language/javascript/extractor/src/model/coref/expression.ts b/language/javascript/extractor/src/model/coref/expression.ts new file mode 100644 index 00000000..d55450f1 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/expression.ts @@ -0,0 +1,5 @@ + + +import { Node } from './node'; + +export interface Expression extends Node {} diff --git a/language/javascript/extractor/src/model/coref/file.ts b/language/javascript/extractor/src/model/coref/file.ts new file mode 100644 index 00000000..e23197ac --- /dev/null +++ b/language/javascript/extractor/src/model/coref/file.ts @@ -0,0 +1,25 @@ + + +import * as path from 'path'; +import { hashToInt64 } from '../../util'; + +import { BaseModel } from './base-model'; + +export interface File extends BaseModel { + name: string; + extension: string; + relativePath: string; + locationOid?: bigint; +} + +export function createFile(relativePath: string): File { + const name = path.basename(relativePath); + const extension = path.extname(name); + const oid = hashToInt64(relativePath); + return { + oid, + name, + extension, + relativePath, + }; +} diff --git a/language/javascript/extractor/src/model/coref/function.ts b/language/javascript/extractor/src/model/coref/function.ts new file mode 100644 index 00000000..32fe371d --- /dev/null +++ b/language/javascript/extractor/src/model/coref/function.ts @@ -0,0 +1,23 @@ + + +import { Node } from './node'; +import { SignatureDeclaration } from './signature-declaration'; + +export interface FunctionLikeDeclaration extends SignatureDeclaration {} + +export interface FunctionEnclosingNode { + nodeOid: bigint; + functionOid: bigint; +} + +export interface CallSite { + invokeExpression: Node; + callee: Node; +} + +export function createCallSite(invokeExpression: Node, callee: Node): CallSite { + return { + invokeExpression, + callee, + }; +} diff --git a/language/javascript/extractor/src/model/coref/ignored-path.ts b/language/javascript/extractor/src/model/coref/ignored-path.ts new file mode 100644 index 00000000..64e6bbf4 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/ignored-path.ts @@ -0,0 +1,53 @@ + + +import { hashToInt64 } from '../../util'; + +/** + * 路径类型枚举 + */ +export enum PathKind { + DIRECTORY, + FILE, +} + +export enum IgnoreKind { + DOT_GITIGNORE, + DIST_DIR, + DIST_FILE, + FILE_SIZE_LIMIT, + BLACK_LIST, +} + +/** + * 忽略的路径 + */ +export interface IgnoredPath { + oid: bigint; + pathKind: PathKind; + path: string; + ignoreKind: IgnoreKind; +} + +/** + * 创建忽略的路径 + * + * @param pathKind 路径类型 + * @param path 路径 + * @param message 备注信息 + * @returns 忽略的路径对象 + */ +export function createIgnoredPath( + pathKind: PathKind, + path: string, + ignoreKind: IgnoreKind, +): IgnoredPath { + const uri = `ignored_path:${path}`; + const oid = hashToInt64(uri); + + return { + oid, + pathKind, + path, + ignoreKind, + }; +} diff --git a/language/javascript/extractor/src/model/coref/index.ts b/language/javascript/extractor/src/model/coref/index.ts new file mode 100644 index 00000000..a114c850 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/index.ts @@ -0,0 +1,23 @@ + + +export * from './base-model'; +export * from './binding-element'; +export * from './comment'; +export * from './coref'; +export * from './expression'; +export * from './file'; +export * from './location'; +export * from './locatable'; +export * from './modifier'; +export * from './node'; +export * from './position'; +export * from './statement'; +export * from './symbol'; +export * from './synthetic-cfg-node'; +export * from './token'; +export * from './class'; +export * from './function'; +export * from './literal'; +export * from './top-level'; +export * from './number-of-lines'; +export * from './ignored-path'; diff --git a/language/javascript/extractor/src/model/coref/literal.ts b/language/javascript/extractor/src/model/coref/literal.ts new file mode 100644 index 00000000..52a88401 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/literal.ts @@ -0,0 +1,7 @@ + + +import { Node } from './node'; + +export interface Literal extends Node { + value: string; +} diff --git a/language/javascript/extractor/src/model/coref/locatable.ts b/language/javascript/extractor/src/model/coref/locatable.ts new file mode 100644 index 00000000..678c5d87 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/locatable.ts @@ -0,0 +1,8 @@ + + +import { BaseModel } from './base-model'; +import { Location } from './location'; + +export interface Locatable extends BaseModel { + location: Location; +} diff --git a/language/javascript/extractor/src/model/coref/location.ts b/language/javascript/extractor/src/model/coref/location.ts new file mode 100644 index 00000000..cc12e62e --- /dev/null +++ b/language/javascript/extractor/src/model/coref/location.ts @@ -0,0 +1,30 @@ + + +import { BaseModel } from './base-model'; +import { Position } from './position'; +import { File } from './file'; +import { hashToInt64 } from '../../util'; + +export interface Location extends BaseModel { + file: File; + start: Position; + end: Position; + text: string; +} + +export function createLocation( + file: File, + start: Position, + end: Position, + text: string, +): Location { + const uri = `${file.relativePath}:(${start.offset}-${end.offset})`; + const oid = hashToInt64(uri); + return { + oid, + file, + start, + end, + text, + }; +} diff --git a/language/javascript/extractor/src/model/coref/modifier.ts b/language/javascript/extractor/src/model/coref/modifier.ts new file mode 100644 index 00000000..cf581f80 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/modifier.ts @@ -0,0 +1,7 @@ + + +import { Node } from './node'; + +export interface Modifier extends Node { + modifierIndex: number; +} diff --git a/language/javascript/extractor/src/model/coref/node.ts b/language/javascript/extractor/src/model/coref/node.ts new file mode 100644 index 00000000..8deca802 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/node.ts @@ -0,0 +1,34 @@ + + +import * as ts from 'typescript'; + +import { BaseModel } from './base-model'; +import { Locatable } from './locatable'; +import { Location } from './location'; +import { hashToInt64 } from '../../util'; + +export type NodeSyntaxKind = ts.SyntaxKind; + +export interface Node extends BaseModel, Locatable { + kind: NodeSyntaxKind; + parent_oid?: bigint; + index?: number; +} + +export function computeNodeOid( + kind: ts.SyntaxKind, + location: Location, +): bigint { + const uri = `node:${kind}:${location.file.relativePath}:(${location.start.offset}-${location.end.offset})`; + const oid = hashToInt64(uri); + return oid; +} + +export function createNode(kind: ts.SyntaxKind, location: Location): Node { + const oid = computeNodeOid(kind, location); + return { + oid, + kind, + location, + }; +} diff --git a/language/javascript/extractor/src/model/coref/number-of-lines.ts b/language/javascript/extractor/src/model/coref/number-of-lines.ts new file mode 100644 index 00000000..aefb2c11 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/number-of-lines.ts @@ -0,0 +1,22 @@ + + +export interface NumberOfLines { + locationOid: bigint; + lines: number; + codeLines: number; + commentLines: number; +} + +export function createNumberOfLines( + locationOid: bigint, + lines: number, + codeLines: number, + commentLines: number, +): NumberOfLines { + return { + locationOid, + lines, + codeLines, + commentLines, + }; +} diff --git a/language/javascript/extractor/src/model/coref/parse-error.ts b/language/javascript/extractor/src/model/coref/parse-error.ts new file mode 100644 index 00000000..074894a4 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/parse-error.ts @@ -0,0 +1,8 @@ + + +import { Position } from './position'; + +export interface ParseError { + message: string; + position: Position; +} diff --git a/language/javascript/extractor/src/model/coref/position.ts b/language/javascript/extractor/src/model/coref/position.ts new file mode 100644 index 00000000..22cad304 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/position.ts @@ -0,0 +1,7 @@ + + +export interface Position { + line: number; + column: number; + offset: number; +} diff --git a/language/javascript/extractor/src/model/coref/signature-declaration.ts b/language/javascript/extractor/src/model/coref/signature-declaration.ts new file mode 100644 index 00000000..b6499721 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/signature-declaration.ts @@ -0,0 +1,5 @@ + + +import { NamedDeclaration } from './declaration'; + +export interface SignatureDeclaration extends NamedDeclaration {} diff --git a/language/javascript/extractor/src/model/coref/statement.ts b/language/javascript/extractor/src/model/coref/statement.ts new file mode 100644 index 00000000..df68e490 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/statement.ts @@ -0,0 +1,5 @@ + + +import { Node } from './node'; + +export interface Statement extends Node {} diff --git a/language/javascript/extractor/src/model/coref/symbol.ts b/language/javascript/extractor/src/model/coref/symbol.ts new file mode 100644 index 00000000..55ec2280 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/symbol.ts @@ -0,0 +1,55 @@ + +/* eslint-disable @typescript-eslint/ban-types */ + +import * as ts from 'typescript'; + +import { BaseModel } from './base-model'; +import { Node } from './node'; + +export interface Symbol extends BaseModel { + name: string; + description: string; +} + +export interface NodeSymbol { + node: Node; + symbol: Symbol; +} + +/** + * Try to get the symbol name + * + * @param tsSymbol the specified ts.Symbol + * @returns symbol name + */ +function getSymbolName(tsSymbol: ts.Symbol): string { + // export default class A + // symbol.name cannot get 'default' instead of 'A' + if (tsSymbol.flags & ts.SymbolFlags.Class && tsSymbol.name === 'default') { + const { + valueDeclaration: { localSymbol }, + } = tsSymbol as any; + if (localSymbol != null) { + return localSymbol.name; + } + + // export default class { } + // class without a name + return 'default'; + } + + // other cases + return tsSymbol.name; +} + +export function createSymbol( + oid: bigint, + tsSymbol: ts.Symbol, + description: string, +): Symbol { + return { + oid, + name: getSymbolName(tsSymbol), + description, + }; +} diff --git a/language/javascript/extractor/src/model/coref/synthetic-cfg-node.ts b/language/javascript/extractor/src/model/coref/synthetic-cfg-node.ts new file mode 100644 index 00000000..7fa0c0b7 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/synthetic-cfg-node.ts @@ -0,0 +1,53 @@ + + +import { hashToInt64 } from '../../util'; + +export interface SyntheticCfgNode { + oid: bigint; + astNodeOid: bigint; +} + +export const enum SyntheticCfgNodeKind { + Entry, + Exit, +} + +/** + * Create a synthetic CFG node, which is a entry or exit node. + * + * @param astNodeOid + * @param kind + * @returns + */ +function createSyntheticCfgNode( + astNodeOid: bigint, + kind: SyntheticCfgNodeKind, +): SyntheticCfgNode { + const kindName = kind === SyntheticCfgNodeKind.Entry ? 'entry' : 'exit'; + const uri = `cfg:${kindName}:${astNodeOid}`; + const oid = hashToInt64(uri); + return { + oid, + astNodeOid, + }; +} + +/** + * Create a CFG entry node + * + * @param astNodeOid + * @returns + */ +export function createCfgEntryNode(astNodeOid: bigint) { + return createSyntheticCfgNode(astNodeOid, SyntheticCfgNodeKind.Entry); +} + +/** + * Create a CFG exit node + * + * @param astNodeOid + * @returns + */ +export function createCfgExitNode(astNodeOid: bigint) { + return createSyntheticCfgNode(astNodeOid, SyntheticCfgNodeKind.Exit); +} diff --git a/language/javascript/extractor/src/model/coref/token.ts b/language/javascript/extractor/src/model/coref/token.ts new file mode 100644 index 00000000..3c983c08 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/token.ts @@ -0,0 +1,16 @@ + + +import * as ts from 'typescript'; + +import { Location } from './location'; +import { Node, createNode } from './node'; + +export type TokenSyntaxKind = ts.TokenSyntaxKind; + +export interface Token extends Node { + kind: TokenSyntaxKind; +} + +export function createToken(kind: TokenSyntaxKind, location: Location): Token { + return createNode(kind, location) as Token; +} diff --git a/language/javascript/extractor/src/model/coref/top-level.ts b/language/javascript/extractor/src/model/coref/top-level.ts new file mode 100644 index 00000000..8cdb08c1 --- /dev/null +++ b/language/javascript/extractor/src/model/coref/top-level.ts @@ -0,0 +1,31 @@ + + +import { BaseModel } from './base-model'; +import { Location } from './location'; +import { hashToInt64 } from '../../util'; + +export enum TopLevelKind { + SCRIPT, + INLINE_SCRIPT, + EVENT_HANDLER, + JAVASCRIPT_URL, +} + +export interface TopLevel extends BaseModel { + kind: TopLevelKind; + location: Location; +} + +export function createTopLevel( + kind: TopLevelKind, + location: Location, +): TopLevel { + const uri = `top_level:${kind}:${location.file.relativePath}:(${location.start.offset}-${location.end.offset})`; + const oid = hashToInt64(uri); + + return { + oid, + kind, + location, + }; +} diff --git a/language/javascript/extractor/src/model/extended-ts/binding-element.ts b/language/javascript/extractor/src/model/extended-ts/binding-element.ts new file mode 100644 index 00000000..ed0521ae --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/binding-element.ts @@ -0,0 +1,10 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; +import { NodeBase } from './node'; + +export interface BindingElement extends ts.BindingElement, NodeBase { + $corefModel: coref.BindingElement; +} diff --git a/language/javascript/extractor/src/model/extended-ts/class.ts b/language/javascript/extractor/src/model/extended-ts/class.ts new file mode 100644 index 00000000..659b281c --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/class.ts @@ -0,0 +1,16 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; +import { NodeBase } from './node'; + +export interface ClassDeclaration extends ts.ClassDeclaration, NodeBase { + $corefModel?: coref.Node; +} + +export interface ClassExpression extends ts.ClassExpression, NodeBase { + $corefModel?: coref.Node; +} + +export type ClassLikeDeclaration = ClassDeclaration | ClassExpression; diff --git a/language/javascript/extractor/src/model/extended-ts/expression.ts b/language/javascript/extractor/src/model/extended-ts/expression.ts new file mode 100644 index 00000000..244bf09f --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/expression.ts @@ -0,0 +1,53 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; +import { NodeBase } from './node'; + +export interface ExpressionBase extends NodeBase { + $corefModel?: coref.Expression; +} + +export interface Expression extends ts.Expression, ExpressionBase {} + +export interface CallExpression extends ts.CallExpression, ExpressionBase {} + +export interface NewExpression extends ts.NewExpression, ExpressionBase {} + +export interface TaggedTemplateExpression + extends ts.TaggedTemplateExpression, + ExpressionBase {} + +export interface Decorator extends ts.Decorator, ExpressionBase {} + +export interface JsxSelfClosingElement + extends ts.JsxSelfClosingElement, + ExpressionBase {} + +export interface JsxOpeningElement + extends ts.JsxOpeningElement, + ExpressionBase {} + +export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + +export type CallLikeExpression = + | CallExpression + | NewExpression + | TaggedTemplateExpression + | Decorator + | JsxOpeningLikeElement; + +export interface PropertyAccessExpression + extends ts.PropertyAccessExpression, + ExpressionBase {} + +export interface ElementAccessExpression + extends ts.ElementAccessExpression, + ExpressionBase {} + +export type AccessExpression = + | PropertyAccessExpression + | ElementAccessExpression; + +export type MayInvokeExpression = CallLikeExpression | AccessExpression; diff --git a/language/javascript/extractor/src/model/extended-ts/function.ts b/language/javascript/extractor/src/model/extended-ts/function.ts new file mode 100644 index 00000000..2cc78999 --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/function.ts @@ -0,0 +1,34 @@ + + +import * as ts from 'typescript'; + +import { NodeBase } from './node'; + +export interface FunctionDeclaration extends ts.FunctionDeclaration, NodeBase {} + +export interface MethodDeclaration extends ts.MethodDeclaration, NodeBase {} + +export interface GetAccessorDeclaration + extends ts.GetAccessorDeclaration, + NodeBase {} + +export interface SetAccessorDeclaration + extends ts.SetAccessorDeclaration, + NodeBase {} + +export interface ConstructorDeclaration + extends ts.ConstructorDeclaration, + NodeBase {} + +export interface FunctionExpression extends ts.FunctionExpression, NodeBase {} + +export interface ArrowFunction extends ts.ArrowFunction, NodeBase {} + +export type FunctionLikeDeclaration = + | FunctionDeclaration + | MethodDeclaration + | GetAccessorDeclaration + | SetAccessorDeclaration + | ConstructorDeclaration + | FunctionExpression + | ArrowFunction; diff --git a/language/javascript/extractor/src/model/extended-ts/index.ts b/language/javascript/extractor/src/model/extended-ts/index.ts new file mode 100644 index 00000000..7d478654 --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/index.ts @@ -0,0 +1,10 @@ + + +export * from './binding-element'; +export * from './class'; +export * from './expression'; +export * from './function'; +export * from './modifier'; +export * from './node'; +export * from './source-file'; +export * from './statement'; diff --git a/language/javascript/extractor/src/model/extended-ts/modifier.ts b/language/javascript/extractor/src/model/extended-ts/modifier.ts new file mode 100644 index 00000000..f0797856 --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/modifier.ts @@ -0,0 +1,12 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; +import { NodeBase } from './node'; + +export interface Modifier + extends ts.ModifierToken, + NodeBase { + $corefModel: coref.Modifier; +} diff --git a/language/javascript/extractor/src/model/extended-ts/node.ts b/language/javascript/extractor/src/model/extended-ts/node.ts new file mode 100644 index 00000000..cb55a77b --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/node.ts @@ -0,0 +1,12 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; + +export interface NodeBase { + $corefModel?: coref.BaseModel; + symbol?: ts.Symbol; +} + +export interface Node extends ts.Node, NodeBase {} diff --git a/language/javascript/extractor/src/model/extended-ts/source-file.ts b/language/javascript/extractor/src/model/extended-ts/source-file.ts new file mode 100644 index 00000000..ff4b6257 --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/source-file.ts @@ -0,0 +1,16 @@ + + +import * as ts from 'typescript'; + +import * as coref from '../coref'; + +/** + * The ts.SourceFile interface with internal properties and COREF properties + */ +export interface SourceFile extends ts.SourceFile { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + parseDiagnostics?: any[]; + + $file?: coref.File; + $corefModel?: coref.TopLevel; +} diff --git a/language/javascript/extractor/src/model/extended-ts/statement.ts b/language/javascript/extractor/src/model/extended-ts/statement.ts new file mode 100644 index 00000000..f7eebd3d --- /dev/null +++ b/language/javascript/extractor/src/model/extended-ts/statement.ts @@ -0,0 +1,14 @@ + + +import * as ts from 'typescript'; + +import { NodeBase } from './node'; +import * as coref from '../coref'; + +export interface StatementBase extends NodeBase { + $corefModel?: coref.Statement; +} + +export interface Statement extends ts.Statement, StatementBase {} + +export interface ForStatement extends ts.ForStatement, StatementBase {} diff --git a/language/javascript/extractor/src/model/index.ts b/language/javascript/extractor/src/model/index.ts new file mode 100644 index 00000000..f01c4909 --- /dev/null +++ b/language/javascript/extractor/src/model/index.ts @@ -0,0 +1,4 @@ + + +export * as coref from './coref'; +export * as extendedTs from './extended-ts'; diff --git a/language/javascript/extractor/src/util.ts b/language/javascript/extractor/src/util.ts new file mode 100644 index 00000000..4afcd186 --- /dev/null +++ b/language/javascript/extractor/src/util.ts @@ -0,0 +1,53 @@ + + +import { createHash } from 'crypto'; + +const INT64_MIN = -9223372036854775808n; +const INT64_HEX_LENGTH = 16; + +/** + * 计算一段内容的哈希,得到64位整型的哈希值 + * + * @param value 哈希的内容 + * @returns int64 的哈希值 + */ +export function hashToInt64(value: string): bigint { + const hash = createHash('sha1'); + hash.update(value); + const hexHash = hash.digest('hex'); + + // 截取前16位来计算 int64 的哈希 + const hexHashPrefix = hexHash.substring(0, INT64_HEX_LENGTH); + const unsignedBigIntHash = BigInt(`0x${hexHashPrefix}`); + + // 转换为有符号的 int64 + const bigIntHash: bigint = INT64_MIN + unsignedBigIntHash; + + return bigIntHash; +} + +/** + * 限流执行 Promise 的 pool + * + * @param iterable + * @param asyncFunction + * @param poolSize + */ +export async function asyncPool( + iterable: Iterable, + asyncFunction: (value: T) => Promise, + poolSize: number, +) { + const executingPromises: Promise[] = []; + for (const entry of iterable) { + while (executingPromises.length >= poolSize) { + await Promise.race(executingPromises); + } + const promise = asyncFunction(entry); + executingPromises.push(promise); + promise.then(() => + executingPromises.splice(executingPromises.indexOf(promise), 1), + ); + } + await Promise.all(executingPromises); +} diff --git a/language/javascript/extractor/tests/control-flow/as-expr.ts b/language/javascript/extractor/tests/control-flow/as-expr.ts new file mode 100644 index 00000000..4bd8e6f0 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/as-expr.ts @@ -0,0 +1,4 @@ +function* test(arg: number | string) { + (arg as string) += ''; + console.log(arg); +} diff --git a/language/javascript/extractor/tests/control-flow/binary-logical-expr.ts b/language/javascript/extractor/tests/control-flow/binary-logical-expr.ts new file mode 100644 index 00000000..2a84dcea --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/binary-logical-expr.ts @@ -0,0 +1,12 @@ +function test(arg: number) { + if (arg > 0 && arg < 100) { + if (arg < 10 || arg > 2) { + arg += 5; + } + } else { + arg += 1; + } + let x = arg ?? 1; + console.log(arg); + console.log(x); +} diff --git a/language/javascript/extractor/tests/control-flow/class-declaration.ts b/language/javascript/extractor/tests/control-flow/class-declaration.ts new file mode 100644 index 00000000..0b27ffd9 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/class-declaration.ts @@ -0,0 +1,4 @@ +function test() { + class A {} + let x = 1; +} diff --git a/language/javascript/extractor/tests/control-flow/class-expr.ts b/language/javascript/extractor/tests/control-flow/class-expr.ts new file mode 100644 index 00000000..7a5fa2f5 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/class-expr.ts @@ -0,0 +1,19 @@ +function test() { + const Rectangle = class { + height: number; + width: number; + + constructor(height: number, width: number) { + this.height = height; + this.width = width; + } + + area() { + return this.height * this.width; + } + }; + + console.log(new Rectangle(5, 8).area()); +} + +test(); diff --git a/language/javascript/extractor/tests/control-flow/conditional-expr.ts b/language/javascript/extractor/tests/control-flow/conditional-expr.ts new file mode 100644 index 00000000..66396378 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/conditional-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number) { + let x = arg > 1 ? 2 : 3; + x = 4; +} diff --git a/language/javascript/extractor/tests/control-flow/enum.ts b/language/javascript/extractor/tests/control-flow/enum.ts new file mode 100644 index 00000000..ed871f6f --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/enum.ts @@ -0,0 +1,10 @@ +function test() { + enum Direction { + Up = 1, + Down, + } + console.log(Direction.Up); + console.log(Direction.Down); +} + +test(); diff --git a/language/javascript/extractor/tests/control-flow/function-expr.ts b/language/javascript/extractor/tests/control-flow/function-expr.ts new file mode 100644 index 00000000..53615bb1 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/function-expr.ts @@ -0,0 +1,6 @@ +function test() { + const getRectArea = function (width, height) { + return width * height; + }; + console.log(getRectArea(3, 4)); +} diff --git a/language/javascript/extractor/tests/control-flow/if-stmt.ts b/language/javascript/extractor/tests/control-flow/if-stmt.ts new file mode 100644 index 00000000..1e1973f2 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/if-stmt.ts @@ -0,0 +1,13 @@ +function test(arg: number | string) { + // arg type: number, string + if (typeof arg === 'number') { + // arg type is narrowed to: number + if (arg == 0) { + arg += 1; + } + } else { + // arg type is narrowed to: string + arg += 'xy'; + } + console.log(arg); +} diff --git a/language/javascript/extractor/tests/control-flow/loop-statements/do-while-statement.ts b/language/javascript/extractor/tests/control-flow/loop-statements/do-while-statement.ts new file mode 100644 index 00000000..daa5dfba --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/loop-statements/do-while-statement.ts @@ -0,0 +1,20 @@ +function test() { + let i = 0; + do { + if (i === 1) { + continue; + } + + console.log(i); + + if (i < 3) { + break; + } + + if (i > 5) { + return; + } + + i += 1; + } while (i < 4); +} diff --git a/language/javascript/extractor/tests/control-flow/loop-statements/enhanced-for-statement.ts b/language/javascript/extractor/tests/control-flow/loop-statements/enhanced-for-statement.ts new file mode 100644 index 00000000..79a08471 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/loop-statements/enhanced-for-statement.ts @@ -0,0 +1,14 @@ +async function test() { + const arr = [3, 5, 7]; + arr.foo = 'hello'; + + for (const i in arr) { + console.log(i); + } + // "0" "1" "2" "foo" + + for await (const j of arr) { + console.log(j); + } + // 3 5 7 +} diff --git a/language/javascript/extractor/tests/control-flow/loop-statements/for-statement.ts b/language/javascript/extractor/tests/control-flow/loop-statements/for-statement.ts new file mode 100644 index 00000000..f4d53bd9 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/loop-statements/for-statement.ts @@ -0,0 +1,18 @@ +function test() { + for (let i = 0; i < 3; i++) { + console.log(i); + } + + for (let j = 0; j < 4; ) { + console.log(j); + j++; + } + + let k = 0; + for (; ; k++) { + if (k > 5) { + break; + } + console.log(k); + } +} diff --git a/language/javascript/extractor/tests/control-flow/loop-statements/while-statement.ts b/language/javascript/extractor/tests/control-flow/loop-statements/while-statement.ts new file mode 100644 index 00000000..6b3898ae --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/loop-statements/while-statement.ts @@ -0,0 +1,20 @@ +function test() { + let i = 0; + + while (i < 5) { + if (i === 1) { + continue; + } + + if (i < 3) { + break; + } + + if (i > 4) { + return; + } + + console.log(i); + i++; + } +} diff --git a/language/javascript/extractor/tests/control-flow/object-literal-expr.ts b/language/javascript/extractor/tests/control-flow/object-literal-expr.ts new file mode 100644 index 00000000..815b677f --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/object-literal-expr.ts @@ -0,0 +1,11 @@ +function test() { + let obj = { + id: 5, + name: 'www', + dump() { + console.log(this.id); + }, + }; + + obj.dump(); +} diff --git a/language/javascript/extractor/tests/control-flow/return-stmt.ts b/language/javascript/extractor/tests/control-flow/return-stmt.ts new file mode 100644 index 00000000..bb353fc4 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/return-stmt.ts @@ -0,0 +1,6 @@ +function test(arg: number | string) { + if (arg == 1) { + return; + } + arg = 2; +} diff --git a/language/javascript/extractor/tests/control-flow/spread-element.ts b/language/javascript/extractor/tests/control-flow/spread-element.ts new file mode 100644 index 00000000..83f1a56e --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/spread-element.ts @@ -0,0 +1,4 @@ +function test(arg: number | string) { + let xx = [1, 2, 3]; + console.log(...xx); +} diff --git a/language/javascript/extractor/tests/control-flow/switch-stmt.ts b/language/javascript/extractor/tests/control-flow/switch-stmt.ts new file mode 100644 index 00000000..3f7ce16c --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/switch-stmt.ts @@ -0,0 +1,29 @@ +function test_case_body_is_not_block(i: number) { + let x = 0; + switch (i) { + case 1: + x = 1; + x = -1; + case 2: + x = 2; + x = -2; + default: + x = 666; + x = -666; + } + console.log(x); +} + +function test_with_break(i: number) { + let x = 0; + switch (i) { + case 1: + x = 1; + break; + case 2: + x = 2; + default: + x = 666; + } + console.log(x); +} diff --git a/language/javascript/extractor/tests/control-flow/throw-stmt.ts b/language/javascript/extractor/tests/control-flow/throw-stmt.ts new file mode 100644 index 00000000..f0dbd30f --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/throw-stmt.ts @@ -0,0 +1,5 @@ +function test() { + let x = 1; + throw 'error'; + x = 2; +} diff --git a/language/javascript/extractor/tests/control-flow/try-stmt.ts b/language/javascript/extractor/tests/control-flow/try-stmt.ts new file mode 100644 index 00000000..e3815eb3 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/try-stmt.ts @@ -0,0 +1,23 @@ +function test_try_catch(i: number) { + i = 0; + try { + i = 1; + } catch (error) { + i = 2; + console.error(i); + } + i = -1; +} + +function test_try_catch_finally(i: number) { + i = 0; + try { + i = 1; + } catch (error) { + i = 2; + console.error(i); + } finally { + i = 3; + } + i = -1; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-array-literal-expr.ts b/language/javascript/extractor/tests/control-flow/unary-array-literal-expr.ts new file mode 100644 index 00000000..f87aa6b9 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-array-literal-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number) { + let x = [1, 2, 3]; + console.log(x); +} diff --git a/language/javascript/extractor/tests/control-flow/unary-await-expr.ts b/language/javascript/extractor/tests/control-flow/unary-await-expr.ts new file mode 100644 index 00000000..f6946d89 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-await-expr.ts @@ -0,0 +1,4 @@ +async function test(arg: number | string) { + const num = await Promise.resolve(42); + return num; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-delete-expr.ts b/language/javascript/extractor/tests/control-flow/unary-delete-expr.ts new file mode 100644 index 00000000..153cc66b --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-delete-expr.ts @@ -0,0 +1,8 @@ +interface Object { + x?: number; +} + +function test(arg: Object) { + delete arg.x; + let x = 1; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-expression-prefix-and-postfix.ts b/language/javascript/extractor/tests/control-flow/unary-expression-prefix-and-postfix.ts new file mode 100644 index 00000000..4771ca85 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-expression-prefix-and-postfix.ts @@ -0,0 +1,11 @@ +function test(arg: number | string) { + let x = 1; + x++; + x--; + ++x; + --x; + -x; + ~x; + !x; + x = 2; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-new-expr.ts b/language/javascript/extractor/tests/control-flow/unary-new-expr.ts new file mode 100644 index 00000000..f307a68f --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-new-expr.ts @@ -0,0 +1,14 @@ +class TestClass { + f1: string; + f2: number; + + constructor(f1: string, f2: number) { + this.f1 = f1; + this.f2 = f2; + } +} + +function test() { + let tc = new TestClass('h', 2); + console.log(tc); +} diff --git a/language/javascript/extractor/tests/control-flow/unary-non-null-expr.ts b/language/javascript/extractor/tests/control-flow/unary-non-null-expr.ts new file mode 100644 index 00000000..899106a1 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-non-null-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number | string) { + let x = arg!; + console.log(arg); +} diff --git a/language/javascript/extractor/tests/control-flow/unary-parenthesized-expr.ts b/language/javascript/extractor/tests/control-flow/unary-parenthesized-expr.ts new file mode 100644 index 00000000..55bd5c0b --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-parenthesized-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number) { + let x = 1; + x = 4; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-type-assertion-expr.ts b/language/javascript/extractor/tests/control-flow/unary-type-assertion-expr.ts new file mode 100644 index 00000000..25fca453 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-type-assertion-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number | string) { + let x = 1; + let y = x; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-typeof-expr.ts b/language/javascript/extractor/tests/control-flow/unary-typeof-expr.ts new file mode 100644 index 00000000..d6382fa9 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-typeof-expr.ts @@ -0,0 +1,4 @@ +function test(arg: number | string) { + let x = typeof arg; + x += 'x'; +} diff --git a/language/javascript/extractor/tests/control-flow/unary-void-expression.ts b/language/javascript/extractor/tests/control-flow/unary-void-expression.ts new file mode 100644 index 00000000..63db9b82 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/unary-void-expression.ts @@ -0,0 +1,4 @@ +function test(arg: number | string) { + void 2 === '2'; + let x = 1; +} diff --git a/language/javascript/extractor/tests/control-flow/variable-declaration.ts b/language/javascript/extractor/tests/control-flow/variable-declaration.ts new file mode 100644 index 00000000..d7db29a2 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/variable-declaration.ts @@ -0,0 +1,10 @@ +function test() { + let a; + + let b: number[]; + + let [c, d] = [1, 2]; + + let e: number[] = [1, 2, 3], + f!: string; +} diff --git a/language/javascript/extractor/tests/control-flow/with-stmt.ts b/language/javascript/extractor/tests/control-flow/with-stmt.ts new file mode 100644 index 00000000..bf76861e --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/with-stmt.ts @@ -0,0 +1,9 @@ +function test() { + with ([1, 2, 3]) { + console.log(toString()); // 1,2,3 + } + + // with (1) { + // console.log(toString()) + // } +} diff --git a/language/javascript/extractor/tests/control-flow/yield-expr.ts b/language/javascript/extractor/tests/control-flow/yield-expr.ts new file mode 100644 index 00000000..ce2e42e1 --- /dev/null +++ b/language/javascript/extractor/tests/control-flow/yield-expr.ts @@ -0,0 +1,6 @@ +function* test(arg: number | string) { + if (arg == 1) { + yield 2; + } + arg = 2; +} diff --git a/language/javascript/extractor/tests/data-flow/object.ts b/language/javascript/extractor/tests/data-flow/object.ts new file mode 100644 index 00000000..824a1ecc --- /dev/null +++ b/language/javascript/extractor/tests/data-flow/object.ts @@ -0,0 +1,35 @@ +const prop1 = { + a: 'a', + o: { + x: 'x', + y: 'y', + }, +}; + +const { result: prop2 } = getResult(); + +const { + result: { + config: { m }, + }, +} = { + result: { + config: { + m: 'm', + }, + }, +}; + +const otherProps = { + prop4: 'prop4', + prop5: prop1, +}; + +otherProps.prop6 = 'prop6'; + +const result = { + prop1, + prop2, + prop3: m, + ...otherProps, +}; diff --git a/language/javascript/extractor/tests/def-use/binding-pattern.ts b/language/javascript/extractor/tests/def-use/binding-pattern.ts new file mode 100644 index 00000000..4486379b --- /dev/null +++ b/language/javascript/extractor/tests/def-use/binding-pattern.ts @@ -0,0 +1,8 @@ +const [, a, , b = 4] = [1, 2, 3]; +const { x, b: y, ...z } = { x: 1, b: 2, c: 3, d: 4 }; + +console.log(a); +console.log(b); +console.log(x); +console.log(y); +console.log(z); diff --git a/language/javascript/extractor/tests/ts/binding-pattern.ts b/language/javascript/extractor/tests/ts/binding-pattern.ts new file mode 100644 index 00000000..58dfeb85 --- /dev/null +++ b/language/javascript/extractor/tests/ts/binding-pattern.ts @@ -0,0 +1,2 @@ +const [, a, , b = 4] = [1, 2, 3]; +const { x, b: y, ...z } = { x: 1, b: 2, c: 3, d: 4 }; diff --git a/language/javascript/extractor/tests/ts/comment.ts b/language/javascript/extractor/tests/ts/comment.ts new file mode 100644 index 00000000..ca76dabb --- /dev/null +++ b/language/javascript/extractor/tests/ts/comment.ts @@ -0,0 +1,9 @@ + + +// test1 +const test1 = 1; // test1 + +/** test2 */ +const test2 = 2; /** test2 */ + +// test3 diff --git a/language/javascript/extractor/tests/ts/for-statement.ts b/language/javascript/extractor/tests/ts/for-statement.ts new file mode 100644 index 00000000..358b5e09 --- /dev/null +++ b/language/javascript/extractor/tests/ts/for-statement.ts @@ -0,0 +1,19 @@ +let i = 0; + +for (; i < 5; i++) { + console.log(i); +} + +for (i = 0; ; ) { + console.log(i); + + if (i === 1) { + continue; + } + + if (i > 4) { + break; + } + + i++; +} diff --git a/language/javascript/extractor/tests/ts/function.ts b/language/javascript/extractor/tests/ts/function.ts new file mode 100644 index 00000000..21f76d27 --- /dev/null +++ b/language/javascript/extractor/tests/ts/function.ts @@ -0,0 +1,10 @@ +function greeter(fn: (a: TypeA, b: TypeB) => TypeA) { + fn('Hello', 'World'); +} + +function printToConsole(a: TypeA, b: TypeB): TypeA { + console.log(a, b); + return a; +} + +greeter(printToConsole); diff --git a/language/javascript/extractor/tests/ts/heritage-clause.ts b/language/javascript/extractor/tests/ts/heritage-clause.ts new file mode 100644 index 00000000..380679aa --- /dev/null +++ b/language/javascript/extractor/tests/ts/heritage-clause.ts @@ -0,0 +1,11 @@ +interface Animal { + name: string; +} + +interface Bear extends Animal { + honey: boolean; +} + +class Cat implements Animal { + name = 'Cat'; +} diff --git a/language/javascript/extractor/tests/ts/meta-property.ts b/language/javascript/extractor/tests/ts/meta-property.ts new file mode 100644 index 00000000..bd14f943 --- /dev/null +++ b/language/javascript/extractor/tests/ts/meta-property.ts @@ -0,0 +1 @@ +import.meta.url; diff --git a/language/javascript/extractor/tests/ts/parameter.ts b/language/javascript/extractor/tests/ts/parameter.ts new file mode 100644 index 00000000..7b022a75 --- /dev/null +++ b/language/javascript/extractor/tests/ts/parameter.ts @@ -0,0 +1,28 @@ +type DescribableFunction = { + description: string; + (someArg: number): boolean; +}; + +function doSomething(fn: DescribableFunction) { + console.log(fn.description + ' returned ' + fn(6)); +} + +function myForEach(arr: any[], callback: (arg: any, index?: number) => void) { + for (let i = 0; i < arr.length; i++) { + callback(arr[i], i); + } +} + +const a = 0; + +function makeDate(mOrTimestamp: number = a, d?: number, y?: number): Date { + if (d !== undefined && y !== undefined) { + return new Date(y, mOrTimestamp, d); + } else { + return new Date(mOrTimestamp); + } +} + +function multiply(n: number, ...m: number[]) { + return m.map(x => n * x); +} diff --git a/language/javascript/extractor/tests/ts/type-operator.ts b/language/javascript/extractor/tests/ts/type-operator.ts new file mode 100644 index 00000000..a06f4f9e --- /dev/null +++ b/language/javascript/extractor/tests/ts/type-operator.ts @@ -0,0 +1,2 @@ +type Point = { x: number; y: number }; +type P = keyof Point; diff --git a/language/javascript/extractor/tsconfig.json b/language/javascript/extractor/tsconfig.json new file mode 100644 index 00000000..2f48f26c --- /dev/null +++ b/language/javascript/extractor/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "moduleResolution": "node", + "strict": true, + "importHelpers": true, + "resolveJsonModule": true, + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "composite": true, + "outDir": "dist" + }, + "include": ["src/**/*", "package.json"], + "exclude": ["node_modules/**/*", "**/__test__/**/*"] +} diff --git a/language/javascript/extractor/yarn.lock b/language/javascript/extractor/yarn.lock new file mode 100644 index 00000000..fabe1b6a --- /dev/null +++ b/language/javascript/extractor/yarn.lock @@ -0,0 +1,3792 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.npmmirror.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" + integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== + dependencies: + "@babel/highlight" "^7.22.10" + chalk "^2.4.2" + +"@babel/compat-data@^7.20.0": + version "7.20.1" + resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" + integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== + +"@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + +"@babel/core@^7.11.6": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" + integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.10" + "@babel/parser" "^7.22.10" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.1" + +"@babel/core@^7.12.3": + version "7.20.2" + resolved "https://registry.npmmirror.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" + integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.2" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-module-transforms" "^7.20.2" + "@babel/helpers" "^7.20.1" + "@babel/parser" "^7.20.2" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@7.18.2": + version "7.18.2" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d" + integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== + dependencies: + "@babel/types" "^7.18.2" + "@jridgewell/gen-mapping" "^0.3.0" + jsesc "^2.5.1" + +"@babel/generator@^7.20.1", "@babel/generator@^7.20.2", "@babel/generator@^7.7.2": + version "7.20.3" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.20.3.tgz#e58c9ae2f7bf7fdf4899160cf1e04400a82cd641" + integrity sha512-Wl5ilw2UD1+ZYprHVprxHZJCFeBWlzZYOovE4SDYLZnqCOD11j+0QzNeEWKLLTWM7nixrZEh7vNIyb76MyJg3A== + dependencies: + "@babel/types" "^7.20.2" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/generator@^7.22.10": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" + integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== + dependencies: + "@babel/types" "^7.22.10" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.20.0": + version "7.20.0" + resolved "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== + dependencies: + "@babel/compat-data" "^7.20.0" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + +"@babel/helper-compilation-targets@^7.22.10": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" + integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.20.2": + version "7.20.2" + resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" + integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" + +"@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0": + version "7.20.2" + resolved "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.18.10", "@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.20.1": + version "7.20.1" + resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" + integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.0" + +"@babel/helpers@^7.22.10": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" + integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.10" + "@babel/types" "^7.22.10" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/highlight@^7.22.10": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" + integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@7.18.4": + version "7.18.4" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef" + integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": + version "7.20.3" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" + integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== + +"@babel/parser@^7.22.10", "@babel/parser@^7.22.5": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" + integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.20.0" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + +"@babel/template@^7.18.10", "@babel/template@^7.3.3": + version "7.18.10" + resolved "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.20.1": + version "7.20.1" + resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" + integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.1" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.1" + "@babel/types" "^7.20.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.22.10": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" + integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig== + dependencies: + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.10" + "@babel/types" "^7.22.10" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@7.19.0": + version "7.19.0" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" + integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== + dependencies: + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.20.2" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" + integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@babel/types@^7.18.2": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@babel/types@^7.22.10", "@babel/types@^7.22.5": + version "7.22.10" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" + integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@bazel/typescript@^5.8.1": + version "5.8.1" + resolved "https://registry.npmmirror.com/@bazel/typescript/-/typescript-5.8.1.tgz#74a76af434fad7930893cf3e98b4cc201e52dc65" + integrity sha512-NAJ8WQHZL1WE1YmRoCrq/1hhG15Mvy/viWh6TkvFnBeEhNUiQUsA5GYyhU1ztnBIYW03nATO3vwhAEfO7Q0U5g== + dependencies: + "@bazel/worker" "5.8.1" + semver "5.6.0" + source-map-support "0.5.9" + tsutils "3.21.0" + +"@bazel/worker@5.8.1": + version "5.8.1" + resolved "https://registry.npmmirror.com/@bazel/worker/-/worker-5.8.1.tgz#65af7a70dd2f1aaedd6c19330abd9a198f96e7b2" + integrity sha512-GMyZSNW3F34f9GjbJqvs1aHyed5BNrNeiDzNJhC1fIizo/UeBM21oBBONIYLBDoBtq936U85VyPZ76JaP/83hw== + dependencies: + google-protobuf "^3.6.1" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + +"@eslint/eslintrc@^2.1.1": + version "2.1.1" + resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.1.tgz#18d635e24ad35f7276e8a49d135c7d3ca6a46f93" + integrity sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@^8.46.0": + version "8.46.0" + resolved "https://registry.npmmirror.com/@eslint/js/-/js-8.46.0.tgz#3f7802972e8b6fe3f88ed1aabc74ec596c456db6" + integrity sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/console/-/console-29.6.2.tgz#bf1d4101347c23e07c029a1b1ae07d550f5cc541" + integrity sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + slash "^3.0.0" + +"@jest/core@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/core/-/core-29.6.2.tgz#6f2d1dbe8aa0265fcd4fb8082ae1952f148209c8" + integrity sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg== + dependencies: + "@jest/console" "^29.6.2" + "@jest/reporters" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.5.0" + jest-config "^29.6.2" + jest-haste-map "^29.6.2" + jest-message-util "^29.6.2" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-resolve-dependencies "^29.6.2" + jest-runner "^29.6.2" + jest-runtime "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + jest-watcher "^29.6.2" + micromatch "^4.0.4" + pretty-format "^29.6.2" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" + integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== + dependencies: + "@jest/fake-timers" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.2" + +"@jest/expect-utils@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.6.2.tgz#1b97f290d0185d264dd9fdec7567a14a38a90534" + integrity sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg== + dependencies: + jest-get-type "^29.4.3" + +"@jest/expect@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/expect/-/expect-29.6.2.tgz#5a2ad58bb345165d9ce0a1845bbf873c480a4b28" + integrity sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg== + dependencies: + expect "^29.6.2" + jest-snapshot "^29.6.2" + +"@jest/fake-timers@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" + integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== + dependencies: + "@jest/types" "^29.6.1" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.6.2" + jest-mock "^29.6.2" + jest-util "^29.6.2" + +"@jest/globals@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/globals/-/globals-29.6.2.tgz#74af81b9249122cc46f1eb25793617eec69bf21a" + integrity sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/expect" "^29.6.2" + "@jest/types" "^29.6.1" + jest-mock "^29.6.2" + +"@jest/reporters@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/reporters/-/reporters-29.6.2.tgz#524afe1d76da33d31309c2c4a2c8062d0c48780a" + integrity sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + jest-worker "^29.6.2" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.0": + version "29.6.0" + resolved "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" + integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.0": + version "29.6.0" + resolved "https://registry.npmmirror.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" + integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/test-result/-/test-result-29.6.2.tgz#fdd11583cd1608e4db3114e8f0cce277bf7a32ed" + integrity sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw== + dependencies: + "@jest/console" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz#585eff07a68dd75225a7eacf319780cb9f6b9bf4" + integrity sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw== + dependencies: + "@jest/test-result" "^29.6.2" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + slash "^3.0.0" + +"@jest/transform@^29.6.2": + version "29.6.2" + resolved "https://registry.npmmirror.com/@jest/transform/-/transform-29.6.2.tgz#522901ebbb211af08835bc3bcdf765ab778094e3" + integrity sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-regex-util "^29.4.3" + jest-util "^29.6.2" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.1": + version "29.6.1" + resolved "https://registry.npmmirror.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" + integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== + dependencies: + "@jest/schemas" "^29.6.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.3" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18": + version "0.3.19" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.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.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.npmmirror.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" + +"@prisma/client@^5.1.1": + version "5.1.1" + resolved "https://registry.npmmirror.com/@prisma/client/-/client-5.1.1.tgz#ea2b0c8599bdb3f86d92e8df46fba795a744db01" + integrity sha512-fxcCeK5pMQGcgCqCrWsi+I2rpIbk0rAhdrN+ke7f34tIrgPwA68ensrpin+9+fZvuV2OtzHmuipwduSY6HswdA== + dependencies: + "@prisma/engines-version" "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e" + +"@prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e": + version "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e" + resolved "https://registry.npmmirror.com/@prisma/engines-version/-/engines-version-5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e.tgz#2e8a1f098ec09452dbe00923b24f582f95d1747c" + integrity sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ== + +"@prisma/engines@5.1.1": + version "5.1.1" + resolved "https://registry.npmmirror.com/@prisma/engines/-/engines-5.1.1.tgz#9c26d209f93a563e048eab63b1976f222f1707d0" + integrity sha512-NV/4nVNWFZSJCCIA3HIFJbbDKO/NARc9ej0tX5S9k2EVbkrFJC4Xt9b0u4rNZWL4V+F5LAjvta8vzEUw0rw+HA== + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.npmmirror.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + +"@types/babel__core@^7.1.14": + version "7.1.20" + resolved "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" + integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.2" + resolved "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" + integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== + dependencies: + "@babel/types" "^7.3.0" + +"@types/glob@~7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.3": + version "29.5.3" + resolved "https://registry.npmmirror.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" + integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/json-schema@^7.0.12": + version "7.0.12" + resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/lodash@^4.14.196": + version "4.14.196" + resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.196.tgz#a7c3d6fc52d8d71328b764e28e080b4169ec7a95" + integrity sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + +"@types/node@*": + version "20.4.8" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.4.8.tgz#b5dda19adaa473a9bf0ab5cbd8f30ec7d43f5c85" + integrity sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg== + +"@types/node@^18.11.9": + version "18.17.4" + resolved "https://registry.npmmirror.com/@types/node/-/node-18.17.4.tgz#bf8ae9875528929cc9930dc3f066cd0481fe1231" + integrity sha512-ATL4WLgr7/W40+Sp1WnNTSKbgVn6Pvhc/2RHAdt8fl6NsQyp4oPCi2eKcGOvA494bwf1K/W6nGgZ9TwDqvpjdw== + +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.npmmirror.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/shelljs@^0.8.12": + version "0.8.12" + resolved "https://registry.npmmirror.com/@types/shelljs/-/shelljs-0.8.12.tgz#79dc9632af7d5ca1b5afb65a6bfc1422d79b5fa0" + integrity sha512-ZA8U81/gldY+rR5zl/7HSHrG2KDfEb3lzG6uCUDhW1DTQE9yC/VBQ45fXnXq8f3CgInfhZmjtdu/WOUlrXRQUg== + dependencies: + "@types/glob" "~7.2.0" + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz#e751e148aab7ccaf8a7bfd370f7ce9e6bdd1f3f4" + integrity sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.3.0" + "@typescript-eslint/type-utils" "6.3.0" + "@typescript-eslint/utils" "6.3.0" + "@typescript-eslint/visitor-keys" "6.3.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + natural-compare-lite "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-6.3.0.tgz#359684c443f4f848db3c4f14674f544f169c8f46" + integrity sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg== + dependencies: + "@typescript-eslint/scope-manager" "6.3.0" + "@typescript-eslint/types" "6.3.0" + "@typescript-eslint/typescript-estree" "6.3.0" + "@typescript-eslint/visitor-keys" "6.3.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz#6b74e338c4b88d5e1dfc1a28c570dd5cf8c86b09" + integrity sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ== + dependencies: + "@typescript-eslint/types" "6.3.0" + "@typescript-eslint/visitor-keys" "6.3.0" + +"@typescript-eslint/type-utils@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-6.3.0.tgz#3bf89ccd36621ddec1b7f8246afe467c67adc247" + integrity sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ== + dependencies: + "@typescript-eslint/typescript-estree" "6.3.0" + "@typescript-eslint/utils" "6.3.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/types/-/types-6.3.0.tgz#84517f1427923e714b8418981e493b6635ab4c9d" + integrity sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg== + +"@typescript-eslint/typescript-estree@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.3.0.tgz#20e1e10e2f51cdb9e19a2751215cac92c003643c" + integrity sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg== + dependencies: + "@typescript-eslint/types" "6.3.0" + "@typescript-eslint/visitor-keys" "6.3.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-6.3.0.tgz#0898c5e374372c2092ca1b979ea7ee9cc020ce84" + integrity sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.3.0" + "@typescript-eslint/types" "6.3.0" + "@typescript-eslint/typescript-estree" "6.3.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.3.0": + version "6.3.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.3.0.tgz#8d09aa3e389ae0971426124c155ac289afbe450a" + integrity sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw== + dependencies: + "@typescript-eslint/types" "6.3.0" + eslint-visitor-keys "^3.4.1" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.8.1" + resolved "https://registry.npmmirror.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +agent-base@6: + version "6.0.2" + resolved "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +babel-jest@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/babel-jest/-/babel-jest-29.6.2.tgz#cada0a59e07f5acaeb11cbae7e3ba92aec9c1126" + integrity sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A== + dependencies: + "@jest/transform" "^29.6.2" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.5.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== + dependencies: + babel-plugin-jest-hoist "^29.5.0" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + +browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.npmmirror.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +callsites@^3.0.0, callsites@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001400: + version "1.0.30001431" + resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795" + integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== + +caniuse-lite@^1.0.30001517: + version "1.0.30001519" + resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" + integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== + +chalk@^2.0.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmmirror.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^11.0.0: + version "11.0.0" + resolved "https://registry.npmmirror.com/commander/-/commander-11.0.0.tgz#43e19c25dbedc8256203538e8d7e9346877a6f67" + integrity sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.npmmirror.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +detect-libc@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmmirror.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.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + +electron-to-chromium@^1.4.477: + version "1.4.487" + resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.487.tgz#e2ef8b15f2791bf68fa6f38f2656f1a551d360ae" + integrity sha512-XbCRs/34l31np/p33m+5tdBrdXu9jJkZxSbNxj5I0H1KtV2ZMSB+i/HYqDiRzHaFx2T5EdytjoBRe8QRJE2vQg== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.npmmirror.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2: + version "3.4.2" + resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" + integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== + +eslint@^8.46.0: + version "8.46.0" + resolved "https://registry.npmmirror.com/eslint/-/eslint-8.46.0.tgz#a06a0ff6974e53e643acc42d1dcf2e7f797b3552" + integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.1" + "@eslint/js" "^8.46.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.2" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.npmmirror.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.npmmirror.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expect@^29.0.0, expect@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/expect/-/expect-29.6.2.tgz#7b08e83eba18ddc4a2cf62b5f2d1918f5cd84521" + integrity sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA== + dependencies: + "@jest/expect-utils" "^29.6.2" + "@types/node" "*" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + 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" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.npmmirror.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +from2@^2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmmirror.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" + +google-protobuf@^3.6.1: + version "3.21.2" + resolved "https://registry.npmmirror.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4" + integrity sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.10" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +into-stream@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/into-stream/-/into-stream-6.0.0.tgz#4bfc1244c0128224e18b8870e85b2de8e66c6702" + integrity sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA== + dependencies: + from2 "^2.3.0" + p-is-promise "^3.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@2.9.0: + version "2.9.0" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-core-module@^2.11.0: + version "2.12.1" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.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.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.npmmirror.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.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-observable@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-observable/-/is-observable-2.1.0.tgz#5c8d733a0b201c80dff7bb7c0df58c6a255c7c69" + integrity sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-circus/-/jest-circus-29.6.2.tgz#1e6ffca60151ac66cad63fce34f443f6b5bb4258" + integrity sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/expect" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.6.2" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-runtime "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + p-limit "^3.1.0" + pretty-format "^29.6.2" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-cli/-/jest-cli-29.6.2.tgz#edb381763398d1a292cd1b636a98bfa5644b8fda" + integrity sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q== + dependencies: + "@jest/core" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-config/-/jest-config-29.6.2.tgz#c68723f06b31ca5e63030686e604727d406cd7c3" + integrity sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.6.2" + "@jest/types" "^29.6.1" + babel-jest "^29.6.2" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.6.2" + jest-environment-node "^29.6.2" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-runner "^29.6.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.6.2" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46" + integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-each/-/jest-each-29.6.2.tgz#c9e4b340bcbe838c73adf46b76817b15712d02ce" + integrity sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw== + dependencies: + "@jest/types" "^29.6.1" + chalk "^4.0.0" + jest-get-type "^29.4.3" + jest-util "^29.6.2" + pretty-format "^29.6.2" + +jest-environment-node@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" + integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/fake-timers" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.2" + jest-util "^29.6.2" + +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + +jest-haste-map@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-29.6.2.tgz#298c25ea5255cfad8b723179d4295cf3a50a70d1" + integrity sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA== + dependencies: + "@jest/types" "^29.6.1" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.4.3" + jest-util "^29.6.2" + jest-worker "^29.6.2" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz#e2b307fee78cab091c37858a98c7e1d73cdf5b38" + integrity sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ== + dependencies: + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-matcher-utils@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz#39de0be2baca7a64eacb27291f0bd834fea3a535" + integrity sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ== + dependencies: + chalk "^4.0.0" + jest-diff "^29.6.2" + jest-get-type "^29.4.3" + pretty-format "^29.6.2" + +jest-message-util@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" + integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.6.2" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" + integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-util "^29.6.2" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== + +jest-resolve-dependencies@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz#36435269b6672c256bcc85fb384872c134cc4cf2" + integrity sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w== + dependencies: + jest-regex-util "^29.4.3" + jest-snapshot "^29.6.2" + +jest-resolve@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-resolve/-/jest-resolve-29.6.2.tgz#f18405fe4b50159b7b6d85e81f6a524d22afb838" + integrity sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-pnp-resolver "^1.2.2" + jest-util "^29.6.2" + jest-validate "^29.6.2" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-runner/-/jest-runner-29.6.2.tgz#89e8e32a8fef24781a7c4c49cd1cb6358ac7fc01" + integrity sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w== + dependencies: + "@jest/console" "^29.6.2" + "@jest/environment" "^29.6.2" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.4.3" + jest-environment-node "^29.6.2" + jest-haste-map "^29.6.2" + jest-leak-detector "^29.6.2" + jest-message-util "^29.6.2" + jest-resolve "^29.6.2" + jest-runtime "^29.6.2" + jest-util "^29.6.2" + jest-watcher "^29.6.2" + jest-worker "^29.6.2" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-runtime/-/jest-runtime-29.6.2.tgz#692f25e387f982e89ab83270e684a9786248e545" + integrity sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg== + dependencies: + "@jest/environment" "^29.6.2" + "@jest/fake-timers" "^29.6.2" + "@jest/globals" "^29.6.2" + "@jest/source-map" "^29.6.0" + "@jest/test-result" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.2" + jest-message-util "^29.6.2" + jest-mock "^29.6.2" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.2" + jest-snapshot "^29.6.2" + jest-util "^29.6.2" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-29.6.2.tgz#9b431b561a83f2bdfe041e1cab8a6becdb01af9c" + integrity sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.6.2" + "@jest/transform" "^29.6.2" + "@jest/types" "^29.6.1" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.6.2" + graceful-fs "^4.2.9" + jest-diff "^29.6.2" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.2" + jest-message-util "^29.6.2" + jest-util "^29.6.2" + natural-compare "^1.4.0" + pretty-format "^29.6.2" + semver "^7.5.3" + +jest-util@^29.0.0, jest-util@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" + integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" + integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== + dependencies: + "@jest/types" "^29.6.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + leven "^3.1.0" + pretty-format "^29.6.2" + +jest-watcher@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-29.6.2.tgz#77c224674f0620d9f6643c4cfca186d8893ca088" + integrity sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA== + dependencies: + "@jest/test-result" "^29.6.2" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.6.2" + string-length "^4.0.1" + +jest-worker@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-29.6.2.tgz#682fbc4b6856ad0aa122a5403c6d048b83f3fb44" + integrity sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ== + dependencies: + "@types/node" "*" + jest-util "^29.6.2" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/jest/-/jest-29.6.2.tgz#3bd55b9fd46a161b2edbdf5f1d1bd0d1eab76c42" + integrity sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg== + dependencies: + "@jest/core" "^29.6.2" + "@jest/types" "^29.6.1" + import-local "^3.0.2" + jest-cli "^29.6.2" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.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.npmmirror.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.npmmirror.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@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.7" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multistream@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/multistream/-/multistream-4.1.0.tgz#7bf00dfd119556fbc153cff3de4c6d477909f5a8" + integrity sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw== + dependencies: + once "^1.4.0" + readable-stream "^3.6.0" + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-abi@^3.3.0: + version "3.45.0" + resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.45.0.tgz#f568f163a3bfca5aacfce1fbeee1fa2cc98441f5" + integrity sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ== + dependencies: + semver "^7.3.5" + +node-fetch@^2.6.6: + version "2.6.7" + resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +observable-fns@^0.6.1: + version "0.6.1" + resolved "https://registry.npmmirror.com/observable-fns/-/observable-fns-0.6.1.tgz#636eae4fdd1132e88c0faf38d33658cc79d87e37" + integrity sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.npmmirror.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-is-promise@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971" + integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.npmmirror.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-fetch@3.4.2: + version "3.4.2" + resolved "https://registry.npmmirror.com/pkg-fetch/-/pkg-fetch-3.4.2.tgz#6f68ebc54842b73f8c0808959a9df3739dcb28b7" + integrity sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA== + dependencies: + chalk "^4.1.2" + fs-extra "^9.1.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.6" + progress "^2.0.3" + semver "^7.3.5" + tar-fs "^2.1.1" + yargs "^16.2.0" + +pkg@^5.8.1: + version "5.8.1" + resolved "https://registry.npmmirror.com/pkg/-/pkg-5.8.1.tgz#862020f3c0575638ef7d1146f951a54d65ddc984" + integrity sha512-CjBWtFStCfIiT4Bde9QpJy0KeH19jCfwZRJqHFDFXfhUklCx8JoFmMj3wgnEYIwGmZVNkhsStPHEOnrtrQhEXA== + dependencies: + "@babel/generator" "7.18.2" + "@babel/parser" "7.18.4" + "@babel/types" "7.19.0" + chalk "^4.1.2" + fs-extra "^9.1.0" + globby "^11.1.0" + into-stream "^6.0.0" + is-core-module "2.9.0" + minimist "^1.2.6" + multistream "^4.1.0" + pkg-fetch "3.4.2" + prebuild-install "7.1.1" + resolve "^1.22.0" + stream-meter "^1.0.4" + +prebuild-install@7.1.1: + version "7.1.1" + resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/prettier/-/prettier-3.0.1.tgz#65271fc9320ce4913c57747a70ce635b30beaa40" + integrity sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ== + +pretty-format@^29.0.0, pretty-format@^29.6.2: + version "29.6.2" + resolved "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" + integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== + dependencies: + "@jest/schemas" "^29.6.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prisma@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/prisma/-/prisma-5.1.1.tgz#8f5c0f9467a828746cb94f846d694dc7b7481a9e" + integrity sha512-WJFG/U7sMmcc6TjJTTifTfpI6Wjoh55xl4AzopVwAdyK68L9/ogNo8QQ2cxuUjJf/Wa82z/uhyh3wMzvRIBphg== + dependencies: + "@prisma/engines" "5.1.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.npmmirror.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +readable-stream@^2.0.0, readable-stream@^2.1.4: + version "2.3.7" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.npmmirror.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +resolve@^1.1.6, resolve@^1.20.0: + version "1.22.1" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^1.22.0: + version "1.22.2" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +semver@5.6.0: + version "5.6.0" + resolved "https://registry.npmmirror.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.5: + version "7.3.8" + resolved "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@^0.8.5: + version "0.8.5" + resolved "https://registry.npmmirror.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@0.5.9: + version "0.5.9" + resolved "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +stream-meter@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/stream-meter/-/stream-meter-1.0.4.tgz#52af95aa5ea760a2491716704dbff90f73afdd1d" + integrity sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ== + dependencies: + readable-stream "^2.1.4" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +threads@^1.7.0: + version "1.7.0" + resolved "https://registry.npmmirror.com/threads/-/threads-1.7.0.tgz#d9e9627bfc1ef22ada3b733c2e7558bbe78e589c" + integrity sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ== + dependencies: + callsites "^3.1.0" + debug "^4.2.0" + is-observable "^2.1.0" + observable-fns "^0.6.1" + optionalDependencies: + tiny-worker ">= 2" + +"tiny-worker@>= 2": + version "2.3.0" + resolved "https://registry.npmmirror.com/tiny-worker/-/tiny-worker-2.3.0.tgz#715ae34304c757a9af573ae9a8e3967177e6011e" + integrity sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g== + dependencies: + esm "^3.2.25" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + +ts-jest@^29.1.1: + version "29.1.1" + resolved "https://registry.npmmirror.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@3.21.0: + version "3.21.0" + resolved "https://registry.npmmirror.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +"typescript-latest@npm:typescript@^5.1.6": + version "5.1.6" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +typescript@4.5.5: + version "4.5.5" + resolved "https://registry.npmmirror.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==