Socket
Socket
Sign inDemoInstall

tsconfck

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tsconfck - npm Package Compare versions

Comparing version 1.1.2 to 1.2.0

src/find-all.ts

13

bin/tsconfck.js
#!/usr/bin/env node
import { parse, find } from '../dist/index.js';
import { parse, find, findAll } from '../dist/index.js';
import * as process from 'process';

@@ -8,3 +8,3 @@

Commands: find, parse, parse-result
Commands: find, find-all, parse, parse-result

@@ -15,2 +15,7 @@ Examples:

> tsconfck find-all src/
> /src/foo/tsconfig.json
> /src/bar/tsconfig.json
> /src/tsconfig.json
> tsconfck parse src/index.ts

@@ -30,3 +35,3 @@ >{

const HELP_ARGS = ['-h', '--help', '-?', 'help'];
const COMMANDS = ['find', 'parse', 'parse-result'];
const COMMANDS = ['find', 'find-all', 'parse', 'parse-result'];
function needsHelp(args) {

@@ -56,2 +61,4 @@ if (args.some((arg) => HELP_ARGS.includes(arg))) {

return JSON.stringify(await parse(file), null, 2);
} else if (command === 'find-all') {
return (await findAll(file || '.')).join('\n');
}

@@ -58,0 +65,0 @@ }

@@ -5,7 +5,39 @@ /**

* @param {string} filename - path to file to find tsconfig for (absolute or relative to cwd)
* @param {TSConfckFindOptions} options - options
* @returns {Promise<string>} absolute path to closest tsconfig.json
*/
declare function find(filename: string): Promise<string>;
declare function find(filename: string, options?: TSConfckFindOptions): Promise<string>;
interface TSConfckFindOptions {
/**
* Set of known tsconfig file locations to use instead of scanning the file system
*
* This is better for performance in projects like vite where find is called frequently but tsconfig locations rarely change
* You can use `findAll` to build this
*/
tsConfigPaths?: Set<string>;
/**
* 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;
}
/**
* find all tsconfig.json files in dir
*
* @param {string} dir - path to dir (absolute or relative to cwd)
* @param {TSConfckFindAllOptions} options - options
* @returns {Promise<string[]>} list of absolute paths to all found tsconfig.json files
*/
declare function findAll(dir: string, options?: TSConfckFindAllOptions): Promise<string[]>;
interface TSConfckFindAllOptions {
/**
* helper to skip subdirectories when scanning for tsconfig.json
*
* eg ` dir => dir === 'node_modules' || dir === '.git'`
*/ skip?: (dir: string) => boolean;
}
/**
* convert content of tsconfig.json to regular json

@@ -27,3 +59,3 @@ *

declare function parse(filename: string, options?: TSConfckParseOptions): Promise<TSConfckParseResult>;
interface TSConfckParseOptions {
interface TSConfckParseOptions extends TSConfckFindOptions {
/**

@@ -176,2 +208,2 @@ * optional cache map to speed up repeated parsing with multiple files

export { TSConfckParseError, TSConfckParseNativeError, TSConfckParseNativeOptions, TSConfckParseNativeResult, TSConfckParseOptions, TSConfckParseResult, find, findNative, parse, parseNative, toJson };
export { TSConfckParseError, TSConfckParseNativeError, TSConfckParseNativeOptions, TSConfckParseNativeResult, TSConfckParseOptions, TSConfckParseResult, find, findAll, findNative, parse, parseNative, toJson };

@@ -24,9 +24,13 @@ var __defProp = Object.defineProperty;

import { promises as fs } from "fs";
async function find(filename) {
async function find(filename, options) {
let dir = path.dirname(path.resolve(filename));
const root = (options == null ? void 0 : options.root) ? path.resolve(options.root) : null;
while (dir) {
const tsconfig = await tsconfigInDir(dir);
const tsconfig = await tsconfigInDir(dir, options);
if (tsconfig) {
return tsconfig;
} else {
if (root === dir) {
break;
}
const parent = path.dirname(dir);

@@ -42,4 +46,7 @@ if (parent === dir) {

}
async function tsconfigInDir(dir) {
async function tsconfigInDir(dir, options) {
const tsconfig = path.join(dir, "tsconfig.json");
if (options == null ? void 0 : options.tsConfigPaths) {
return options.tsConfigPaths.has(tsconfig) ? tsconfig : void 0;
}
try {

@@ -57,2 +64,25 @@ const stat = await fs.stat(tsconfig);

// src/find-all.ts
import path2 from "path";
import { promises as fs2 } from "fs";
async function findAll(dir, options) {
const files = [];
for await (const tsconfigFile of findTSConfig(path2.resolve(dir), options)) {
files.push(tsconfigFile);
}
return files;
}
async function* findTSConfig(dir, options, visited = /* @__PURE__ */ new Set()) {
if (!visited.has(dir)) {
const dirents = await fs2.readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
if (dirent.isDirectory() && (!(options == null ? void 0 : options.skip) || !options.skip(dirent.name))) {
yield* findTSConfig(path2.resolve(dir, dirent.name), options, visited);
} else if (dirent.isFile() && dirent.name === "tsconfig.json") {
yield path2.resolve(dir, dirent.name);
}
}
}
}
// src/to-json.ts

