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.0.0-4 to 1.0.0-5

26

dist/index.d.ts

@@ -21,6 +21,17 @@ /**

* @param {string} filename - path to a tsconfig.json or a .ts source file (absolute or relative to cwd)
* @param {ParseOptions} options - options
* @returns {Promise<ParseResult>}
* @throws {ParseError}
*/
declare function parse(filename: string): Promise<ParseResult>;
declare function parse(filename: string, options?: ParseOptions): Promise<ParseResult>;
interface ParseOptions {
/**
* optional cache map to speed up repeated parsing with multiple files
* it is your own responsibility to clear the cache if tsconfig files change during its lifetime
* cache keys are input `filename` and absolute paths to tsconfig.json files
*
* You must not modify cached values.
*/
cache?: Map<string, ParseResult>;
}
interface ParseResult {

@@ -67,6 +78,17 @@ /**

* @param {string} filename - path to a tsconfig.json or a .ts source file (absolute or relative to cwd)
* @param {ParseNativeOptions} options - options
* @returns {Promise<ParseNativeResult>}
* @throws {ParseNativeError}
*/
declare function parseNative(filename: string): Promise<ParseNativeResult>;
declare function parseNative(filename: string, options?: ParseNativeOptions): Promise<ParseNativeResult>;
interface ParseNativeOptions {
/**
* optional cache map to speed up repeated parsing with multiple files
* it is your own responsibility to clear the cache if tsconfig files change during its lifetime
* cache keys are input `filename` and absolute paths to tsconfig.json files
*
* You must not modify cached values.
*/
cache?: Map<string, ParseNativeResult>;
}
interface ParseNativeResult {

@@ -73,0 +95,0 @@ /**

87

dist/index.js

@@ -222,5 +222,4 @@ var __defProp = Object.defineProperty;

function resolveSolutionTSConfig(filename, result) {
var _a;
if ([".ts", ".tsx"].some((ext) => filename.endsWith(ext)) && !isIncluded(filename, result)) {
const solutionTSConfig = (_a = result.referenced) == null ? void 0 : _a.find((referenced) => isIncluded(filename, referenced));
if (result.referenced && [".ts", ".tsx"].some((ext) => filename.endsWith(ext)) && !isIncluded(filename, result)) {
const solutionTSConfig = result.referenced.find((referenced) => isIncluded(filename, referenced));
if (solutionTSConfig) {

@@ -321,16 +320,33 @@ return __spreadProps(__spreadValues({}, solutionTSConfig), {

// src/parse.ts
async function parse(filename) {
async function parse(filename, options) {
const cache = options == null ? void 0 : options.cache;
if (cache == null ? void 0 : cache.has(filename)) {
return cache.get(filename);
}
const tsconfigFile = await resolveTSConfig(filename) || await find(filename);
const result = await parseFile(tsconfigFile);
await Promise.all([parseExtends(result), parseReferences(result)]);
return resolveSolutionTSConfig(filename, result);
let result;
if (cache == null ? void 0 : cache.has(tsconfigFile)) {
result = cache.get(tsconfigFile);
} else {
result = await parseFile(tsconfigFile, cache);
await Promise.all([parseExtends(result, cache), parseReferences(result, cache)]);
cache == null ? void 0 : cache.set(tsconfigFile, result);
}
result = resolveSolutionTSConfig(filename, result);
cache == null ? void 0 : cache.set(filename, result);
return result;
}
async function parseFile(tsconfigFile) {
async function parseFile(tsconfigFile, cache) {
if (cache == null ? void 0 : cache.has(tsconfigFile)) {
return cache.get(tsconfigFile);
}
try {
const tsconfigJson = await fs3.readFile(tsconfigFile, "utf-8");
const json = toJson(tsconfigJson);
return {
const result = {
filename: tsconfigFile,
tsconfig: normalizeTSConfig(JSON.parse(json), path3.dirname(tsconfigFile))
};
cache == null ? void 0 : cache.set(tsconfigFile, result);
return result;
} catch (e) {

@@ -347,3 +363,3 @@ throw new ParseError(`parsing ${tsconfigFile} failed: ${e}`, "PARSE_FILE", e);

}
async function parseReferences(result) {
async function parseReferences(result, cache) {
if (!result.tsconfig.references) {

@@ -353,7 +369,7 @@ return;

const referencedFiles = resolveReferencedTSConfigFiles(result);
const referenced = await Promise.all(referencedFiles.map((file) => parseFile(file)));
await Promise.all(referenced.map((ref) => parseExtends(ref)));
const referenced = await Promise.all(referencedFiles.map((file) => parseFile(file, cache)));
await Promise.all(referenced.map((ref) => parseExtends(ref, cache)));
result.referenced = referenced;
}
async function parseExtends(result) {
async function parseExtends(result, cache) {
if (!result.tsconfig.extends) {

@@ -372,3 +388,3 @@ return;

}
extended.push(await parseFile(extendedTSConfigFile));
extended.push(await parseFile(extendedTSConfigFile, cache));
}

@@ -476,17 +492,31 @@ result.extended = extended;

import path5 from "path";
async function parseNative(filename) {
async function parseNative(filename, options) {
const cache = options == null ? void 0 : options.cache;
if (cache == null ? void 0 : cache.has(filename)) {
return cache.get(filename);
}
let tsconfigFile = await resolveTSConfig(filename);
if (tsconfigFile) {
tsconfigFile = native2posix(tsconfigFile);
} else {
if (!tsconfigFile) {
tsconfigFile = await findNative(filename);
}
const ts = await loadTS();
const result = await parseFile2(tsconfigFile, ts);
await parseReferences2(result, ts);
return resolveSolutionTSConfig(filename, result);
let result;
if (cache == null ? void 0 : cache.has(tsconfigFile)) {
result = cache.get(tsconfigFile);
} else {
const ts = await loadTS();
result = await parseFile2(tsconfigFile, ts, cache);
await parseReferences2(result, ts, cache);
cache == null ? void 0 : cache.set(tsconfigFile, result);
}
result = resolveSolutionTSConfig(filename, result);
cache == null ? void 0 : cache.set(filename, result);
return result;
}
async function parseFile2(tsconfigFile, ts) {
async function parseFile2(tsconfigFile, ts, cache) {
if (cache == null ? void 0 : cache.has(tsconfigFile)) {
return cache.get(tsconfigFile);
}
const posixTSConfigFile = native2posix(tsconfigFile);
const { parseJsonConfigFileContent, readConfigFile, sys } = ts;
const { config, error } = readConfigFile(tsconfigFile, sys.readFile);
const { config, error } = readConfigFile(posixTSConfigFile, sys.readFile);
if (error) {

@@ -501,12 +531,13 @@ throw new ParseNativeError(error, null);

};
const nativeResult = parseJsonConfigFileContent(config, host, path5.dirname(tsconfigFile), void 0, tsconfigFile);
const nativeResult = parseJsonConfigFileContent(config, host, path5.dirname(posixTSConfigFile), void 0, posixTSConfigFile);
checkErrors(nativeResult);
const result = {
filename: posix2native(tsconfigFile),
filename: tsconfigFile,
tsconfig: result2tsconfig(nativeResult, ts),
result: nativeResult
};
cache == null ? void 0 : cache.set(tsconfigFile, result);
return result;
}
async function parseReferences2(result, ts) {
async function parseReferences2(result, ts, cache) {
if (!result.tsconfig.references) {

@@ -516,3 +547,3 @@ return;

const referencedFiles = resolveReferencedTSConfigFiles(result);
result.referenced = await Promise.all(referencedFiles.map((file) => parseFile2(file, ts)));
result.referenced = await Promise.all(referencedFiles.map((file) => parseFile2(file, ts, cache)));
}

@@ -519,0 +550,0 @@ function checkErrors(nativeResult) {

{
"name": "tsconfck",
"version": "1.0.0-4",
"version": "1.0.0-5",
"description": "A utility to work with tsconfig.json without typescript",

@@ -5,0 +5,0 @@ "license": "MIT",

# tsconfck
[![npm version](https://img.shields.io/npm/v/tsconfck)](https://www.npmjs.com/package/tsconfck)
[![CI](https://github.com/dominikg/tsconfck/actions/workflows/test.yml/badge.svg)](https://github.com/dominikg/tsconfck/actions/workflows/test.yml)
A utility to find and parse tsconfig files without depending on typescript

@@ -17,2 +20,8 @@

# Install
```shell
npm install --save-dev tsconfck # or pnpm, yarn
```
# Usage

@@ -39,3 +48,3 @@

filename, // full path to found tsconfig
tsconfig, // tsconfig object including merged values from extended configs
tsconfig, // tsconfig object including merged values from extended configs, normalized
result, // output of ts.parseJsonConfigFileContent

@@ -55,18 +64,22 @@ solution, // solution result if tsconfig is part of a solution

You should cache results to avoid reparsing if you process multiple ts files that share few tsconfig files
You can use a map to cache results and avoid reparsing if you process multiple ts files that share few tsconfig files
```js
import { find, parse } from 'tsconfck';
import { parse } from 'tsconfck';
// 1. create cache instance
const cache = new Map();
const cachedParse = async (filename) => {
const tsconfigFile = find(filename);
if (cache.has(tsconfigFile)) {
return cache.get(tsconfigFile);
}
const parseResult = parse(tsconfigFile);
cache.put(tsconfigFile, parseResult);
return parseResult;
};
// 2. pass cache instance in options
const fooResult = await parse('src/foo.ts', { cache });
// 3. profit (if they share the same tsconfig.json, it is not parsed again)
const barResult = await parse('src/bar.ts', { cache });
```
> You are responsible for clearing the cache if tsconfig files change on disk during its lifetime.
>
> Always clear the whole cache if anything changes as objects in the cache can ref each other
> Returned results are direct cache objects.
>
> If you want to modify them, deep-clone first.
### cli

@@ -73,0 +86,0 @@

@@ -5,3 +5,2 @@ import path from 'path';

native2posix,
posix2native,
resolveReferencedTSConfigFiles,

@@ -19,24 +18,46 @@ resolveSolutionTSConfig,

* @param {string} filename - path to a tsconfig.json or a .ts source file (absolute or relative to cwd)
* @param {ParseNativeOptions} options - options
* @returns {Promise<ParseNativeResult>}
* @throws {ParseNativeError}
*/
export async function parseNative(filename: string): Promise<ParseNativeResult> {
export async function parseNative(
filename: string,
options?: ParseNativeOptions
): Promise<ParseNativeResult> {
const cache = options?.cache;
if (cache?.has(filename)) {
return cache.get(filename)!;
}
let tsconfigFile = await resolveTSConfig(filename);
if (tsconfigFile) {
// convert to C:/foo/bar on windows as ts.readConfigFile expects it that way
tsconfigFile = native2posix(tsconfigFile);
} else {
if (!tsconfigFile) {
tsconfigFile = await findNative(filename);
}
let result: ParseNativeResult;
if (cache?.has(tsconfigFile)) {
result = cache.get(tsconfigFile)!;
} else {
const ts = await loadTS();
result = await parseFile(tsconfigFile, ts, cache);
await parseReferences(result, ts, cache);
cache?.set(tsconfigFile, result);
}
const ts = await loadTS();
const result = await parseFile(tsconfigFile, ts);
await parseReferences(result, ts);
//@ts-ignore
return resolveSolutionTSConfig(filename, result);
result = resolveSolutionTSConfig(filename, result);
//@ts-ignore
cache?.set(filename, result);
return result;
}
async function parseFile(tsconfigFile: string, ts: any) {
async function parseFile(
tsconfigFile: string,
ts: any,
cache?: Map<string, ParseNativeResult>
): Promise<ParseNativeResult> {
if (cache?.has(tsconfigFile)) {
return cache.get(tsconfigFile)!;
}
const posixTSConfigFile = native2posix(tsconfigFile);
const { parseJsonConfigFileContent, readConfigFile, sys } = ts;
const { config, error } = readConfigFile(tsconfigFile, sys.readFile);
const { config, error } = readConfigFile(posixTSConfigFile, sys.readFile);
if (error) {

@@ -56,16 +77,21 @@ throw new ParseNativeError(error, null);

host,
path.dirname(tsconfigFile),
path.dirname(posixTSConfigFile),
undefined,
tsconfigFile
posixTSConfigFile
);
checkErrors(nativeResult);
const result: ParseNativeResult = {
filename: posix2native(tsconfigFile),
filename: tsconfigFile,
tsconfig: result2tsconfig(nativeResult, ts),
result: nativeResult
};
cache?.set(tsconfigFile, result);
return result;
}
async function parseReferences(result: ParseNativeResult, ts: any) {
async function parseReferences(
result: ParseNativeResult,
ts: any,
cache?: Map<string, ParseNativeResult>
) {
if (!result.tsconfig.references) {

@@ -75,3 +101,3 @@ return;

const referencedFiles = resolveReferencedTSConfigFiles(result);
result.referenced = await Promise.all(referencedFiles.map((file) => parseFile(file, ts)));
result.referenced = await Promise.all(referencedFiles.map((file) => parseFile(file, ts, cache)));
}

@@ -185,2 +211,13 @@

export interface ParseNativeOptions {
/**
* optional cache map to speed up repeated parsing with multiple files
* it is your own responsibility to clear the cache if tsconfig files change during its lifetime
* cache keys are input `filename` and absolute paths to tsconfig.json files
*
* You must not modify cached values.
*/
cache?: Map<string, ParseNativeResult>;
}
export interface ParseNativeResult {

@@ -187,0 +224,0 @@ /**

@@ -18,20 +18,41 @@ import path from 'path';

* @param {string} filename - path to a tsconfig.json or a .ts source file (absolute or relative to cwd)
* @param {ParseOptions} options - options
* @returns {Promise<ParseResult>}
* @throws {ParseError}
*/
export async function parse(filename: string): Promise<ParseResult> {
export async function parse(filename: string, options?: ParseOptions): Promise<ParseResult> {
const cache = options?.cache;
if (cache?.has(filename)) {
return cache.get(filename)!;
}
const tsconfigFile = (await resolveTSConfig(filename)) || (await find(filename));
const result = await parseFile(tsconfigFile);
await Promise.all([parseExtends(result), parseReferences(result)]);
return resolveSolutionTSConfig(filename, result);
let result;
if (cache?.has(tsconfigFile)) {
result = cache.get(tsconfigFile)!;
} else {
result = await parseFile(tsconfigFile, cache);
await Promise.all([parseExtends(result, cache), parseReferences(result, cache)]);
cache?.set(tsconfigFile, result);
}
result = resolveSolutionTSConfig(filename, result);
cache?.set(filename, result);
return result;
}
async function parseFile(tsconfigFile: string): Promise<ParseResult> {
async function parseFile(
tsconfigFile: string,
cache?: Map<string, ParseResult>
): Promise<ParseResult> {
if (cache?.has(tsconfigFile)) {
return cache.get(tsconfigFile)!;
}
try {
const tsconfigJson = await fs.readFile(tsconfigFile, 'utf-8');
const json = toJson(tsconfigJson);
return {
const result = {
filename: tsconfigFile,
tsconfig: normalizeTSConfig(JSON.parse(json), path.dirname(tsconfigFile))
};
cache?.set(tsconfigFile, result);
return result;
} catch (e) {

@@ -55,3 +76,3 @@ throw new ParseError(`parsing ${tsconfigFile} failed: ${e}`, 'PARSE_FILE', e);

async function parseReferences(result: ParseResult) {
async function parseReferences(result: ParseResult, cache?: Map<string, ParseResult>) {
if (!result.tsconfig.references) {

@@ -61,8 +82,8 @@ return;

const referencedFiles = resolveReferencedTSConfigFiles(result);
const referenced = await Promise.all(referencedFiles.map((file) => parseFile(file)));
await Promise.all(referenced.map((ref) => parseExtends(ref)));
const referenced = await Promise.all(referencedFiles.map((file) => parseFile(file, cache)));
await Promise.all(referenced.map((ref) => parseExtends(ref, cache)));
result.referenced = referenced;
}
async function parseExtends(result: ParseResult) {
async function parseExtends(result: ParseResult, cache?: Map<string, ParseResult>) {
if (!result.tsconfig.extends) {

@@ -87,3 +108,3 @@ return;

}
extended.push(await parseFile(extendedTSConfigFile));
extended.push(await parseFile(extendedTSConfigFile, cache));
}

@@ -195,2 +216,13 @@ result.extended = extended;

export interface ParseOptions {
/**
* optional cache map to speed up repeated parsing with multiple files
* it is your own responsibility to clear the cache if tsconfig files change during its lifetime
* cache keys are input `filename` and absolute paths to tsconfig.json files
*
* You must not modify cached values.
*/
cache?: Map<string, ParseResult>;
}
export interface ParseResult {

@@ -240,5 +272,5 @@ /**

/**
* code of typescript diagnostic, prefixed with "TS "
* the cause of this error
*/
cause: Error | undefined;
}

@@ -103,4 +103,8 @@ import path from 'path';

export function resolveSolutionTSConfig(filename: string, result: ParseResult): ParseResult {
if (['.ts', '.tsx'].some((ext) => filename.endsWith(ext)) && !isIncluded(filename, result)) {
const solutionTSConfig = result.referenced?.find((referenced) =>
if (
result.referenced &&
['.ts', '.tsx'].some((ext) => filename.endsWith(ext)) &&
!isIncluded(filename, result)
) {
const solutionTSConfig = result.referenced.find((referenced) =>
isIncluded(filename, referenced)

@@ -107,0 +111,0 @@ );

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