Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.
This commit is contained in:
46
node_modules/tsconfck/LICENSE
generated
vendored
Normal file
46
node_modules/tsconfck/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-present dominikg and [contributors](https://github.com/dominikg/tsconfck/graphs/contributors)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
-- Licenses for 3rd-party code included in tsconfck --
|
||||
|
||||
# strip-bom and strip-json-comments
|
||||
MIT License
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
237
node_modules/tsconfck/README.md
generated
vendored
Normal file
237
node_modules/tsconfck/README.md
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
# tsconfck
|
||||
|
||||
[](https://www.npmjs.com/package/tsconfck)
|
||||
[](https://github.com/dominikg/tsconfck/actions/workflows/test.yml)
|
||||
|
||||
A utility to find and parse tsconfig files without depending on typescript
|
||||
|
||||
# Why
|
||||
|
||||
Because no simple official api exists and tsconfig isn't actual json.
|
||||
|
||||
# Features
|
||||
|
||||
- [x] find closest tsconfig (tsconfig.json or jsconfig.json)
|
||||
- [x] convert tsconfig to actual json and parse it
|
||||
- [x] resolve "extends"
|
||||
- [x] resolve "references" of solution-style tsconfig
|
||||
- [x] optional caching for improved performance
|
||||
- [x] optional findNative and parseNative to use official typescript api
|
||||
- [x] zero dependencies (typescript optional)
|
||||
- [x] extensive testsuite
|
||||
- [x] completely async and optimized (it's [fast](https://github.com/dominikg/tsconfck/blob/main/docs/benchmark.md))
|
||||
- [x] tiny [4.8KB gzip](https://pkg-size.dev/tsconfck)
|
||||
- [x] unbundled esm js, no sourcemaps needed
|
||||
- [x] [types](https://github.com/dominikg/tsconfck/blob/main/packages/tsconfck/types/index.d.ts) generated with [dts-buddy](https://github.com/Rich-Harris/dts-buddy)
|
||||
|
||||
# Users
|
||||
|
||||
Used by [vite](https://github.com/vitejs/vite)\*, [vite-tsconfig-paths](https://github.com/aleclarson/vite-tsconfig-paths), [astro](https://github.com/withastro/astro) and [many more](https://github.com/dominikg/tsconfck/network/dependents)
|
||||
|
||||
> (\*) vite bundles tsconfck so it is listed as a devDependency
|
||||
|
||||
# Install
|
||||
|
||||
```shell
|
||||
npm install --save-dev tsconfck # or pnpm, yarn
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
## without typescript installed
|
||||
|
||||
```js
|
||||
import { parse } from 'tsconfck';
|
||||
const {
|
||||
tsconfigFile, // full path to found tsconfig
|
||||
tsconfig, // tsconfig object including merged values from extended configs
|
||||
extended, // separate unmerged results of all tsconfig files that contributed to tsconfig
|
||||
solution, // solution result if tsconfig is part of a solution
|
||||
referenced // referenced tsconfig results if tsconfig is a solution
|
||||
} = await parse('foo/bar.ts');
|
||||
```
|
||||
|
||||
## with typescript
|
||||
|
||||
```js
|
||||
import { parseNative } from 'tsconfck';
|
||||
const {
|
||||
tsconfigFile, // full path to found tsconfig
|
||||
tsconfig, // tsconfig object including merged values from extended configs, normalized
|
||||
result, // output of ts.parseJsonConfigFileContent
|
||||
solution, // solution result if tsconfig is part of a solution
|
||||
referenced // referenced tsconfig results if tsconfig is a solution
|
||||
} = await parseNative('foo/bar.ts');
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
see [API-DOCS](docs/api.md)
|
||||
|
||||
## Advanced
|
||||
|
||||
### ignoring tsconfig for files inside node_modules
|
||||
|
||||
esbuild ignores node_modules so when you want to use tsconfck with esbuild, you can set `ignoreNodeModules: true`
|
||||
|
||||
```js
|
||||
import { find, parse } from 'tsconfck';
|
||||
// returns some-lib/tsconfig.json
|
||||
const fooTSConfig = await find('node_modules/some-lib/src/foo.ts');
|
||||
|
||||
// returns null
|
||||
const fooTSConfigIgnored = await find('node_modules/some-lib/src/foo.ts', {
|
||||
ignoreNodeModules: true
|
||||
});
|
||||
|
||||
// returns empty config
|
||||
const { tsconfig } = await parse('node_modules/some-lib/src/foo.ts', { ignoreNodeModules: true });
|
||||
```
|
||||
|
||||
### caching
|
||||
|
||||
a TSConfckCache instance can be created and passed to find and parse functions to reduce overhead when they are called often within the same project
|
||||
|
||||
```js
|
||||
import { find, parse, TSCOnfckCache } from 'tsconfck';
|
||||
// 1. create cache instance
|
||||
const cache = new TSCOnfckCache();
|
||||
// 2. pass cache instance in options
|
||||
const fooTSConfig = await find(('src/foo.ts', { cache })); // stores tsconfig for src in cache
|
||||
const barTSConfig = await find(('src/bar.ts', { cache })); // reuses tsconfig result for src without fs call
|
||||
|
||||
const fooResult = await parse('src/foo.ts', { cache }); // uses cached path for tsconfig, stores parse result in cache
|
||||
const barResult = await parse('src/bar.ts', { cache }); // uses cached parse result without fs call or resolving
|
||||
```
|
||||
|
||||
#### cache invalidation
|
||||
|
||||
You are responsible for clearing the cache if tsconfig files are added/removed/changed after reading them during the cache lifetime.
|
||||
|
||||
Call `cache.clear()` and also discard all previous compilation results based previously cached configs.
|
||||
|
||||
#### cache mutation
|
||||
|
||||
Returned results are direct cache objects. If you want to modify them, deep-clone first.
|
||||
|
||||
#### cache reuse
|
||||
|
||||
Never use the same cache instance for mixed calls of find/findNative or parse/parseNative as result structures are different
|
||||
|
||||
### root
|
||||
|
||||
This option can be used to limit finding tsconfig files outside of a root directory
|
||||
|
||||
```js
|
||||
import { parse, TSConfckCache } from 'tsconfck';
|
||||
const root = '.';
|
||||
const parseOptions = { root };
|
||||
// these calls are not going to look for tsconfig files outside root
|
||||
const fooResult = await find('src/foo.ts', parseOptions);
|
||||
const barResult = await parse('src/bar.ts', parseOptions);
|
||||
```
|
||||
|
||||
> Using the root option can lead to errors if there is no tsconfig found inside root.
|
||||
|
||||
### error handling
|
||||
|
||||
find and parse reject for errors they encounter, but return null or empty result if no config was found
|
||||
|
||||
If you want them to error instead, test the result and throw
|
||||
|
||||
```js
|
||||
import { parse } from 'tsconfck';
|
||||
find('some/path/without/tsconfig/foo.ts').then((result) => {
|
||||
if (result === null) {
|
||||
throw new Error('not found');
|
||||
}
|
||||
return result;
|
||||
});
|
||||
parse('some/path/without/tsconfig/foo.ts').then((result) => {
|
||||
if (result.tsconfigFile === null) {
|
||||
throw new Error('not found');
|
||||
}
|
||||
return result;
|
||||
});
|
||||
```
|
||||
|
||||
### TSConfig type (optional, requires typescript as devDependency)
|
||||
|
||||
```ts
|
||||
import type { TSConfig } from 'pkg-types';
|
||||
```
|
||||
|
||||
Check out https://github.com/unjs/pkg-types
|
||||
|
||||
### cli
|
||||
|
||||
A simple cli wrapper is included, you can use it like this
|
||||
|
||||
#### find
|
||||
|
||||
```shell
|
||||
# prints /path/to/tsconfig.json on stdout
|
||||
tsconfck find src/index.ts
|
||||
```
|
||||
|
||||
#### find-all
|
||||
|
||||
```shell
|
||||
# prints all tsconfig.json in dir on stdout
|
||||
tsconfck find-all src/
|
||||
```
|
||||
|
||||
#### parse
|
||||
|
||||
```shell
|
||||
# print content of ParseResult.tsconfig on stdout
|
||||
tsconfck parse src/index.ts
|
||||
|
||||
# print to file
|
||||
tsconfck parse src/index.ts > output.json
|
||||
```
|
||||
|
||||
#### parse-result
|
||||
|
||||
```shell
|
||||
# print content of ParseResult on stdout
|
||||
tsconfck parse-result src/index.ts
|
||||
|
||||
# print to file
|
||||
tsconfck parse-result src/index.ts > output.json
|
||||
```
|
||||
|
||||
#### help
|
||||
|
||||
```shell
|
||||
# print usage
|
||||
tsconfck -h # or --help, -?, help
|
||||
```
|
||||
|
||||
# Links
|
||||
|
||||
- [changelog](CHANGELOG.md)
|
||||
|
||||
# Develop
|
||||
|
||||
This repo uses
|
||||
|
||||
- [pnpm](https://pnpm.io)
|
||||
- [changesets](https://github.com/changesets/changesets)
|
||||
|
||||
In every PR you have to add a changeset by running `pnpm changeset` and following the prompts
|
||||
|
||||
PRs are going to be squash-merged
|
||||
|
||||
```shell
|
||||
# install dependencies
|
||||
pnpm install
|
||||
# run tests
|
||||
pnpm test
|
||||
#run tests in watch mode (doesn't require dev in parallel)
|
||||
pnpm test:watch
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
[MIT](./LICENSE)
|
76
node_modules/tsconfck/bin/tsconfck.js
generated
vendored
Executable file
76
node_modules/tsconfck/bin/tsconfck.js
generated
vendored
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
import { parse, find, findAll } from '../src/index.js';
|
||||
import * as process from 'node:process';
|
||||
|
||||
const HELP_TEXT = `
|
||||
Usage: tsconfck <command> <file> [args]
|
||||
|
||||
Commands: find, find-all, parse, parse-result
|
||||
Args:
|
||||
-js : find/parse jsconfig.json instead of tsconfig.json
|
||||
|
||||
Examples:
|
||||
find tsconfig.json for a file
|
||||
> tsconfck find src/index.ts
|
||||
|
||||
find all tsconfig files in current dir
|
||||
> tsconfck find-all .
|
||||
|
||||
parse tsconfig for a file
|
||||
> tsconfck parse src/index.ts
|
||||
`;
|
||||
|
||||
const HELP_ARGS = ['-h', '--help', '-?', 'help'];
|
||||
const JS_ARG = '-js';
|
||||
const COMMANDS = ['find', 'find-all', 'find-all', 'parse', 'parse-result'];
|
||||
function needsHelp(args) {
|
||||
if (args.some((arg) => HELP_ARGS.includes(arg))) {
|
||||
return HELP_TEXT;
|
||||
}
|
||||
const expectedLength = args.includes(JS_ARG) ? 3 : 2;
|
||||
if (args.length !== expectedLength) {
|
||||
return 'invalid number of arguments\n' + HELP_TEXT;
|
||||
} else if (!COMMANDS.includes(args[0])) {
|
||||
return 'invalid command ' + args[0] + '\n' + HELP_TEXT;
|
||||
}
|
||||
}
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const help = needsHelp(args);
|
||||
if (help) {
|
||||
return help;
|
||||
}
|
||||
|
||||
const command = args[0];
|
||||
const file = args[1];
|
||||
const isJS = args[2] === JS_ARG;
|
||||
const findOptions = isJS ? { configName: 'jsconfig.json' } : undefined;
|
||||
if (command === 'find') {
|
||||
return find(file, findOptions).then((found) => {
|
||||
if (!found) {
|
||||
throw new Error(`no tsconfig found for ${file}`);
|
||||
}
|
||||
return found;
|
||||
});
|
||||
} else if (command === 'parse') {
|
||||
return JSON.stringify((await parse(file, findOptions)).tsconfig, null, 2);
|
||||
} else if (command === 'parse-result') {
|
||||
return JSON.stringify(await parse(file, findOptions), null, 2);
|
||||
} else if (command === 'find-all') {
|
||||
return (
|
||||
await findAll(file || '.', { configNames: [isJS ? 'jsconfig.json' : 'tsconfig.json'] })
|
||||
).join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
main().then(
|
||||
(result) => {
|
||||
process.stdout.write(result);
|
||||
process.stdout.write('\n');
|
||||
},
|
||||
(err) => {
|
||||
console.error(err.message, err);
|
||||
// eslint-disable-next-line n/no-process-exit
|
||||
process.exit(1);
|
||||
}
|
||||
);
|
71
node_modules/tsconfck/package.json
generated
vendored
Normal file
71
node_modules/tsconfck/package.json
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "tsconfck",
|
||||
"version": "3.1.6",
|
||||
"description": "A utility to work with tsconfig.json without typescript",
|
||||
"license": "MIT",
|
||||
"author": "dominikg",
|
||||
"files": [
|
||||
"bin",
|
||||
"src",
|
||||
"types",
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
"package.json"
|
||||
],
|
||||
"type": "module",
|
||||
"bin": "bin/tsconfck.js",
|
||||
"types": "types/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./types/index.d.ts",
|
||||
"default": "./src/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/dominikg/tsconfck.git",
|
||||
"directory": "packages/tsconfck"
|
||||
},
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"tsconfig",
|
||||
"tsconfig.json",
|
||||
"jsconfig",
|
||||
"jsconfig.json"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/dominikg/tsconfck/issues"
|
||||
},
|
||||
"homepage": "https://github.com/dominikg/tsconfck/tree/main/packages/tsconfck#readme",
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node18": "^18.2.4",
|
||||
"@tsconfig/strictest": "^2.0.5",
|
||||
"@vitest/coverage-v8": "^3.0.9",
|
||||
"esbuild": "^0.25.1",
|
||||
"isaacscript-tsconfig": "^7.0.1",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"typescript": "^5.8.2",
|
||||
"vitest": "^3.0.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18 || >=20"
|
||||
},
|
||||
"scripts": {
|
||||
"check:publint": "publint --strict",
|
||||
"check:types": "tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"test:watch": "vitest",
|
||||
"dts-buddy": "dts-buddy -m \"tsconfck:src/index.js\""
|
||||
}
|
||||
}
|
129
node_modules/tsconfck/src/cache.js
generated
vendored
Normal file
129
node_modules/tsconfck/src/cache.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/** @template T */
|
||||
export class TSConfckCache {
|
||||
/**
|
||||
* clear cache, use this if you have a long running process and tsconfig files have been added,changed or deleted
|
||||
*/
|
||||
clear() {
|
||||
this.#configPaths.clear();
|
||||
this.#parsed.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* has cached closest config for files in dir
|
||||
* @param {string} dir
|
||||
* @param {string} [configName=tsconfig.json]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasConfigPath(dir, configName = 'tsconfig.json') {
|
||||
return this.#configPaths.has(`${dir}/${configName}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* get cached closest tsconfig for files in dir
|
||||
* @param {string} dir
|
||||
* @param {string} [configName=tsconfig.json]
|
||||
* @returns {Promise<string|null>|string|null}
|
||||
* @throws {unknown} if cached value is an error
|
||||
*/
|
||||
getConfigPath(dir, configName = 'tsconfig.json') {
|
||||
const key = `${dir}/${configName}`;
|
||||
const value = this.#configPaths.get(key);
|
||||
if (value == null || value.length || value.then) {
|
||||
return value;
|
||||
} else {
|
||||
throw value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* has parsed tsconfig for file
|
||||
* @param {string} file
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasParseResult(file) {
|
||||
return this.#parsed.has(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* get parsed tsconfig for file
|
||||
* @param {string} file
|
||||
* @returns {Promise<T>|T}
|
||||
* @throws {unknown} if cached value is an error
|
||||
*/
|
||||
getParseResult(file) {
|
||||
const value = this.#parsed.get(file);
|
||||
if (value.then || value.tsconfig) {
|
||||
return value;
|
||||
} else {
|
||||
throw value; // cached error, rethrow
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @private
|
||||
* @param file
|
||||
* @param {boolean} isRootFile a flag to check if current file which involking the parse() api, used to distinguish the normal cache which only parsed by parseFile()
|
||||
* @param {Promise<T>} result
|
||||
*/
|
||||
setParseResult(file, result, isRootFile = false) {
|
||||
// _isRootFile_ is a temporary property for Promise result, used to prevent deadlock with cache
|
||||
Object.defineProperty(result, '_isRootFile_', {
|
||||
value: isRootFile,
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
this.#parsed.set(file, result);
|
||||
result
|
||||
.then((parsed) => {
|
||||
if (this.#parsed.get(file) === result) {
|
||||
this.#parsed.set(file, parsed);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
if (this.#parsed.get(file) === result) {
|
||||
this.#parsed.set(file, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @private
|
||||
* @param {string} dir
|
||||
* @param {Promise<string|null>} configPath
|
||||
* @param {string} [configName=tsconfig.json]
|
||||
*/
|
||||
setConfigPath(dir, configPath, configName = 'tsconfig.json') {
|
||||
const key = `${dir}/${configName}`;
|
||||
this.#configPaths.set(key, configPath);
|
||||
configPath
|
||||
.then((path) => {
|
||||
if (this.#configPaths.get(key) === configPath) {
|
||||
this.#configPaths.set(key, path);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
if (this.#configPaths.get(key) === configPath) {
|
||||
this.#configPaths.set(key, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* map directories to their closest tsconfig.json
|
||||
* @internal
|
||||
* @private
|
||||
* @type{Map<string,(Promise<string|null>|string|null)>}
|
||||
*/
|
||||
#configPaths = new Map();
|
||||
|
||||
/**
|
||||
* map files to their parsed tsconfig result
|
||||
* @internal
|
||||
* @private
|
||||
* @type {Map<string,(Promise<T>|T)> }
|
||||
*/
|
||||
#parsed = new Map();
|
||||
}
|
71
node_modules/tsconfck/src/find-all.js
generated
vendored
Normal file
71
node_modules/tsconfck/src/find-all.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import path from 'node:path';
|
||||
import { readdir } from 'node:fs';
|
||||
|
||||
/**
|
||||
* @typedef WalkState
|
||||
* @interface
|
||||
* @property {string[]} files - files
|
||||
* @property {number} calls - number of ongoing calls
|
||||
* @property {(dir: string)=>boolean} skip - function to skip dirs
|
||||
* @property {boolean} err - error flag
|
||||
* @property {string[]} configNames - config file names
|
||||
*/
|
||||
|
||||
const sep = path.sep;
|
||||
|
||||
/**
|
||||
* find all tsconfig.json files in dir
|
||||
*
|
||||
* @param {string} dir - path to dir (absolute or relative to cwd)
|
||||
* @param {import('./public.d.ts').TSConfckFindAllOptions} [options] - options
|
||||
* @returns {Promise<string[]>} list of absolute paths to all found tsconfig.json files
|
||||
*/
|
||||
export async function findAll(dir, options) {
|
||||
/** @type WalkState */
|
||||
const state = {
|
||||
files: [],
|
||||
calls: 0,
|
||||
skip: options?.skip,
|
||||
err: false,
|
||||
configNames: options?.configNames ?? ['tsconfig.json']
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
walk(path.resolve(dir), state, (err, files) => (err ? reject(err) : resolve(files)));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} dir
|
||||
* @param {WalkState} state
|
||||
* @param {(err: NodeJS.ErrnoException | null, files?: string[]) => void} done
|
||||
*/
|
||||
function walk(dir, state, done) {
|
||||
if (state.err) {
|
||||
return;
|
||||
}
|
||||
state.calls++;
|
||||
readdir(dir, { withFileTypes: true }, (err, entries = []) => {
|
||||
if (state.err) {
|
||||
return;
|
||||
}
|
||||
// skip deleted or inaccessible directories
|
||||
if (err && !(err.code === 'ENOENT' || err.code === 'EACCES' || err.code === 'EPERM')) {
|
||||
state.err = true;
|
||||
done(err);
|
||||
} else {
|
||||
for (const ent of entries) {
|
||||
if (ent.isDirectory() && !state.skip?.(ent.name)) {
|
||||
walk(`${dir}${sep}${ent.name}`, state, done);
|
||||
} else if (ent.isFile() && state.configNames.includes(ent.name)) {
|
||||
state.files.push(`${dir}${sep}${ent.name}`);
|
||||
}
|
||||
}
|
||||
if (--state.calls === 0) {
|
||||
if (!state.err) {
|
||||
done(null, state.files);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
70
node_modules/tsconfck/src/find-native.js
generated
vendored
Normal file
70
node_modules/tsconfck/src/find-native.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import path from 'node:path';
|
||||
import { isInNodeModules, loadTS, native2posix } from './util.js';
|
||||
|
||||
/**
|
||||
* find the closest tsconfig.json file using native ts.findConfigFile
|
||||
*
|
||||
* You must have `typescript` installed to use this
|
||||
*
|
||||
* @param {string} filename - path to file to find tsconfig for (absolute or relative to cwd)
|
||||
* @param {import('./public.d.ts').TSConfckFindOptions} [options] - options
|
||||
* @returns {Promise<string>} absolute path to closest tsconfig.json
|
||||
*/
|
||||
export async function findNative(filename, options) {
|
||||
let dir = native2posix(path.dirname(path.resolve(filename)));
|
||||
if (options?.ignoreNodeModules && isInNodeModules(dir)) {
|
||||
return null;
|
||||
}
|
||||
const cache = options?.cache;
|
||||
const root = options?.root ? native2posix(path.resolve(options.root)) : undefined;
|
||||
const configName = options?.configName ?? 'tsconfig.json';
|
||||
if (cache?.hasConfigPath(dir, configName)) {
|
||||
return cache.getConfigPath(dir, configName);
|
||||
}
|
||||
const ts = await loadTS();
|
||||
const { findConfigFile, sys } = ts;
|
||||
let tsconfigFile = findConfigFile(dir, sys.fileExists, configName);
|
||||
if (!tsconfigFile || is_out_of_root(tsconfigFile, root)) {
|
||||
tsconfigFile = null;
|
||||
}
|
||||
if (cache) {
|
||||
cache_result(tsconfigFile, dir, cache, root, configName);
|
||||
}
|
||||
return tsconfigFile;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} tsconfigFile
|
||||
* @param {string} root
|
||||
*/
|
||||
function is_out_of_root(tsconfigFile, root) {
|
||||
return root && !tsconfigFile.startsWith(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* add all intermediate directories between fileDir and tsconfigFile to cache
|
||||
* if no tsconfig was found, go up until root
|
||||
* @param {string|null} tsconfigFile
|
||||
* @param {string} fileDir
|
||||
* @param {import('./cache.js').TSConfckCache} cache
|
||||
* @param {string|undefined} root
|
||||
* @param {string} configName
|
||||
*/
|
||||
function cache_result(tsconfigFile, fileDir, cache, root, configName) {
|
||||
const tsconfigDir = tsconfigFile ? path.dirname(tsconfigFile) : root;
|
||||
const directories = [];
|
||||
let dir = fileDir;
|
||||
while (dir) {
|
||||
directories.push(dir);
|
||||
const parent = path.dirname(dir);
|
||||
if (tsconfigDir === dir || parent === dir) {
|
||||
break;
|
||||
} else {
|
||||
dir = parent;
|
||||
}
|
||||
}
|
||||
directories.forEach((d) => {
|
||||
cache.setConfigPath(d, Promise.resolve(tsconfigFile), configName);
|
||||
});
|
||||
}
|
70
node_modules/tsconfck/src/find.js
generated
vendored
Normal file
70
node_modules/tsconfck/src/find.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { isInNodeModules, makePromise } from './util.js';
|
||||
/**
|
||||
* find the closest tsconfig.json file
|
||||
*
|
||||
* @param {string} filename - path to file to find tsconfig for (absolute or relative to cwd)
|
||||
* @param {import('./public.d.ts').TSConfckFindOptions} [options] - options
|
||||
* @returns {Promise<string|null>} absolute path to closest tsconfig.json or null if not found
|
||||
*/
|
||||
export async function find(filename, options) {
|
||||
let dir = path.dirname(path.resolve(filename));
|
||||
if (options?.ignoreNodeModules && isInNodeModules(dir)) {
|
||||
return null;
|
||||
}
|
||||
const cache = options?.cache;
|
||||
const configName = options?.configName ?? 'tsconfig.json';
|
||||
if (cache?.hasConfigPath(dir, configName)) {
|
||||
return cache.getConfigPath(dir, configName);
|
||||
}
|
||||
const { /** @type {Promise<string|null>} */ promise, resolve, reject } = makePromise();
|
||||
if (options?.root && !path.isAbsolute(options.root)) {
|
||||
options.root = path.resolve(options.root);
|
||||
}
|
||||
findUp(dir, { promise, resolve, reject }, options);
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} dir
|
||||
* @param {{promise:Promise<string|null>,resolve:(result:string|null)=>void,reject:(err:any)=>void}} madePromise
|
||||
* @param {import('./public.d.ts').TSConfckFindOptions} [options] - options
|
||||
*/
|
||||
function findUp(dir, { resolve, reject, promise }, options) {
|
||||
const { cache, root, configName } = options ?? {};
|
||||
if (cache) {
|
||||
if (cache.hasConfigPath(dir, configName)) {
|
||||
let cached;
|
||||
try {
|
||||
cached = cache.getConfigPath(dir, configName);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
if (cached?.then) {
|
||||
cached.then(resolve).catch(reject);
|
||||
} else {
|
||||
resolve(cached);
|
||||
}
|
||||
} else {
|
||||
cache.setConfigPath(dir, promise, configName);
|
||||
}
|
||||
}
|
||||
const tsconfig = path.join(dir, options?.configName ?? 'tsconfig.json');
|
||||
fs.stat(tsconfig, (err, stats) => {
|
||||
if (stats && (stats.isFile() || stats.isFIFO())) {
|
||||
resolve(tsconfig);
|
||||
} else if (err?.code !== 'ENOENT') {
|
||||
reject(err);
|
||||
} else {
|
||||
let parent;
|
||||
if (root === dir || (parent = path.dirname(dir)) === dir) {
|
||||
resolve(null);
|
||||
} else {
|
||||
findUp(parent, { promise, resolve, reject }, options);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
7
node_modules/tsconfck/src/index.js
generated
vendored
Normal file
7
node_modules/tsconfck/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export { find } from './find.js';
|
||||
export { findAll } from './find-all.js';
|
||||
export { toJson } from './to-json.js';
|
||||
export { parse, TSConfckParseError } from './parse.js';
|
||||
export { findNative } from './find-native.js';
|
||||
export { parseNative, TSConfckParseNativeError } from './parse-native.js';
|
||||
export { TSConfckCache } from './cache.js';
|
305
node_modules/tsconfck/src/parse-native.js
generated
vendored
Normal file
305
node_modules/tsconfck/src/parse-native.js
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
import path from 'node:path';
|
||||
import {
|
||||
makePromise,
|
||||
loadTS,
|
||||
native2posix,
|
||||
resolveReferencedTSConfigFiles,
|
||||
resolveSolutionTSConfig,
|
||||
resolveTSConfigJson,
|
||||
replaceTokens
|
||||
} from './util.js';
|
||||
import { findNative } from './find-native.js';
|
||||
|
||||
const notFoundResult = {
|
||||
tsconfigFile: null,
|
||||
tsconfig: {},
|
||||
result: null
|
||||
};
|
||||
|
||||
/**
|
||||
* parse the closest tsconfig.json file with typescript native functions
|
||||
*
|
||||
* You need to have `typescript` installed to use this
|
||||
*
|
||||
* @param {string} filename - path to a tsconfig .json or a source file (absolute or relative to cwd)
|
||||
* @param {import('./public.d.ts').TSConfckParseNativeOptions} [options] - options
|
||||
* @returns {Promise<import('./public.d.ts').TSConfckParseNativeResult>}
|
||||
* @throws {TSConfckParseNativeError}
|
||||
*/
|
||||
export async function parseNative(filename, options) {
|
||||
/** @type {import('./cache.js').TSConfckCache} */
|
||||
const cache = options?.cache;
|
||||
if (cache?.hasParseResult(filename)) {
|
||||
return cache.getParseResult(filename);
|
||||
}
|
||||
const {
|
||||
resolve,
|
||||
reject,
|
||||
/** @type {Promise<import('./public.d.ts').TSConfckParseNativeResult>}*/
|
||||
promise
|
||||
} = makePromise();
|
||||
cache?.setParseResult(filename, promise);
|
||||
try {
|
||||
const tsconfigFile =
|
||||
(await resolveTSConfigJson(filename, cache)) || (await findNative(filename, options));
|
||||
if (!tsconfigFile) {
|
||||
resolve(notFoundResult);
|
||||
return promise;
|
||||
}
|
||||
/** @type {import('./public.d.ts').TSConfckParseNativeResult} */
|
||||
let result;
|
||||
if (filename !== tsconfigFile && cache?.hasParseResult(tsconfigFile)) {
|
||||
result = await cache.getParseResult(tsconfigFile);
|
||||
} else {
|
||||
const ts = await loadTS();
|
||||
result = await parseFile(tsconfigFile, ts, options, filename === tsconfigFile);
|
||||
await parseReferences(result, ts, options);
|
||||
cache?.setParseResult(tsconfigFile, Promise.resolve(result));
|
||||
}
|
||||
|
||||
resolve(resolveSolutionTSConfig(filename, result));
|
||||
return promise;
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} tsconfigFile
|
||||
* @param {any} ts
|
||||
* @param {import('./public.d.ts').TSConfckParseNativeOptions} [options]
|
||||
* @param {boolean} [skipCache]
|
||||
* @returns {import('./public.d.ts').TSConfckParseNativeResult}
|
||||
*/
|
||||
function parseFile(tsconfigFile, ts, options, skipCache) {
|
||||
const cache = options?.cache;
|
||||
if (!skipCache && cache?.hasParseResult(tsconfigFile)) {
|
||||
return cache.getParseResult(tsconfigFile);
|
||||
}
|
||||
const posixTSConfigFile = native2posix(tsconfigFile);
|
||||
const { parseJsonConfigFileContent, readConfigFile, sys } = ts;
|
||||
const { config, error } = readConfigFile(posixTSConfigFile, sys.readFile);
|
||||
if (error) {
|
||||
throw new TSConfckParseNativeError(error, tsconfigFile, null);
|
||||
}
|
||||
|
||||
const host = {
|
||||
useCaseSensitiveFileNames: false,
|
||||
readDirectory: sys.readDirectory,
|
||||
fileExists: sys.fileExists,
|
||||
readFile: sys.readFile
|
||||
};
|
||||
|
||||
if (options?.ignoreSourceFiles) {
|
||||
config.files = [];
|
||||
config.include = [];
|
||||
}
|
||||
const nativeResult = parseJsonConfigFileContent(
|
||||
config,
|
||||
host,
|
||||
path.dirname(posixTSConfigFile),
|
||||
undefined,
|
||||
posixTSConfigFile
|
||||
);
|
||||
|
||||
checkErrors(nativeResult, tsconfigFile);
|
||||
|
||||
/** @type {import('./public.d.ts').TSConfckParseNativeResult} */
|
||||
const result = {
|
||||
tsconfigFile,
|
||||
tsconfig: result2tsconfig(nativeResult, ts, tsconfigFile),
|
||||
result: nativeResult
|
||||
};
|
||||
|
||||
if (!skipCache) {
|
||||
cache?.setParseResult(tsconfigFile, Promise.resolve(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./public.d.ts').TSConfckParseNativeResult} result
|
||||
* @param {any} ts
|
||||
* @param {import('./public.d.ts').TSConfckParseNativeOptions} [options]
|
||||
*/
|
||||
async function parseReferences(result, ts, options) {
|
||||
if (!result.tsconfig.references) {
|
||||
return;
|
||||
}
|
||||
const referencedFiles = resolveReferencedTSConfigFiles(result, options);
|
||||
result.referenced = await Promise.all(
|
||||
referencedFiles.map((file) => parseFile(file, ts, options))
|
||||
);
|
||||
result.referenced.forEach((ref) => (ref.solution = result));
|
||||
}
|
||||
|
||||
/**
|
||||
* check errors reported by parseJsonConfigFileContent
|
||||
*
|
||||
* ignores errors related to missing input files as these may happen regularly in programmatic use
|
||||
* and do not affect the config itself
|
||||
*
|
||||
* @param {any} nativeResult - native typescript parse result to check for errors
|
||||
* @param {string} tsconfigFile
|
||||
* @throws {TSConfckParseNativeError} for critical error
|
||||
*/
|
||||
function checkErrors(nativeResult, tsconfigFile) {
|
||||
const ignoredErrorCodes = [
|
||||
// see https://github.com/microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json
|
||||
18002, // empty files list
|
||||
18003 // no inputs
|
||||
];
|
||||
const criticalError = nativeResult.errors?.find(
|
||||
(error) => error.category === 1 && !ignoredErrorCodes.includes(error.code)
|
||||
);
|
||||
if (criticalError) {
|
||||
throw new TSConfckParseNativeError(criticalError, tsconfigFile, nativeResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the result of `parseJsonConfigFileContent` to a tsconfig that can be parsed again
|
||||
*
|
||||
* - use merged compilerOptions
|
||||
* - strip prefix and postfix of compilerOptions.lib
|
||||
* - convert enum values back to string
|
||||
*
|
||||
* @param {any} result
|
||||
* @param {any} ts typescript
|
||||
* @param {string} tsconfigFile
|
||||
* @returns {object} tsconfig with merged compilerOptions and enums restored to their string form
|
||||
*/
|
||||
function result2tsconfig(result, ts, tsconfigFile) {
|
||||
// dereference result.raw so changes below don't modify original
|
||||
const tsconfig = JSON.parse(JSON.stringify(result.raw));
|
||||
// for some reason the extended compilerOptions are not available in result.raw but only in result.options
|
||||
// and contain an extra fields 'configFilePath' and 'pathsBasePath'. Use everything but those 2
|
||||
const ignoredOptions = ['configFilePath', 'pathsBasePath'];
|
||||
if (result.options && Object.keys(result.options).some((o) => !ignoredOptions.includes(o))) {
|
||||
tsconfig.compilerOptions = {
|
||||
...result.options
|
||||
};
|
||||
for (const ignored of ignoredOptions) {
|
||||
delete tsconfig.compilerOptions[ignored];
|
||||
}
|
||||
}
|
||||
|
||||
const compilerOptions = tsconfig.compilerOptions;
|
||||
if (compilerOptions) {
|
||||
if (compilerOptions.lib != null) {
|
||||
// remove lib. and .dts from lib.es2019.d.ts etc
|
||||
compilerOptions.lib = compilerOptions.lib.map((x) =>
|
||||
x.replace(/^lib\./, '').replace(/\.d\.ts$/, '')
|
||||
);
|
||||
}
|
||||
const enumProperties = [
|
||||
{ name: 'importsNotUsedAsValues', enumeration: ts.ImportsNotUsedAsValues },
|
||||
{ name: 'module', enumeration: ts.ModuleKind },
|
||||
{
|
||||
name: 'moduleResolution',
|
||||
enumeration: {
|
||||
...ts.ModuleResolutionKind,
|
||||
2: 'node' /*ts.ModuleResolutionKind uses "Node10" but in tsconfig it is just node"*/
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'newLine',
|
||||
enumeration: { 0: 'crlf', 1: 'lf' } /*ts.NewLineKind uses different names*/
|
||||
},
|
||||
{ name: 'target', enumeration: ts.ScriptTarget }
|
||||
];
|
||||
for (const prop of enumProperties) {
|
||||
if (compilerOptions[prop.name] != null && typeof compilerOptions[prop.name] === 'number') {
|
||||
compilerOptions[prop.name] = prop.enumeration[compilerOptions[prop.name]].toLowerCase();
|
||||
}
|
||||
}
|
||||
if (compilerOptions.target === 'latest') {
|
||||
compilerOptions.target = 'esnext'; // why ts, why?
|
||||
}
|
||||
}
|
||||
|
||||
// merged watchOptions
|
||||
if (result.watchOptions) {
|
||||
tsconfig.watchOptions = {
|
||||
...result.watchOptions
|
||||
};
|
||||
}
|
||||
|
||||
const watchOptions = tsconfig.watchOptions;
|
||||
if (watchOptions) {
|
||||
const enumProperties = [
|
||||
{ name: 'watchFile', enumeration: ts.WatchFileKind },
|
||||
{ name: 'watchDirectory', enumeration: ts.WatchDirectoryKind },
|
||||
{ name: 'fallbackPolling', enumeration: ts.PollingWatchKind }
|
||||
];
|
||||
for (const prop of enumProperties) {
|
||||
if (watchOptions[prop.name] != null && typeof watchOptions[prop.name] === 'number') {
|
||||
const enumVal = prop.enumeration[watchOptions[prop.name]];
|
||||
watchOptions[prop.name] = enumVal.charAt(0).toLowerCase() + enumVal.slice(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tsconfig.compileOnSave === false) {
|
||||
// ts adds this property even if it isn't present in the actual config
|
||||
// delete if it is false to match content of tsconfig
|
||||
delete tsconfig.compileOnSave;
|
||||
}
|
||||
// ts itself has not replaced all tokens at this point, make sure they are
|
||||
const parseResult = { tsconfig, tsconfigFile };
|
||||
replaceTokens(parseResult);
|
||||
return parseResult.tsconfig;
|
||||
}
|
||||
|
||||
export class TSConfckParseNativeError extends Error {
|
||||
/**
|
||||
*
|
||||
* @param {TSDiagnosticError} diagnostic - diagnostics of ts
|
||||
* @param {string} tsconfigFile - file that errored
|
||||
* @param {any?} result - parsed result, if any
|
||||
*/
|
||||
constructor(diagnostic, tsconfigFile, result) {
|
||||
super(diagnostic.messageText);
|
||||
// Set the prototype explicitly.
|
||||
Object.setPrototypeOf(this, TSConfckParseNativeError.prototype);
|
||||
this.name = TSConfckParseNativeError.name;
|
||||
this.code = `TS ${diagnostic.code}`;
|
||||
this.diagnostic = diagnostic;
|
||||
this.result = result;
|
||||
this.tsconfigFile = tsconfigFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* code of typescript diagnostic, prefixed with "TS "
|
||||
* @type {string}
|
||||
*/
|
||||
code;
|
||||
|
||||
/**
|
||||
* full ts diagnostic that caused this error
|
||||
* @type {TSDiagnosticError}
|
||||
*/
|
||||
diagnostic;
|
||||
|
||||
/**
|
||||
* absolute path of tsconfig file where the error happened
|
||||
* @type {string}
|
||||
*/
|
||||
tsconfigFile;
|
||||
|
||||
/**
|
||||
* native result if present, contains all errors in result.errors
|
||||
* @type {any|undefined}
|
||||
*/
|
||||
result;
|
||||
}
|
||||
|
||||
/** @typedef TSDiagnosticError {
|
||||
code: number;
|
||||
category: number;
|
||||
messageText: string;
|
||||
start?: number;
|
||||
} TSDiagnosticError */
|
441
node_modules/tsconfck/src/parse.js
generated
vendored
Normal file
441
node_modules/tsconfck/src/parse.js
generated
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
import path from 'node:path';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { createRequire } from 'module';
|
||||
import { find } from './find.js';
|
||||
import { toJson } from './to-json.js';
|
||||
import {
|
||||
makePromise,
|
||||
native2posix,
|
||||
resolve2posix,
|
||||
replaceTokens,
|
||||
resolveReferencedTSConfigFiles,
|
||||
resolveSolutionTSConfig,
|
||||
resolveTSConfigJson
|
||||
} from './util.js';
|
||||
|
||||
const not_found_result = {
|
||||
tsconfigFile: null,
|
||||
tsconfig: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* parse the closest tsconfig.json file
|
||||
*
|
||||
* @param {string} filename - path to a tsconfig .json or a source file or directory (absolute or relative to cwd)
|
||||
* @param {import('./public.d.ts').TSConfckParseOptions} [options] - options
|
||||
* @returns {Promise<import('./public.d.ts').TSConfckParseResult>}
|
||||
* @throws {TSConfckParseError}
|
||||
*/
|
||||
export async function parse(filename, options) {
|
||||
/** @type {import('./cache.js').TSConfckCache} */
|
||||
const cache = options?.cache;
|
||||
if (cache?.hasParseResult(filename)) {
|
||||
return getParsedDeep(filename, cache, options);
|
||||
}
|
||||
const {
|
||||
resolve,
|
||||
reject,
|
||||
/** @type {Promise<import('./public.d.ts').TSConfckParseResult>}*/
|
||||
promise
|
||||
} = makePromise();
|
||||
cache?.setParseResult(filename, promise, true);
|
||||
try {
|
||||
let tsconfigFile =
|
||||
(await resolveTSConfigJson(filename, cache)) || (await find(filename, options));
|
||||
if (!tsconfigFile) {
|
||||
resolve(not_found_result);
|
||||
return promise;
|
||||
}
|
||||
let result;
|
||||
if (filename !== tsconfigFile && cache?.hasParseResult(tsconfigFile)) {
|
||||
result = await getParsedDeep(tsconfigFile, cache, options);
|
||||
} else {
|
||||
result = await parseFile(tsconfigFile, cache, filename === tsconfigFile);
|
||||
await Promise.all([parseExtends(result, cache), parseReferences(result, options)]);
|
||||
}
|
||||
replaceTokens(result);
|
||||
resolve(resolveSolutionTSConfig(filename, result));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* ensure extends and references are parsed
|
||||
*
|
||||
* @param {string} filename - cached file
|
||||
* @param {import('./cache.js').TSConfckCache} cache - cache
|
||||
* @param {import('./public.d.ts').TSConfckParseOptions} options - options
|
||||
*/
|
||||
async function getParsedDeep(filename, cache, options) {
|
||||
const result = await cache.getParseResult(filename);
|
||||
if (
|
||||
(result.tsconfig.extends && !result.extended) ||
|
||||
(result.tsconfig.references && !result.referenced)
|
||||
) {
|
||||
const promise = Promise.all([
|
||||
parseExtends(result, cache),
|
||||
parseReferences(result, options)
|
||||
]).then(() => result);
|
||||
cache.setParseResult(filename, promise, true);
|
||||
return promise;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} tsconfigFile - path to tsconfig file
|
||||
* @param {import('./cache.js').TSConfckCache} [cache] - cache
|
||||
* @param {boolean} [skipCache] - skip cache
|
||||
* @returns {Promise<import('./public.d.ts').TSConfckParseResult>}
|
||||
*/
|
||||
async function parseFile(tsconfigFile, cache, skipCache) {
|
||||
if (
|
||||
!skipCache &&
|
||||
cache?.hasParseResult(tsconfigFile) &&
|
||||
!cache.getParseResult(tsconfigFile)._isRootFile_
|
||||
) {
|
||||
return cache.getParseResult(tsconfigFile);
|
||||
}
|
||||
const promise = fs
|
||||
.readFile(tsconfigFile, 'utf-8')
|
||||
.then(toJson)
|
||||
.then((json) => {
|
||||
const parsed = JSON.parse(json);
|
||||
applyDefaults(parsed, tsconfigFile);
|
||||
return {
|
||||
tsconfigFile,
|
||||
tsconfig: normalizeTSConfig(parsed, path.dirname(tsconfigFile))
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
throw new TSConfckParseError(
|
||||
`parsing ${tsconfigFile} failed: ${e}`,
|
||||
'PARSE_FILE',
|
||||
tsconfigFile,
|
||||
e
|
||||
);
|
||||
});
|
||||
if (
|
||||
!skipCache &&
|
||||
(!cache?.hasParseResult(tsconfigFile) || !cache.getParseResult(tsconfigFile)._isRootFile_)
|
||||
) {
|
||||
cache?.setParseResult(tsconfigFile, promise);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* normalize to match the output of ts.parseJsonConfigFileContent
|
||||
*
|
||||
* @param {any} tsconfig - typescript tsconfig output
|
||||
* @param {string} dir - directory
|
||||
*/
|
||||
function normalizeTSConfig(tsconfig, dir) {
|
||||
// set baseUrl to absolute path
|
||||
const baseUrl = tsconfig.compilerOptions?.baseUrl;
|
||||
if (baseUrl && !baseUrl.startsWith('${') && !path.isAbsolute(baseUrl)) {
|
||||
tsconfig.compilerOptions.baseUrl = resolve2posix(dir, baseUrl);
|
||||
}
|
||||
return tsconfig;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
* @param {import('./public.d.ts').TSConfckParseOptions} [options]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function parseReferences(result, options) {
|
||||
if (!result.tsconfig.references) {
|
||||
return;
|
||||
}
|
||||
const referencedFiles = resolveReferencedTSConfigFiles(result, options);
|
||||
const referenced = await Promise.all(
|
||||
referencedFiles.map((file) => parseFile(file, options?.cache))
|
||||
);
|
||||
await Promise.all(referenced.map((ref) => parseExtends(ref, options?.cache)));
|
||||
referenced.forEach((ref) => {
|
||||
ref.solution = result;
|
||||
replaceTokens(ref);
|
||||
});
|
||||
result.referenced = referenced;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
* @param {import('./cache.js').TSConfckCache}[cache]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function parseExtends(result, cache) {
|
||||
if (!result.tsconfig.extends) {
|
||||
return;
|
||||
}
|
||||
// use result as first element in extended
|
||||
// but dereference tsconfig so that mergeExtended can modify the original without affecting extended[0]
|
||||
/** @type {import('./public.d.ts').TSConfckParseResult[]} */
|
||||
const extended = [
|
||||
{ tsconfigFile: result.tsconfigFile, tsconfig: JSON.parse(JSON.stringify(result.tsconfig)) }
|
||||
];
|
||||
|
||||
// flatten extends graph into extended
|
||||
let pos = 0;
|
||||
/** @type {string[]} */
|
||||
const extendsPath = [];
|
||||
let currentBranchDepth = 0;
|
||||
while (pos < extended.length) {
|
||||
const extending = extended[pos];
|
||||
extendsPath.push(extending.tsconfigFile);
|
||||
if (extending.tsconfig.extends) {
|
||||
// keep following this branch
|
||||
currentBranchDepth += 1;
|
||||
/** @type {string[]} */
|
||||
let resolvedExtends;
|
||||
if (!Array.isArray(extending.tsconfig.extends)) {
|
||||
resolvedExtends = [resolveExtends(extending.tsconfig.extends, extending.tsconfigFile)];
|
||||
} else {
|
||||
// reverse because typescript 5.0 treats ['a','b','c'] as c extends b extends a
|
||||
resolvedExtends = extending.tsconfig.extends
|
||||
.reverse()
|
||||
.map((ex) => resolveExtends(ex, extending.tsconfigFile));
|
||||
}
|
||||
|
||||
const circularExtends = resolvedExtends.find((tsconfigFile) =>
|
||||
extendsPath.includes(tsconfigFile)
|
||||
);
|
||||
if (circularExtends) {
|
||||
const circle = extendsPath.concat([circularExtends]).join(' -> ');
|
||||
throw new TSConfckParseError(
|
||||
`Circular dependency in "extends": ${circle}`,
|
||||
'EXTENDS_CIRCULAR',
|
||||
result.tsconfigFile
|
||||
);
|
||||
}
|
||||
// add new extends to the list directly after current
|
||||
extended.splice(
|
||||
pos + 1,
|
||||
0,
|
||||
...(await Promise.all(resolvedExtends.map((file) => parseFile(file, cache))))
|
||||
);
|
||||
} else {
|
||||
// reached a leaf, backtrack to the last branching point and continue
|
||||
extendsPath.splice(-currentBranchDepth);
|
||||
currentBranchDepth = 0;
|
||||
}
|
||||
pos = pos + 1;
|
||||
}
|
||||
result.extended = extended;
|
||||
// skip first as it is the original config
|
||||
for (const ext of result.extended.slice(1)) {
|
||||
extendTSConfig(result, ext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} extended
|
||||
* @param {string} from
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolveExtends(extended, from) {
|
||||
// see #149 and #220
|
||||
if (['.', '..'].includes(extended)) {
|
||||
extended = extended + '/tsconfig.json';
|
||||
}
|
||||
const req = createRequire(from);
|
||||
let error;
|
||||
try {
|
||||
return req.resolve(extended);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
if (extended[0] !== '.' && !path.isAbsolute(extended)) {
|
||||
try {
|
||||
return req.resolve(`${extended}/tsconfig.json`);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
}
|
||||
|
||||
throw new TSConfckParseError(
|
||||
`failed to resolve "extends":"${extended}" in ${from}`,
|
||||
'EXTENDS_RESOLVE',
|
||||
from,
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
// references, extends and custom keys are not carried over
|
||||
const EXTENDABLE_KEYS = [
|
||||
'compilerOptions',
|
||||
'files',
|
||||
'include',
|
||||
'exclude',
|
||||
'watchOptions',
|
||||
'compileOnSave',
|
||||
'typeAcquisition',
|
||||
'buildOptions'
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} extending
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} extended
|
||||
* @returns void
|
||||
*/
|
||||
function extendTSConfig(extending, extended) {
|
||||
const extendingConfig = extending.tsconfig;
|
||||
const extendedConfig = extended.tsconfig;
|
||||
const relativePath = native2posix(
|
||||
path.relative(path.dirname(extending.tsconfigFile), path.dirname(extended.tsconfigFile))
|
||||
);
|
||||
for (const key of Object.keys(extendedConfig).filter((key) => EXTENDABLE_KEYS.includes(key))) {
|
||||
if (key === 'compilerOptions') {
|
||||
if (!extendingConfig.compilerOptions) {
|
||||
extendingConfig.compilerOptions = {};
|
||||
}
|
||||
for (const option of Object.keys(extendedConfig.compilerOptions)) {
|
||||
if (Object.prototype.hasOwnProperty.call(extendingConfig.compilerOptions, option)) {
|
||||
continue; // already set
|
||||
}
|
||||
extendingConfig.compilerOptions[option] = rebaseRelative(
|
||||
option,
|
||||
extendedConfig.compilerOptions[option],
|
||||
relativePath
|
||||
);
|
||||
}
|
||||
} else if (extendingConfig[key] === undefined) {
|
||||
if (key === 'watchOptions') {
|
||||
extendingConfig.watchOptions = {};
|
||||
for (const option of Object.keys(extendedConfig.watchOptions)) {
|
||||
extendingConfig.watchOptions[option] = rebaseRelative(
|
||||
option,
|
||||
extendedConfig.watchOptions[option],
|
||||
relativePath
|
||||
);
|
||||
}
|
||||
} else {
|
||||
extendingConfig[key] = rebaseRelative(key, extendedConfig[key], relativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const REBASE_KEYS = [
|
||||
// root
|
||||
'files',
|
||||
'include',
|
||||
'exclude',
|
||||
// compilerOptions
|
||||
'baseUrl',
|
||||
'rootDir',
|
||||
'rootDirs',
|
||||
'typeRoots',
|
||||
'outDir',
|
||||
'outFile',
|
||||
'declarationDir',
|
||||
// watchOptions
|
||||
'excludeDirectories',
|
||||
'excludeFiles'
|
||||
];
|
||||
|
||||
/** @typedef {string | string[]} PathValue */
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {PathValue} value
|
||||
* @param {string} prependPath
|
||||
* @returns {PathValue}
|
||||
*/
|
||||
function rebaseRelative(key, value, prependPath) {
|
||||
if (!REBASE_KEYS.includes(key)) {
|
||||
return value;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((x) => rebasePath(x, prependPath));
|
||||
} else {
|
||||
return rebasePath(value, prependPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} value
|
||||
* @param {string} prependPath
|
||||
* @returns {string}
|
||||
*/
|
||||
function rebasePath(value, prependPath) {
|
||||
if (path.isAbsolute(value) || value.startsWith('${configDir}')) {
|
||||
return value;
|
||||
} else {
|
||||
// relative paths use posix syntax in tsconfig
|
||||
return path.posix.normalize(path.posix.join(prependPath, value));
|
||||
}
|
||||
}
|
||||
|
||||
export class TSConfckParseError extends Error {
|
||||
/**
|
||||
* error code
|
||||
* @type {string}
|
||||
*/
|
||||
code;
|
||||
/**
|
||||
* error cause
|
||||
* @type { Error | undefined}
|
||||
*/
|
||||
cause;
|
||||
|
||||
/**
|
||||
* absolute path of tsconfig file where the error happened
|
||||
* @type {string}
|
||||
*/
|
||||
tsconfigFile;
|
||||
/**
|
||||
*
|
||||
* @param {string} message - error message
|
||||
* @param {string} code - error code
|
||||
* @param {string} tsconfigFile - path to tsconfig file
|
||||
* @param {Error?} cause - cause of this error
|
||||
*/
|
||||
constructor(message, code, tsconfigFile, cause) {
|
||||
super(message);
|
||||
// Set the prototype explicitly.
|
||||
Object.setPrototypeOf(this, TSConfckParseError.prototype);
|
||||
this.name = TSConfckParseError.name;
|
||||
this.code = code;
|
||||
this.cause = cause;
|
||||
this.tsconfigFile = tsconfigFile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} tsconfig
|
||||
* @param {string} tsconfigFile
|
||||
*/
|
||||
function applyDefaults(tsconfig, tsconfigFile) {
|
||||
if (isJSConfig(tsconfigFile)) {
|
||||
tsconfig.compilerOptions = {
|
||||
...DEFAULT_JSCONFIG_COMPILER_OPTIONS,
|
||||
...tsconfig.compilerOptions
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_JSCONFIG_COMPILER_OPTIONS = {
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
allowSyntheticDefaultImports: true,
|
||||
skipLibCheck: true,
|
||||
noEmit: true
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} configFileName
|
||||
*/
|
||||
function isJSConfig(configFileName) {
|
||||
return path.basename(configFileName) === 'jsconfig.json';
|
||||
}
|
125
node_modules/tsconfck/src/public.d.ts
generated
vendored
Normal file
125
node_modules/tsconfck/src/public.d.ts
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
import { TSConfckCache } from './cache.js';
|
||||
|
||||
export interface TSConfckFindOptions {
|
||||
/**
|
||||
* A cache to improve performance for multiple calls in the same project
|
||||
*
|
||||
* Warning: You must clear this cache in case tsconfig files are added/removed during it's lifetime
|
||||
*/
|
||||
cache?: TSConfckCache<TSConfckParseResult | TSConfckParseNativeResult>;
|
||||
|
||||
/**
|
||||
* project root dir, does not continue scanning outside of this directory.
|
||||
*
|
||||
* Improves performance but may lead to different results from native typescript when no tsconfig is found inside root
|
||||
*/
|
||||
root?: string;
|
||||
|
||||
/**
|
||||
* set to true if you don't want to find tsconfig for files inside node_modules
|
||||
*
|
||||
* This is useful if you want to use the output with esbuild.transform as esbuild itself also ignores node_modules
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
ignoreNodeModules?: boolean;
|
||||
|
||||
/**
|
||||
* Override the default name of the config file to find.
|
||||
*
|
||||
* Use `jsconfig.json` in projects that have typechecking for js files with jsconfig.json
|
||||
*
|
||||
* @default tsconfig.json
|
||||
*/
|
||||
configName?: string;
|
||||
}
|
||||
|
||||
export interface TSConfckParseOptions extends TSConfckFindOptions {
|
||||
// same as find options
|
||||
}
|
||||
|
||||
export interface TSConfckFindAllOptions {
|
||||
/**
|
||||
* helper to skip subdirectories when scanning for tsconfig.json
|
||||
*
|
||||
* eg ` dir => dir === 'node_modules' || dir === '.git'`
|
||||
*/
|
||||
skip?: (dir: string) => boolean;
|
||||
/**
|
||||
* list of config filenames to include, use ["tsconfig.json","jsconfig.json"] if you need both
|
||||
*
|
||||
* @default ["tsconfig.json"]
|
||||
*/
|
||||
configNames?: string[];
|
||||
}
|
||||
|
||||
export interface TSConfckParseResult {
|
||||
/**
|
||||
* absolute path to parsed tsconfig.json
|
||||
*/
|
||||
tsconfigFile: string;
|
||||
|
||||
/**
|
||||
* parsed result, including merged values from extended
|
||||
*/
|
||||
tsconfig: any;
|
||||
|
||||
/**
|
||||
* ParseResult for parent solution
|
||||
*/
|
||||
solution?: TSConfckParseResult;
|
||||
|
||||
/**
|
||||
* ParseResults for all tsconfig files referenced in a solution
|
||||
*/
|
||||
referenced?: TSConfckParseResult[];
|
||||
|
||||
/**
|
||||
* ParseResult for all tsconfig files
|
||||
*
|
||||
* [a,b,c] where a extends b and b extends c
|
||||
*/
|
||||
extended?: TSConfckParseResult[];
|
||||
}
|
||||
|
||||
export interface TSConfckParseNativeOptions extends TSConfckParseOptions {
|
||||
/**
|
||||
* Set this option to true to force typescript to ignore all source files.
|
||||
*
|
||||
* This is faster - especially for large projects - but comes with 2 caveats
|
||||
*
|
||||
* 1) output tsconfig always has `files: [],include: []` instead of any real values configured.
|
||||
* 2) as a result of 1), it won't be able to resolve solution-style references and always return the closest tsconfig
|
||||
*/
|
||||
ignoreSourceFiles?: boolean;
|
||||
}
|
||||
|
||||
export interface TSConfckParseNativeResult {
|
||||
/**
|
||||
* absolute path to parsed tsconfig.json
|
||||
*/
|
||||
tsconfigFile: string;
|
||||
|
||||
/**
|
||||
* parsed result, including merged values from extended and normalized
|
||||
*/
|
||||
tsconfig: any;
|
||||
|
||||
/**
|
||||
* ParseResult for parent solution
|
||||
*/
|
||||
solution?: TSConfckParseNativeResult;
|
||||
|
||||
/**
|
||||
* ParseNativeResults for all tsconfig files referenced in a solution
|
||||
*/
|
||||
referenced?: TSConfckParseNativeResult[];
|
||||
|
||||
/**
|
||||
* full output of ts.parseJsonConfigFileContent
|
||||
*/
|
||||
result: any;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line n/no-missing-import
|
||||
export * from './index.js';
|
167
node_modules/tsconfck/src/to-json.js
generated
vendored
Normal file
167
node_modules/tsconfck/src/to-json.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
this file contains code from strip-bom and strip-json-comments by Sindre Sorhus
|
||||
https://github.com/sindresorhus/strip-json-comments/blob/v4.0.0/index.js
|
||||
https://github.com/sindresorhus/strip-bom/blob/v5.0.0/index.js
|
||||
licensed under MIT, see ../LICENSE
|
||||
*/
|
||||
|
||||
/**
|
||||
* convert content of tsconfig.json to regular json
|
||||
*
|
||||
* @param {string} tsconfigJson - content of tsconfig.json
|
||||
* @returns {string} content as regular json, comments and dangling commas have been replaced with whitespace
|
||||
*/
|
||||
export function toJson(tsconfigJson) {
|
||||
const stripped = stripDanglingComma(stripJsonComments(stripBom(tsconfigJson)));
|
||||
if (stripped.trim() === '') {
|
||||
// only whitespace left after stripping, return empty object so that JSON.parse still works
|
||||
return '{}';
|
||||
} else {
|
||||
return stripped;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* replace dangling commas from pseudo-json string with single space
|
||||
* implementation heavily inspired by strip-json-comments
|
||||
*
|
||||
* @param {string} pseudoJson
|
||||
* @returns {string}
|
||||
*/
|
||||
function stripDanglingComma(pseudoJson) {
|
||||
let insideString = false;
|
||||
let offset = 0;
|
||||
let result = '';
|
||||
let danglingCommaPos = null;
|
||||
for (let i = 0; i < pseudoJson.length; i++) {
|
||||
const currentCharacter = pseudoJson[i];
|
||||
if (currentCharacter === '"') {
|
||||
const escaped = isEscaped(pseudoJson, i);
|
||||
if (!escaped) {
|
||||
insideString = !insideString;
|
||||
}
|
||||
}
|
||||
if (insideString) {
|
||||
danglingCommaPos = null;
|
||||
continue;
|
||||
}
|
||||
if (currentCharacter === ',') {
|
||||
danglingCommaPos = i;
|
||||
continue;
|
||||
}
|
||||
if (danglingCommaPos) {
|
||||
if (currentCharacter === '}' || currentCharacter === ']') {
|
||||
result += pseudoJson.slice(offset, danglingCommaPos) + ' ';
|
||||
offset = danglingCommaPos + 1;
|
||||
danglingCommaPos = null;
|
||||
} else if (!currentCharacter.match(/\s/)) {
|
||||
danglingCommaPos = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result + pseudoJson.substring(offset);
|
||||
}
|
||||
|
||||
// start strip-json-comments
|
||||
/**
|
||||
*
|
||||
* @param {string} jsonString
|
||||
* @param {number} quotePosition
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isEscaped(jsonString, quotePosition) {
|
||||
let index = quotePosition - 1;
|
||||
let backslashCount = 0;
|
||||
|
||||
while (jsonString[index] === '\\') {
|
||||
index -= 1;
|
||||
backslashCount += 1;
|
||||
}
|
||||
|
||||
return Boolean(backslashCount % 2);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} string
|
||||
* @param {number?} start
|
||||
* @param {number?} end
|
||||
*/
|
||||
function strip(string, start, end) {
|
||||
return string.slice(start, end).replace(/\S/g, ' ');
|
||||
}
|
||||
|
||||
const singleComment = Symbol('singleComment');
|
||||
const multiComment = Symbol('multiComment');
|
||||
|
||||
/**
|
||||
* @param {string} jsonString
|
||||
* @returns {string}
|
||||
*/
|
||||
function stripJsonComments(jsonString) {
|
||||
let isInsideString = false;
|
||||
/** @type {false | symbol} */
|
||||
let isInsideComment = false;
|
||||
let offset = 0;
|
||||
let result = '';
|
||||
|
||||
for (let index = 0; index < jsonString.length; index++) {
|
||||
const currentCharacter = jsonString[index];
|
||||
const nextCharacter = jsonString[index + 1];
|
||||
|
||||
if (!isInsideComment && currentCharacter === '"') {
|
||||
const escaped = isEscaped(jsonString, index);
|
||||
if (!escaped) {
|
||||
isInsideString = !isInsideString;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInsideString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isInsideComment && currentCharacter + nextCharacter === '//') {
|
||||
result += jsonString.slice(offset, index);
|
||||
offset = index;
|
||||
isInsideComment = singleComment;
|
||||
index++;
|
||||
} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
|
||||
index++;
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index);
|
||||
offset = index;
|
||||
} else if (isInsideComment === singleComment && currentCharacter === '\n') {
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index);
|
||||
offset = index;
|
||||
} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
|
||||
result += jsonString.slice(offset, index);
|
||||
offset = index;
|
||||
isInsideComment = multiComment;
|
||||
index++;
|
||||
} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
|
||||
index++;
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index + 1);
|
||||
offset = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
|
||||
}
|
||||
// end strip-json-comments
|
||||
|
||||
// start strip-bom
|
||||
/**
|
||||
* @param {string} string
|
||||
* @returns {string}
|
||||
*/
|
||||
function stripBom(string) {
|
||||
// Catches EFBBBF (UTF-8 BOM) because the buffer-to-string
|
||||
// conversion translates it to FEFF (UTF-16 BOM).
|
||||
if (string.charCodeAt(0) === 0xfeff) {
|
||||
return string.slice(1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
// end strip-bom
|
339
node_modules/tsconfck/src/util.js
generated
vendored
Normal file
339
node_modules/tsconfck/src/util.js
generated
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
import path from 'node:path';
|
||||
import { promises as fs } from 'node:fs';
|
||||
|
||||
const POSIX_SEP_RE = new RegExp('\\' + path.posix.sep, 'g');
|
||||
const NATIVE_SEP_RE = new RegExp('\\' + path.sep, 'g');
|
||||
/** @type {Map<string,RegExp>}*/
|
||||
const PATTERN_REGEX_CACHE = new Map();
|
||||
const GLOB_ALL_PATTERN = `**/*`;
|
||||
const TS_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts'];
|
||||
const JS_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs'];
|
||||
const TSJS_EXTENSIONS = TS_EXTENSIONS.concat(JS_EXTENSIONS);
|
||||
const TS_EXTENSIONS_RE_GROUP = `\\.(?:${TS_EXTENSIONS.map((ext) => ext.substring(1)).join('|')})`;
|
||||
const TSJS_EXTENSIONS_RE_GROUP = `\\.(?:${TSJS_EXTENSIONS.map((ext) => ext.substring(1)).join(
|
||||
'|'
|
||||
)})`;
|
||||
const IS_POSIX = path.posix.sep === path.sep;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @returns {{resolve:(result:T)=>void, reject:(error:any)=>void, promise: Promise<T>}}
|
||||
*/
|
||||
export function makePromise() {
|
||||
let resolve, reject;
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve, reject };
|
||||
}
|
||||
|
||||
/**
|
||||
* loads typescript async to avoid direct dependency
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export async function loadTS() {
|
||||
try {
|
||||
return import('typescript').then((m) => m.default);
|
||||
} catch (e) {
|
||||
console.error('typescript must be installed to use "native" functions');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {import('./cache.js').TSConfckCache} [cache]
|
||||
* @returns {Promise<string|void>}
|
||||
*/
|
||||
export async function resolveTSConfigJson(filename, cache) {
|
||||
if (path.extname(filename) !== '.json') {
|
||||
return; // ignore files that are not json
|
||||
}
|
||||
const tsconfig = path.resolve(filename);
|
||||
if (cache && (cache.hasParseResult(tsconfig) || cache.hasParseResult(filename))) {
|
||||
return tsconfig;
|
||||
}
|
||||
return fs.stat(tsconfig).then((stat) => {
|
||||
if (stat.isFile() || stat.isFIFO()) {
|
||||
return tsconfig;
|
||||
} else {
|
||||
throw new Error(`${filename} exists but is not a regular file.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} dir an absolute directory path
|
||||
* @returns {boolean} if dir path includes a node_modules segment
|
||||
*/
|
||||
export const isInNodeModules = IS_POSIX
|
||||
? (dir) => dir.includes('/node_modules/')
|
||||
: (dir) => dir.match(/[/\\]node_modules[/\\]/);
|
||||
|
||||
/**
|
||||
* convert posix separator to native separator
|
||||
*
|
||||
* eg.
|
||||
* windows: C:/foo/bar -> c:\foo\bar
|
||||
* linux: /foo/bar -> /foo/bar
|
||||
*
|
||||
* @param {string} filename with posix separators
|
||||
* @returns {string} filename with native separators
|
||||
*/
|
||||
export const posix2native = IS_POSIX
|
||||
? (filename) => filename
|
||||
: (filename) => filename.replace(POSIX_SEP_RE, path.sep);
|
||||
|
||||
/**
|
||||
* convert native separator to posix separator
|
||||
*
|
||||
* eg.
|
||||
* windows: C:\foo\bar -> c:/foo/bar
|
||||
* linux: /foo/bar -> /foo/bar
|
||||
*
|
||||
* @param {string} filename - filename with native separators
|
||||
* @returns {string} filename with posix separators
|
||||
*/
|
||||
export const native2posix = IS_POSIX
|
||||
? (filename) => filename
|
||||
: (filename) => filename.replace(NATIVE_SEP_RE, path.posix.sep);
|
||||
|
||||
/**
|
||||
* converts params to native separator, resolves path and converts native back to posix
|
||||
*
|
||||
* needed on windows to handle posix paths in tsconfig
|
||||
*
|
||||
* @param dir {string|null} directory to resolve from
|
||||
* @param filename {string} filename or pattern to resolve
|
||||
* @returns string
|
||||
*/
|
||||
export const resolve2posix = IS_POSIX
|
||||
? (dir, filename) => (dir ? path.resolve(dir, filename) : path.resolve(filename))
|
||||
: (dir, filename) =>
|
||||
native2posix(
|
||||
dir
|
||||
? path.resolve(posix2native(dir), posix2native(filename))
|
||||
: path.resolve(posix2native(filename))
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
* @param {import('./public.d.ts').TSConfckParseOptions} [options]
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function resolveReferencedTSConfigFiles(result, options) {
|
||||
const dir = path.dirname(result.tsconfigFile);
|
||||
return result.tsconfig.references.map((ref) => {
|
||||
const refPath = ref.path.endsWith('.json')
|
||||
? ref.path
|
||||
: path.join(ref.path, options?.configName ?? 'tsconfig.json');
|
||||
return resolve2posix(dir, refPath);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
* @returns {import('./public.d.ts').TSConfckParseResult}
|
||||
*/
|
||||
export function resolveSolutionTSConfig(filename, result) {
|
||||
const allowJs = result.tsconfig.compilerOptions?.allowJs;
|
||||
const extensions = allowJs ? TSJS_EXTENSIONS : TS_EXTENSIONS;
|
||||
if (
|
||||
result.referenced &&
|
||||
extensions.some((ext) => filename.endsWith(ext)) &&
|
||||
!isIncluded(filename, result)
|
||||
) {
|
||||
const solutionTSConfig = result.referenced.find((referenced) =>
|
||||
isIncluded(filename, referenced)
|
||||
);
|
||||
if (solutionTSConfig) {
|
||||
return solutionTSConfig;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} filename
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isIncluded(filename, result) {
|
||||
const dir = native2posix(path.dirname(result.tsconfigFile));
|
||||
const files = (result.tsconfig.files || []).map((file) => resolve2posix(dir, file));
|
||||
const absoluteFilename = resolve2posix(null, filename);
|
||||
if (files.includes(filename)) {
|
||||
return true;
|
||||
}
|
||||
const allowJs = result.tsconfig.compilerOptions?.allowJs;
|
||||
const isIncluded = isGlobMatch(
|
||||
absoluteFilename,
|
||||
dir,
|
||||
result.tsconfig.include || (result.tsconfig.files ? [] : [GLOB_ALL_PATTERN]),
|
||||
allowJs
|
||||
);
|
||||
if (isIncluded) {
|
||||
const isExcluded = isGlobMatch(absoluteFilename, dir, result.tsconfig.exclude || [], allowJs);
|
||||
return !isExcluded;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* test filenames agains glob patterns in tsconfig
|
||||
*
|
||||
* @param filename {string} posix style abolute path to filename to test
|
||||
* @param dir {string} posix style absolute path to directory of tsconfig containing patterns
|
||||
* @param patterns {string[]} glob patterns to match against
|
||||
* @param allowJs {boolean} allowJs setting in tsconfig to include js extensions in checks
|
||||
* @returns {boolean} true when at least one pattern matches filename
|
||||
*/
|
||||
export function isGlobMatch(filename, dir, patterns, allowJs) {
|
||||
const extensions = allowJs ? TSJS_EXTENSIONS : TS_EXTENSIONS;
|
||||
return patterns.some((pattern) => {
|
||||
// filename must end with part of pattern that comes after last wildcard
|
||||
let lastWildcardIndex = pattern.length;
|
||||
let hasWildcard = false;
|
||||
let hasExtension = false;
|
||||
let hasSlash = false;
|
||||
let lastSlashIndex = -1;
|
||||
for (let i = pattern.length - 1; i > -1; i--) {
|
||||
const c = pattern[i];
|
||||
if (!hasWildcard) {
|
||||
if (c === '*' || c === '?') {
|
||||
lastWildcardIndex = i;
|
||||
hasWildcard = true;
|
||||
}
|
||||
}
|
||||
if (!hasSlash) {
|
||||
if (c === '.') {
|
||||
hasExtension = true;
|
||||
} else if (c === '/') {
|
||||
lastSlashIndex = i;
|
||||
hasSlash = true;
|
||||
}
|
||||
}
|
||||
if (hasWildcard && hasSlash) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasExtension && (!hasWildcard || lastWildcardIndex < lastSlashIndex)) {
|
||||
// add implicit glob
|
||||
pattern += `${pattern.endsWith('/') ? '' : '/'}${GLOB_ALL_PATTERN}`;
|
||||
lastWildcardIndex = pattern.length - 1;
|
||||
hasWildcard = true;
|
||||
}
|
||||
|
||||
// if pattern does not end with wildcard, filename must end with pattern after last wildcard
|
||||
if (
|
||||
lastWildcardIndex < pattern.length - 1 &&
|
||||
!filename.endsWith(pattern.slice(lastWildcardIndex + 1))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if pattern ends with *, filename must end with a default extension
|
||||
if (pattern.endsWith('*') && !extensions.some((ext) => filename.endsWith(ext))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// for **/* , filename must start with the dir
|
||||
if (pattern === GLOB_ALL_PATTERN) {
|
||||
return filename.startsWith(`${dir}/`);
|
||||
}
|
||||
|
||||
const resolvedPattern = resolve2posix(dir, pattern);
|
||||
|
||||
// filename must start with part of pattern that comes before first wildcard
|
||||
let firstWildcardIndex = -1;
|
||||
for (let i = 0; i < resolvedPattern.length; i++) {
|
||||
if (resolvedPattern[i] === '*' || resolvedPattern[i] === '?') {
|
||||
firstWildcardIndex = i;
|
||||
hasWildcard = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (
|
||||
firstWildcardIndex > 1 &&
|
||||
!filename.startsWith(resolvedPattern.slice(0, firstWildcardIndex - 1))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasWildcard) {
|
||||
// no wildcard in pattern, filename must be equal to resolved pattern
|
||||
return filename === resolvedPattern;
|
||||
} else if (
|
||||
firstWildcardIndex + GLOB_ALL_PATTERN.length ===
|
||||
resolvedPattern.length - (pattern.length - 1 - lastWildcardIndex) &&
|
||||
resolvedPattern.slice(firstWildcardIndex, firstWildcardIndex + GLOB_ALL_PATTERN.length) ===
|
||||
GLOB_ALL_PATTERN
|
||||
) {
|
||||
// singular glob-all pattern and we already validated prefix and suffix matches
|
||||
return true;
|
||||
}
|
||||
// complex pattern, use regex to check it
|
||||
if (PATTERN_REGEX_CACHE.has(resolvedPattern)) {
|
||||
return PATTERN_REGEX_CACHE.get(resolvedPattern).test(filename);
|
||||
}
|
||||
const regex = pattern2regex(resolvedPattern, allowJs);
|
||||
PATTERN_REGEX_CACHE.set(resolvedPattern, regex);
|
||||
return regex.test(filename);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} resolvedPattern
|
||||
* @param {boolean} allowJs
|
||||
* @returns {RegExp}
|
||||
*/
|
||||
function pattern2regex(resolvedPattern, allowJs) {
|
||||
let regexStr = '^';
|
||||
for (let i = 0; i < resolvedPattern.length; i++) {
|
||||
const char = resolvedPattern[i];
|
||||
if (char === '?') {
|
||||
regexStr += '[^\\/]';
|
||||
continue;
|
||||
}
|
||||
if (char === '*') {
|
||||
if (resolvedPattern[i + 1] === '*' && resolvedPattern[i + 2] === '/') {
|
||||
i += 2;
|
||||
regexStr += '(?:[^\\/]*\\/)*'; // zero or more path segments
|
||||
continue;
|
||||
}
|
||||
regexStr += '[^\\/]*';
|
||||
continue;
|
||||
}
|
||||
if ('/.+^${}()|[]\\'.includes(char)) {
|
||||
regexStr += `\\`;
|
||||
}
|
||||
regexStr += char;
|
||||
}
|
||||
|
||||
// add known file endings if pattern ends on *
|
||||
if (resolvedPattern.endsWith('*')) {
|
||||
regexStr += allowJs ? TSJS_EXTENSIONS_RE_GROUP : TS_EXTENSIONS_RE_GROUP;
|
||||
}
|
||||
regexStr += '$';
|
||||
|
||||
return new RegExp(regexStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* replace tokens like ${configDir}
|
||||
* @param {import('./public.d.ts').TSConfckParseResult} result
|
||||
*/
|
||||
export function replaceTokens(result) {
|
||||
if (result.tsconfig) {
|
||||
result.tsconfig = JSON.parse(
|
||||
JSON.stringify(result.tsconfig)
|
||||
// replace ${configDir}
|
||||
.replaceAll(/"\${configDir}/g, `"${native2posix(path.dirname(result.tsconfigFile))}`)
|
||||
);
|
||||
}
|
||||
}
|
262
node_modules/tsconfck/types/index.d.ts
generated
vendored
Normal file
262
node_modules/tsconfck/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
declare module 'tsconfck' {
|
||||
export interface TSConfckFindOptions {
|
||||
/**
|
||||
* A cache to improve performance for multiple calls in the same project
|
||||
*
|
||||
* Warning: You must clear this cache in case tsconfig files are added/removed during it's lifetime
|
||||
*/
|
||||
cache?: TSConfckCache<TSConfckParseResult | TSConfckParseNativeResult>;
|
||||
|
||||
/**
|
||||
* project root dir, does not continue scanning outside of this directory.
|
||||
*
|
||||
* Improves performance but may lead to different results from native typescript when no tsconfig is found inside root
|
||||
*/
|
||||
root?: string;
|
||||
|
||||
/**
|
||||
* set to true if you don't want to find tsconfig for files inside node_modules
|
||||
*
|
||||
* This is useful if you want to use the output with esbuild.transform as esbuild itself also ignores node_modules
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
ignoreNodeModules?: boolean;
|
||||
|
||||
/**
|
||||
* Override the default name of the config file to find.
|
||||
*
|
||||
* Use `jsconfig.json` in projects that have typechecking for js files with jsconfig.json
|
||||
*
|
||||
* @default tsconfig.json
|
||||
*/
|
||||
configName?: string;
|
||||
}
|
||||
|
||||
export interface TSConfckParseOptions extends TSConfckFindOptions {
|
||||
// same as find options
|
||||
}
|
||||
|
||||
export interface TSConfckFindAllOptions {
|
||||
/**
|
||||
* helper to skip subdirectories when scanning for tsconfig.json
|
||||
*
|
||||
* eg ` dir => dir === 'node_modules' || dir === '.git'`
|
||||
*/
|
||||
skip?: (dir: string) => boolean;
|
||||
/**
|
||||
* list of config filenames to include, use ["tsconfig.json","jsconfig.json"] if you need both
|
||||
*
|
||||
* @default ["tsconfig.json"]
|
||||
*/
|
||||
configNames?: string[];
|
||||
}
|
||||
|
||||
export interface TSConfckParseResult {
|
||||
/**
|
||||
* absolute path to parsed tsconfig.json
|
||||
*/
|
||||
tsconfigFile: string;
|
||||
|
||||
/**
|
||||
* parsed result, including merged values from extended
|
||||
*/
|
||||
tsconfig: any;
|
||||
|
||||
/**
|
||||
* ParseResult for parent solution
|
||||
*/
|
||||
solution?: TSConfckParseResult;
|
||||
|
||||
/**
|
||||
* ParseResults for all tsconfig files referenced in a solution
|
||||
*/
|
||||
referenced?: TSConfckParseResult[];
|
||||
|
||||
/**
|
||||
* ParseResult for all tsconfig files
|
||||
*
|
||||
* [a,b,c] where a extends b and b extends c
|
||||
*/
|
||||
extended?: TSConfckParseResult[];
|
||||
}
|
||||
|
||||
export interface TSConfckParseNativeOptions extends TSConfckParseOptions {
|
||||
/**
|
||||
* Set this option to true to force typescript to ignore all source files.
|
||||
*
|
||||
* This is faster - especially for large projects - but comes with 2 caveats
|
||||
*
|
||||
* 1) output tsconfig always has `files: [],include: []` instead of any real values configured.
|
||||
* 2) as a result of 1), it won't be able to resolve solution-style references and always return the closest tsconfig
|
||||
*/
|
||||
ignoreSourceFiles?: boolean;
|
||||
}
|
||||
|
||||
export interface TSConfckParseNativeResult {
|
||||
/**
|
||||
* absolute path to parsed tsconfig.json
|
||||
*/
|
||||
tsconfigFile: string;
|
||||
|
||||
/**
|
||||
* parsed result, including merged values from extended and normalized
|
||||
*/
|
||||
tsconfig: any;
|
||||
|
||||
/**
|
||||
* ParseResult for parent solution
|
||||
*/
|
||||
solution?: TSConfckParseNativeResult;
|
||||
|
||||
/**
|
||||
* ParseNativeResults for all tsconfig files referenced in a solution
|
||||
*/
|
||||
referenced?: TSConfckParseNativeResult[];
|
||||
|
||||
/**
|
||||
* full output of ts.parseJsonConfigFileContent
|
||||
*/
|
||||
result: any;
|
||||
}
|
||||
export class TSConfckCache<T> {
|
||||
/**
|
||||
* clear cache, use this if you have a long running process and tsconfig files have been added,changed or deleted
|
||||
*/
|
||||
clear(): void;
|
||||
/**
|
||||
* has cached closest config for files in dir
|
||||
* */
|
||||
hasConfigPath(dir: string, configName?: string): boolean;
|
||||
/**
|
||||
* get cached closest tsconfig for files in dir
|
||||
* @throws {unknown} if cached value is an error
|
||||
*/
|
||||
getConfigPath(dir: string, configName?: string): Promise<string | null> | string | null;
|
||||
/**
|
||||
* has parsed tsconfig for file
|
||||
* */
|
||||
hasParseResult(file: string): boolean;
|
||||
/**
|
||||
* get parsed tsconfig for file
|
||||
* @throws {unknown} if cached value is an error
|
||||
*/
|
||||
getParseResult(file: string): Promise<T> | T;
|
||||
/**
|
||||
* @param isRootFile a flag to check if current file which involking the parse() api, used to distinguish the normal cache which only parsed by parseFile()
|
||||
* */
|
||||
private setParseResult;
|
||||
|
||||
private setConfigPath;
|
||||
#private;
|
||||
}
|
||||
/**
|
||||
* find the closest tsconfig.json file
|
||||
*
|
||||
* @param filename - path to file to find tsconfig for (absolute or relative to cwd)
|
||||
* @param options - options
|
||||
* @returns absolute path to closest tsconfig.json or null if not found
|
||||
*/
|
||||
export function find(filename: string, options?: TSConfckFindOptions): Promise<string | null>;
|
||||
/**
|
||||
* find all tsconfig.json files in dir
|
||||
*
|
||||
* @param dir - path to dir (absolute or relative to cwd)
|
||||
* @param options - options
|
||||
* @returns list of absolute paths to all found tsconfig.json files
|
||||
*/
|
||||
export function findAll(dir: string, options?: TSConfckFindAllOptions): Promise<string[]>;
|
||||
/**
|
||||
* convert content of tsconfig.json to regular json
|
||||
*
|
||||
* @param tsconfigJson - content of tsconfig.json
|
||||
* @returns content as regular json, comments and dangling commas have been replaced with whitespace
|
||||
*/
|
||||
export function toJson(tsconfigJson: string): string;
|
||||
/**
|
||||
* find the closest tsconfig.json file using native ts.findConfigFile
|
||||
*
|
||||
* You must have `typescript` installed to use this
|
||||
*
|
||||
* @param filename - path to file to find tsconfig for (absolute or relative to cwd)
|
||||
* @param options - options
|
||||
* @returns absolute path to closest tsconfig.json
|
||||
*/
|
||||
export function findNative(filename: string, options?: TSConfckFindOptions): Promise<string>;
|
||||
/**
|
||||
* parse the closest tsconfig.json file
|
||||
*
|
||||
* @param filename - path to a tsconfig .json or a source file or directory (absolute or relative to cwd)
|
||||
* @param options - options
|
||||
* */
|
||||
export function parse(filename: string, options?: TSConfckParseOptions): Promise<TSConfckParseResult>;
|
||||
export class TSConfckParseError extends Error {
|
||||
/**
|
||||
*
|
||||
* @param message - error message
|
||||
* @param code - error code
|
||||
* @param tsconfigFile - path to tsconfig file
|
||||
* @param cause - cause of this error
|
||||
*/
|
||||
constructor(message: string, code: string, tsconfigFile: string, cause: Error | null);
|
||||
/**
|
||||
* error code
|
||||
* */
|
||||
code: string;
|
||||
/**
|
||||
* error cause
|
||||
* */
|
||||
cause: Error | undefined;
|
||||
/**
|
||||
* absolute path of tsconfig file where the error happened
|
||||
* */
|
||||
tsconfigFile: string;
|
||||
}
|
||||
/**
|
||||
* parse the closest tsconfig.json file with typescript native functions
|
||||
*
|
||||
* You need to have `typescript` installed to use this
|
||||
*
|
||||
* @param filename - path to a tsconfig .json or a source file (absolute or relative to cwd)
|
||||
* @param options - options
|
||||
* */
|
||||
export function parseNative(filename: string, options?: TSConfckParseNativeOptions): Promise<TSConfckParseNativeResult>;
|
||||
export class TSConfckParseNativeError extends Error {
|
||||
/**
|
||||
*
|
||||
* @param diagnostic - diagnostics of ts
|
||||
* @param tsconfigFile - file that errored
|
||||
* @param result - parsed result, if any
|
||||
*/
|
||||
constructor(diagnostic: TSDiagnosticError, tsconfigFile: string, result: any | null);
|
||||
/**
|
||||
* code of typescript diagnostic, prefixed with "TS "
|
||||
* */
|
||||
code: string;
|
||||
/**
|
||||
* full ts diagnostic that caused this error
|
||||
* */
|
||||
diagnostic: TSDiagnosticError;
|
||||
/**
|
||||
* native result if present, contains all errors in result.errors
|
||||
* */
|
||||
result: any | undefined;
|
||||
/**
|
||||
* absolute path of tsconfig file where the error happened
|
||||
* */
|
||||
tsconfigFile: string;
|
||||
}
|
||||
/**
|
||||
* {
|
||||
* code: number;
|
||||
* category: number;
|
||||
* messageText: string;
|
||||
* start?: number;
|
||||
* } TSDiagnosticError
|
||||
*/
|
||||
type TSDiagnosticError = any;
|
||||
|
||||
export {};
|
||||
}
|
||||
|
||||
//# sourceMappingURL=index.d.ts.map
|
46
node_modules/tsconfck/types/index.d.ts.map
generated
vendored
Normal file
46
node_modules/tsconfck/types/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"version": 3,
|
||||
"file": "index.d.ts",
|
||||
"names": [
|
||||
"TSConfckFindOptions",
|
||||
"TSConfckParseOptions",
|
||||
"TSConfckFindAllOptions",
|
||||
"TSConfckParseResult",
|
||||
"TSConfckParseNativeOptions",
|
||||
"TSConfckParseNativeResult",
|
||||
"TSConfckCache",
|
||||
"find",
|
||||
"findAll",
|
||||
"toJson",
|
||||
"findNative",
|
||||
"parse",
|
||||
"TSConfckParseError",
|
||||
"parseNative",
|
||||
"TSConfckParseNativeError",
|
||||
"TSDiagnosticError"
|
||||
],
|
||||
"sources": [
|
||||
"../src/public.d.ts",
|
||||
"../src/cache.js",
|
||||
"../src/find.js",
|
||||
"../src/find-all.js",
|
||||
"../src/to-json.js",
|
||||
"../src/find-native.js",
|
||||
"../src/parse.js",
|
||||
"../src/parse-native.js",
|
||||
"../src/parse-native.d.ts"
|
||||
],
|
||||
"sourcesContent": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"mappings": ";kBAEiBA,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkCnBC,oBAAoBA;;;;kBAIpBC,sBAAsBA;;;;;;;;;;;;;;;kBAetBC,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BnBC,0BAA0BA;;;;;;;;;;;;kBAY1BC,yBAAyBA;;;;;;;;;;;;;;;;;;;;;;;;;;cC/F7BC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCSJC,IAAIA;;;;;;;;iBCYJC,OAAOA;;;;;;;iBCTbC,MAAMA;;;;;;;;;;iBCDAC,UAAUA;;;;;;;iBCgBVC,KAAKA;cA8VdC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC9VTC,WAAWA;cAoOpBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MChNzBC,iBAAiBA",
|
||||
"ignoreList": []
|
||||
}
|
Reference in New Issue
Block a user