@@ -167,11 +197,11 @@ function toJson(tsconfigJson) {

// src/parse.ts
import path3 from "path";
import { promises as fs3 } from "fs";
import path4 from "path";
import { promises as fs4 } from "fs";
import { createRequire } from "module";
// src/util.ts
import path2 from "path";
import { promises as fs2 } from "fs";
var POSIX_SEP_RE = new RegExp("\\" + path2.posix.sep, "g");
var NATIVE_SEP_RE = new RegExp("\\" + path2.sep, "g");
import path3 from "path";
import { promises as fs3 } from "fs";
var POSIX_SEP_RE = new RegExp("\\" + path3.posix.sep, "g");
var NATIVE_SEP_RE = new RegExp("\\" + path3.sep, "g");
var PATTERN_REGEX_CACHE = /* @__PURE__ */ new Map();

@@ -191,8 +221,8 @@ var GLOB_ALL_PATTERN = `**/*`;

async function resolveTSConfig(filename) {
if (path2.extname(filename) !== ".json") {
if (path3.extname(filename) !== ".json") {
return;
}
const tsconfig = path2.resolve(filename);
const tsconfig = path3.resolve(filename);
try {
const stat = await fs2.stat(tsconfig);
const stat = await fs3.stat(tsconfig);
if (stat.isFile() || stat.isFIFO()) {

@@ -209,17 +239,17 @@ return tsconfig;

function posix2native(filename) {
return path2.posix.sep !== path2.sep && filename.includes(path2.posix.sep) ? filename.replace(POSIX_SEP_RE, path2.sep) : filename;
return path3.posix.sep !== path3.sep && filename.includes(path3.posix.sep) ? filename.replace(POSIX_SEP_RE, path3.sep) : filename;
}
function native2posix(filename) {
return path2.posix.sep !== path2.sep && filename.includes(path2.sep) ? filename.replace(NATIVE_SEP_RE, path2.posix.sep) : filename;
return path3.posix.sep !== path3.sep && filename.includes(path3.sep) ? filename.replace(NATIVE_SEP_RE, path3.posix.sep) : filename;
}
function resolve2posix(dir, filename) {
if (path2.sep === path2.posix.sep) {
return dir ? path2.resolve(dir, filename) : path2.resolve(filename);
if (path3.sep === path3.posix.sep) {
return dir ? path3.resolve(dir, filename) : path3.resolve(filename);
}
return native2posix(dir ? path2.resolve(posix2native(dir), posix2native(filename)) : path2.resolve(posix2native(filename)));
return native2posix(dir ? path3.resolve(posix2native(dir), posix2native(filename)) : path3.resolve(posix2native(filename)));
}
function resolveReferencedTSConfigFiles(result) {
const dir = path2.dirname(result.tsconfigFile);
const dir = path3.dirname(result.tsconfigFile);
return result.tsconfig.references.map((ref) => {
const refPath = ref.path.endsWith(".json") ? ref.path : path2.join(ref.path, "tsconfig.json");
const refPath = ref.path.endsWith(".json") ? ref.path : path3.join(ref.path, "tsconfig.json");
return resolve2posix(dir, refPath);

@@ -240,3 +270,3 @@ });

function isIncluded(filename, result) {
const dir = native2posix(path2.dirname(result.tsconfigFile));
const dir = native2posix(path3.dirname(result.tsconfigFile));
const files = (result.tsconfig.files || []).map((file) => resolve2posix(dir, file));

@@ -335,3 +365,3 @@ const absoluteFilename = resolve2posix(null, filename);

try {
tsconfigFile = await resolveTSConfig(filename) || await find(filename);
tsconfigFile = await resolveTSConfig(filename) || await find(filename, options);
} catch (e) {

@@ -346,3 +376,3 @@ const notFoundResult = {

} else {
tsconfigFile = await resolveTSConfig(filename) || await find(filename);
tsconfigFile = await resolveTSConfig(filename) || await find(filename, options);
}

@@ -366,7 +396,7 @@ let result;

try {
const tsconfigJson = await fs3.readFile(tsconfigFile, "utf-8");
const tsconfigJson = await fs4.readFile(tsconfigFile, "utf-8");
const json = toJson(tsconfigJson);
const result = {
tsconfigFile,
tsconfig: normalizeTSConfig(JSON.parse(json), path3.dirname(tsconfigFile))
tsconfig: normalizeTSConfig(JSON.parse(json), path4.dirname(tsconfigFile))
};

@@ -381,3 +411,3 @@ cache == null ? void 0 : cache.set(tsconfigFile, result);

var _a;
if (((_a = tsconfig.compilerOptions) == null ? void 0 : _a.baseUrl) && !path3.isAbsolute(tsconfig.compilerOptions.baseUrl)) {
if (((_a = tsconfig.compilerOptions) == null ? void 0 : _a.baseUrl) && !path4.isAbsolute(tsconfig.compilerOptions.baseUrl)) {
tsconfig.compilerOptions.baseUrl = resolve2posix(dir, tsconfig.compilerOptions.baseUrl);

@@ -437,3 +467,3 @@ }

const extendedConfig = extended.tsconfig;
const relativePath = native2posix(path3.relative(path3.dirname(extending.tsconfigFile), path3.dirname(extended.tsconfigFile)));
const relativePath = native2posix(path4.relative(path4.dirname(extending.tsconfigFile), path4.dirname(extended.tsconfigFile)));
for (const key of Object.keys(extendedConfig).filter((key2) => EXTENDABLE_KEYS.includes(key2))) {

@@ -487,6 +517,6 @@ if (key === "compilerOptions") {

function rebasePath(value, prependPath) {
if (path3.isAbsolute(value)) {
if (path4.isAbsolute(value)) {
return value;
} else {
return path3.posix.normalize(path3.posix.join(prependPath, value));
return path4.posix.normalize(path4.posix.join(prependPath, value));
}

@@ -506,7 +536,7 @@ }

// src/find-native.ts
import path4 from "path";
import path5 from "path";
async function findNative(filename) {
const ts = await loadTS();
const { findConfigFile, sys } = ts;
const tsconfigFile = findConfigFile(path4.dirname(path4.resolve(filename)), sys.fileExists);
const tsconfigFile = findConfigFile(path5.dirname(path5.resolve(filename)), sys.fileExists);
if (!tsconfigFile) {

@@ -519,3 +549,3 @@ throw new Error(`no tsconfig file found for ${filename}`);

// src/parse-native.ts
import path5 from "path";
import path6 from "path";
async function parseNative(filename, options) {

@@ -582,3 +612,3 @@ const cache = options == null ? void 0 : options.cache;

}
const nativeResult = parseJsonConfigFileContent(config, host, path5.dirname(posixTSConfigFile), void 0, posixTSConfigFile);
const nativeResult = parseJsonConfigFileContent(config, host, path6.dirname(posixTSConfigFile), void 0, posixTSConfigFile);
checkErrors(nativeResult, tsconfigFile);

@@ -681,2 +711,3 @@ const result = {

find,
findAll,
findNative,

@@ -683,0 +714,0 @@ parse,

{
"name": "tsconfck",
"version": "1.1.2",
"version": "1.2.0",
"description": "A utility to work with tsconfig.json without typescript",

@@ -49,8 +49,8 @@ "license": "MIT",

"devDependencies": {
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@commitlint/cli": "^16.2.1",
"@commitlint/config-conventional": "^16.2.1",
"@tsconfig/node12": "^1.0.9",
"@types/node": "^16.11.21",
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@types/node": "^16.11.25",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"c8": "^7.11.0",

@@ -60,11 +60,11 @@ "chalk": "^5.0.0",

"enquirer": "^2.3.6",
"esbuild": "^0.14.13",
"eslint": "^8.7.0",
"eslint-config-prettier": "^8.3.0",
"esbuild": "^0.14.23",
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.4.0",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"execa": "^6.0.0",
"execa": "^6.1.0",
"husky": "^7.0.4",
"lint-staged": "^12.3.1",
"lint-staged": "^12.3.4",
"minimist": "^1.2.5",

@@ -77,3 +77,3 @@ "npm-run-all": "^4.1.5",

"tsm": "^2.2.1",
"tsup": "^5.11.11",
"tsup": "^5.11.13",
"typescript": "^4.5.5",

@@ -110,3 +110,3 @@ "uvu": "^0.5.3",

},
"readme": "# tsconfck\n\n[![npm version](https://img.shields.io/npm/v/tsconfck)](https://www.npmjs.com/package/tsconfck)\n[![CI](https://github.com/dominikg/tsconfck/actions/workflows/test.yml/badge.svg)](https://github.com/dominikg/tsconfck/actions/workflows/test.yml)\n\nA utility to find and parse tsconfig files without depending on typescript\n\n# Why\n\nBecause no simple official api exists and tsconfig.json isn't actual json.\n\n# Features\n\n- [x] find closest tsconfig.json\n- [x] convert tsconfig.json to actual json and parse it\n- [x] resolve \"extends\"\n- [x] resolve \"references\" of solution-style tsconfig\n- [x] optional findNative and parseNative to use official typescript api\n- [x] zero dependencies (typescript optional)\n- [x] extensive testsuite\n\n# Install\n\n```shell\nnpm install --save-dev tsconfck # or pnpm, yarn\n```\n\n# Usage\n\n## without typescript installed\n\n```js\nimport { parse } from 'tsconfck';\nconst {\n\ttsconfigFile, // full path to found tsconfig\n\ttsconfig, // tsconfig object including merged values from extended configs\n\textended, // separate unmerged results of all tsconfig files that contributed to tsconfig\n\tsolution, // solution result if tsconfig is part of a solution\n\treferenced // referenced tsconfig results if tsconfig is a solution\n} = await parse('foo/bar.ts');\n```\n\n## with typescript\n\n```js\nimport { parseNative } from 'tsconfck';\nconst {\n\ttsconfigFile, // full path to found tsconfig\n\ttsconfig, // tsconfig object including merged values from extended configs, normalized\n\tresult, // output of ts.parseJsonConfigFileContent\n\tsolution, // solution result if tsconfig is part of a solution\n\treferenced // referenced tsconfig results if tsconfig is a solution\n} = await parseNative('foo/bar.ts');\n```\n\n## API\n\nsee [API-DOCS](docs/api.md)\n\n## Advanced\n\n### caching\n\nYou can use a map to cache results and avoid reparsing if you process multiple ts files that share few tsconfig files\n\n```js\nimport { parse } from 'tsconfck';\n// 1. create cache instance\nconst cache = new Map();\n// 2. pass cache instance in options\nconst fooResult = await parse('src/foo.ts', { cache });\n// 3. profit (if they share the same tsconfig.json, it is not parsed again)\nconst barResult = await parse('src/bar.ts', { cache });\n```\n\n> You are responsible for clearing the cache if tsconfig files change on disk during its lifetime.\n>\n> Always clear the whole cache if anything changes as objects in the cache can ref each other\n\n> Returned results are direct cache objects.\n>\n> If you want to modify them, deep-clone first.\n\n### error handling\n\nfind and parse reject for all errors they encounter.\n\nFor parse, you can choose to resolve with an empty result instead if no tsconfig file was found\n\n```js\nimport { parse } from 'tsconfck';\nconst result = await parse('some/path/without/tsconfig/foo.ts', {\n\tresolveWithEmptyIfConfigNotFound: true\n});\n// result = { tsconfigFile: 'no_tsconfig_file_found',tsconfig: {} }\n```\n\n### TSConfig type (optional, requires typescript as devDependency)\n\n```ts\nimport type { TSConfig } from 'pkg-types';\n```\n\nCheck out https://github.com/unjs/pkg-types\n\n### cli\n\nA simple cli wrapper is included, you can use it like this\n\n#### find\n\n```shell\n# prints /path/to/tsconfig.json on stdout\ntsconfck find src/index.ts\n```\n\n#### parse\n\n```shell\n# print content of ParseResult.tsconfig on stdout\ntsconfck parse src/index.ts\n\n# print to file\ntsconfck parse src/index.ts > output.json\n```\n\n#### parse-result\n\n```shell\n# print content of ParseResult on stdout\ntsconfck parse-result src/index.ts\n\n# print to file\ntsconfck parse-result src/index.ts > output.json\n```\n\n#### help\n\n```shell\n# print usage\ntsconfck -h # or --help, -?, help\n```\n\n# Links\n\n- [changelog](CHANGELOG.md)\n\n# Develop\n\nThis repo uses\n\n- [pnpm](https://pnpm.io)\n- [conventional-changelog/commitlint](https://github.com/conventional-changelog/commitlint#what-is-commitlint)\n\nIn addition to default commit-msg prefixes you can use 'wip: ' for commit messages in branches.\nPRs are going to be squash-merged\n\n```shell\n# install dependencies\npnpm install\n# run tests\npnpm test\n#run tests in watch mode (doesn't require dev in parallel)\npnpm test:watch\n```\n\n# License\n\n[MIT](./LICENSE)\n"
"readme": "# tsconfck\n\n[![npm version](https://img.shields.io/npm/v/tsconfck)](https://www.npmjs.com/package/tsconfck)\n[![CI](https://github.com/dominikg/tsconfck/actions/workflows/test.yml/badge.svg)](https://github.com/dominikg/tsconfck/actions/workflows/test.yml)\n\nA utility to find and parse tsconfig files without depending on typescript\n\n# Why\n\nBecause no simple official api exists and tsconfig.json isn't actual json.\n\n# Features\n\n- [x] find closest tsconfig.json\n- [x] convert tsconfig.json to actual json and parse it\n- [x] resolve \"extends\"\n- [x] resolve \"references\" of solution-style tsconfig\n- [x] optional findNative and parseNative to use official typescript api\n- [x] zero dependencies (typescript optional)\n- [x] extensive testsuite\n\n# Install\n\n```shell\nnpm install --save-dev tsconfck # or pnpm, yarn\n```\n\n# Usage\n\n## without typescript installed\n\n```js\nimport { parse } from 'tsconfck';\nconst {\n\ttsconfigFile, // full path to found tsconfig\n\ttsconfig, // tsconfig object including merged values from extended configs\n\textended, // separate unmerged results of all tsconfig files that contributed to tsconfig\n\tsolution, // solution result if tsconfig is part of a solution\n\treferenced // referenced tsconfig results if tsconfig is a solution\n} = await parse('foo/bar.ts');\n```\n\n## with typescript\n\n```js\nimport { parseNative } from 'tsconfck';\nconst {\n\ttsconfigFile, // full path to found tsconfig\n\ttsconfig, // tsconfig object including merged values from extended configs, normalized\n\tresult, // output of ts.parseJsonConfigFileContent\n\tsolution, // solution result if tsconfig is part of a solution\n\treferenced // referenced tsconfig results if tsconfig is a solution\n} = await parseNative('foo/bar.ts');\n```\n\n## API\n\nsee [API-DOCS](docs/api.md)\n\n## Advanced\n\n### caching\n\nYou can use a map to cache results and avoid reparsing if you process multiple ts files that share few tsconfig files\n\n```js\nimport { parse } from 'tsconfck';\n// 1. create cache instance\nconst cache = new Map();\n// 2. pass cache instance in options\nconst fooResult = await parse('src/foo.ts', { cache });\n// 3. profit (if they share the same tsconfig.json, it is not parsed again)\nconst barResult = await parse('src/bar.ts', { cache });\n```\n\n> You are responsible for clearing the cache if tsconfig files change on disk during its lifetime.\n>\n> Always clear the whole cache if anything changes as objects in the cache can ref each other\n\n> Returned results are direct cache objects.\n>\n> If you want to modify them, deep-clone first.\n\n### reduce fs.stat overhead\n\nYou can specify a root directory and provide a set of known tsconfig locations to improve performance in large projects\n\n```js\nimport { parse, findAll } from 'tsconfck';\nconst root = '.';\nconst tsConfigPaths = new Set([\n\t...(await findAll(root, { skip: (dir) => dir === 'node_modules' || dir === '.git' }))\n]);\nconst cache = new Map();\nconst parseOptions = { cache, root, tsConfigPaths };\n// these calls use minimal fs\nconst fooResult = await parse('src/foo.ts', parseOptions);\nconst barResult = await parse('src/bar.ts', parseOptions);\n```\n\n> Using the root option can lead to errors if there is no tsconfig inside root.\n\n> You are responsible for updating tsConfigPaths if tsconfig files are added/removed on disk during its lifetime.\n\n### error handling\n\nfind and parse reject for all errors they encounter.\n\nFor parse, you can choose to resolve with an empty result instead if no tsconfig file was found\n\n```js\nimport { parse } from 'tsconfck';\nconst result = await parse('some/path/without/tsconfig/foo.ts', {\n\tresolveWithEmptyIfConfigNotFound: true\n});\n// result = { tsconfigFile: 'no_tsconfig_file_found',tsconfig: {} }\n```\n\n### TSConfig type (optional, requires typescript as devDependency)\n\n```ts\nimport type { TSConfig } from 'pkg-types';\n```\n\nCheck out https://github.com/unjs/pkg-types\n\n### cli\n\nA simple cli wrapper is included, you can use it like this\n\n#### find\n\n```shell\n# prints /path/to/tsconfig.json on stdout\ntsconfck find src/index.ts\n```\n\n#### find-all\n\n```shell\n# prints all tsconfig.json in dir on stdout\ntsconfck find-all src/\n```\n\n#### parse\n\n```shell\n# print content of ParseResult.tsconfig on stdout\ntsconfck parse src/index.ts\n\n# print to file\ntsconfck parse src/index.ts > output.json\n```\n\n#### parse-result\n\n```shell\n# print content of ParseResult on stdout\ntsconfck parse-result src/index.ts\n\n# print to file\ntsconfck parse-result src/index.ts > output.json\n```\n\n#### help\n\n```shell\n# print usage\ntsconfck -h # or --help, -?, help\n```\n\n# Links\n\n- [changelog](CHANGELOG.md)\n\n# Develop\n\nThis repo uses\n\n- [pnpm](https://pnpm.io)\n- [conventional-changelog/commitlint](https://github.com/conventional-changelog/commitlint#what-is-commitlint)\n\nIn addition to default commit-msg prefixes you can use 'wip: ' for commit messages in branches.\nPRs are going to be squash-merged\n\n```shell\n# install dependencies\npnpm install\n# run tests\npnpm test\n#run tests in watch mode (doesn't require dev in parallel)\npnpm test:watch\n```\n\n# License\n\n[MIT](./LICENSE)\n"
}

@@ -84,2 +84,23 @@ # tsconfck

### reduce fs.stat overhead
You can specify a root directory and provide a set of known tsconfig locations to improve performance in large projects
```js
import { parse, findAll } from 'tsconfck';
const root = '.';
const tsConfigPaths = new Set([
...(await findAll(root, { skip: (dir) => dir === 'node_modules' || dir === '.git' }))
]);
const cache = new Map();
const parseOptions = { cache, root, tsConfigPaths };
// these calls use minimal fs
const fooResult = await parse('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 inside root.
> You are responsible for updating tsConfigPaths if tsconfig files are added/removed on disk during its lifetime.
### error handling

@@ -118,2 +139,9 @@

#### find-all
```shell
# prints all tsconfig.json in dir on stdout
tsconfck find-all src/
```
#### parse

@@ -120,0 +148,0 @@

@@ -8,11 +8,16 @@ import path from 'path';

* @param {string} filename - path to file to find tsconfig for (absolute or relative to cwd)
* @param {TSConfckFindOptions} options - options
* @returns {Promise<string>} absolute path to closest tsconfig.json
*/
export async function find(filename: string) {
export async function find(filename: string, options?: TSConfckFindOptions) {
let dir = path.dirname(path.resolve(filename));
const root = options?.root ? path.resolve(options.root) : null;
while (dir) {
const tsconfig = await tsconfigInDir(dir);
const tsconfig = await tsconfigInDir(dir, options);
if (tsconfig) {
return tsconfig;
} else {
if (root === dir) {
break;
}
const parent = path.dirname(dir);

@@ -29,4 +34,7 @@ if (parent === dir) {

async function tsconfigInDir(dir: string): Promise<string | void> {
async function tsconfigInDir(dir: string, options?: TSConfckFindOptions): Promise<string | void> {
const tsconfig = path.join(dir, 'tsconfig.json');
if (options?.tsConfigPaths) {
return options.tsConfigPaths.has(tsconfig) ? tsconfig : undefined;
}
try {

@@ -44,1 +52,18 @@ const stat = await fs.stat(tsconfig);

}
export interface TSConfckFindOptions {
/**
* Set of known tsconfig file locations to use instead of scanning the file system
*
* This is better for performance in projects like vite where find is called frequently but tsconfig locations rarely change
* You can use `findAll` to build this
*/
tsConfigPaths?: Set<string>;
/**
* 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;
}
export { find } from './find.js';
export { findAll } from './find-all.js';
export { toJson } from './to-json.js';

@@ -3,0 +4,0 @@ export { parse, TSConfckParseOptions, TSConfckParseResult, TSConfckParseError } from './parse.js';

import path from 'path';
import { promises as fs } from 'fs';
import { createRequire } from 'module';
import { find } from './find.js';
import { find, TSConfckFindOptions } from './find.js';
import { toJson } from './to-json.js';

@@ -33,3 +33,3 @@ import {

try {
tsconfigFile = (await resolveTSConfig(filename)) || (await find(filename));
tsconfigFile = (await resolveTSConfig(filename)) || (await find(filename, options));
} catch (e) {

@@ -44,3 +44,3 @@ const notFoundResult = {

} else {
tsconfigFile = (await resolveTSConfig(filename)) || (await find(filename));
tsconfigFile = (await resolveTSConfig(filename)) || (await find(filename, options));
}

@@ -247,3 +247,3 @@ let result;

export interface TSConfckParseOptions {
export interface TSConfckParseOptions extends TSConfckFindOptions {
/**

@@ -250,0 +250,0 @@ * optional cache map to speed up repeated parsing with multiple files

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc