ts-ag 1.1.14 → 1.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -18,11 +18,11 @@ declare function discoverAliasTargets(entry: string, verbose: boolean): Promise<
|
|
|
18
18
|
visitedConfigs: string[];
|
|
19
19
|
}>;
|
|
20
20
|
declare function processAliasTarget(target: AliasTarget): Promise<void>;
|
|
21
|
-
declare function syncWatcherPaths(watcher: FSWatcher, currentPaths: Set<string>, nextPaths: Set<string>):
|
|
21
|
+
declare function syncWatcherPaths(watcher: FSWatcher, currentPaths: Set<string>, nextPaths: Set<string>): Set<string>;
|
|
22
22
|
declare function createRegenerator(entry: string, verbose: boolean): {
|
|
23
23
|
run: (reason?: string) => Promise<void>;
|
|
24
|
-
syncConfigWatcher: (watcher: FSWatcher) =>
|
|
25
|
-
syncOutputWatcher: (watcher: FSWatcher) =>
|
|
24
|
+
syncConfigWatcher: (watcher: FSWatcher) => void;
|
|
25
|
+
syncOutputWatcher: (watcher: FSWatcher) => void;
|
|
26
26
|
getTargets: () => AliasTarget[];
|
|
27
27
|
};
|
|
28
28
|
declare function main(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts-alias.d.mts","names":[],"sources":["../../src/scripts/ts-alias.ts"],"mappings":";;;KAwBY,WAAA;EAAgB,UAAA;EAAoB,MAAA;AAAA;AAAA,iBAEhC,MAAA,CAAO,KAAA;;AAAvB;;iBAOgB,mBAAA,CAAoB,UAAA;AAAA,iBAKpB,aAAA,CAAc,YAAA,UAAsB,MAAA;AAAA,iBAKpC,iBAAA,CAAkB,QAAA;AAAA,iBAIlB,WAAA,CAAY,QAAA,UAAkB,OAAA;AAAA,iBAKxB,oBAAA,CACpB,KAAA,UACA,OAAA,YACC,OAAA;EAAU,OAAA,EAAS,WAAA;EAAe,cAAA;AAAA;AAAA,iBAiDf,kBAAA,CAAmB,MAAA,EAAQ,WAAA,GAAc,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"ts-alias.d.mts","names":[],"sources":["../../src/scripts/ts-alias.ts"],"mappings":";;;KAwBY,WAAA;EAAgB,UAAA;EAAoB,MAAA;AAAA;AAAA,iBAEhC,MAAA,CAAO,KAAA;;AAAvB;;iBAOgB,mBAAA,CAAoB,UAAA;AAAA,iBAKpB,aAAA,CAAc,YAAA,UAAsB,MAAA;AAAA,iBAKpC,iBAAA,CAAkB,QAAA;AAAA,iBAIlB,WAAA,CAAY,QAAA,UAAkB,OAAA;AAAA,iBAKxB,oBAAA,CACpB,KAAA,UACA,OAAA,YACC,OAAA;EAAU,OAAA,EAAS,WAAA;EAAe,cAAA;AAAA;AAAA,iBAiDf,kBAAA,CAAmB,MAAA,EAAQ,WAAA,GAAc,OAAA;AAAA,iBAe/C,gBAAA,CAAiB,OAAA,EAAS,SAAA,EAAW,YAAA,EAAc,GAAA,UAAa,SAAA,EAAW,GAAA,WAAc,GAAA;AAAA,iBAUzF,iBAAA,CACd,KAAA,UACA,OAAA;EAEA,GAAA,GAAM,MAAA,cAAoB,OAAA;EAC1B,iBAAA,GAAoB,OAAA,EAAS,SAAA;EAC7B,iBAAA,GAAoB,OAAA,EAAS,SAAA;EAC7B,UAAA,QAAkB,WAAA;AAAA;AAAA,iBAqDE,IAAA,CAAA,GAAQ,OAAA"}
|
|
@@ -102,9 +102,9 @@ async function processAliasTarget(target) {
|
|
|
102
102
|
console.error(error);
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
function syncWatcherPaths(watcher, currentPaths, nextPaths) {
|
|
106
106
|
const toUnwatch = Array.from(currentPaths).filter((filePath) => !nextPaths.has(filePath));
|
|
107
|
-
if (toUnwatch.length > 0)
|
|
107
|
+
if (toUnwatch.length > 0) watcher.unwatch(toUnwatch);
|
|
108
108
|
const toWatch = Array.from(nextPaths).filter((filePath) => !currentPaths.has(filePath));
|
|
109
109
|
if (toWatch.length > 0) watcher.add(toWatch);
|
|
110
110
|
return new Set(nextPaths);
|
|
@@ -113,9 +113,9 @@ function createRegenerator(entry, verbose) {
|
|
|
113
113
|
let isRunning = false;
|
|
114
114
|
let rerunRequested = false;
|
|
115
115
|
let watchedConfigs = /* @__PURE__ */ new Set();
|
|
116
|
-
let
|
|
116
|
+
let watchedOutputDirs = /* @__PURE__ */ new Set();
|
|
117
117
|
let syncedConfigPaths = /* @__PURE__ */ new Set();
|
|
118
|
-
let
|
|
118
|
+
let syncedOutputDirs = /* @__PURE__ */ new Set();
|
|
119
119
|
let targets = [];
|
|
120
120
|
const run = async (reason) => {
|
|
121
121
|
if (isRunning) {
|
|
@@ -133,7 +133,7 @@ function createRegenerator(entry, verbose) {
|
|
|
133
133
|
const result = await discoverAliasTargets(entry, verbose);
|
|
134
134
|
targets = result.targets;
|
|
135
135
|
watchedConfigs = new Set(result.visitedConfigs);
|
|
136
|
-
|
|
136
|
+
watchedOutputDirs = new Set(unique(result.targets.map((target) => target.outDir)));
|
|
137
137
|
if (targets.length === 0) logWarn("No tsconfig files with compilerOptions.outDir were found");
|
|
138
138
|
else await Promise.all(targets.map((target) => processAliasTarget(target)));
|
|
139
139
|
} while (rerunRequested);
|
|
@@ -141,11 +141,11 @@ function createRegenerator(entry, verbose) {
|
|
|
141
141
|
isRunning = false;
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
|
-
const syncConfigWatcher =
|
|
145
|
-
syncedConfigPaths =
|
|
144
|
+
const syncConfigWatcher = (watcher) => {
|
|
145
|
+
syncedConfigPaths = syncWatcherPaths(watcher, syncedConfigPaths, watchedConfigs);
|
|
146
146
|
};
|
|
147
|
-
const syncOutputWatcher =
|
|
148
|
-
|
|
147
|
+
const syncOutputWatcher = (watcher) => {
|
|
148
|
+
syncedOutputDirs = syncWatcherPaths(watcher, syncedOutputDirs, watchedOutputDirs);
|
|
149
149
|
};
|
|
150
150
|
return {
|
|
151
151
|
run,
|
|
@@ -190,6 +190,7 @@ async function main() {
|
|
|
190
190
|
const configWatcher = watch([], {
|
|
191
191
|
persistent: true,
|
|
192
192
|
ignoreInitial: true,
|
|
193
|
+
ignored: ["**/node_modules/**"],
|
|
193
194
|
awaitWriteFinish: {
|
|
194
195
|
stabilityThreshold: 300,
|
|
195
196
|
pollInterval: 100
|
|
@@ -198,13 +199,14 @@ async function main() {
|
|
|
198
199
|
const outputWatcher = watch([], {
|
|
199
200
|
persistent: true,
|
|
200
201
|
ignoreInitial: true,
|
|
202
|
+
ignored: ["**/node_modules/**"],
|
|
201
203
|
awaitWriteFinish: {
|
|
202
204
|
stabilityThreshold: 300,
|
|
203
205
|
pollInterval: 100
|
|
204
206
|
}
|
|
205
207
|
});
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
regenerator.syncConfigWatcher(configWatcher);
|
|
209
|
+
regenerator.syncOutputWatcher(outputWatcher);
|
|
208
210
|
const pending = /* @__PURE__ */ new Map();
|
|
209
211
|
const scheduleTarget = (target, reason) => {
|
|
210
212
|
const key = `${target.configPath}::${target.outDir}`;
|
|
@@ -229,20 +231,20 @@ async function main() {
|
|
|
229
231
|
configWatcher.on("change", async (filePath) => {
|
|
230
232
|
logInfo(`${colorText("cyan", "change")} ${formatPath(filePath)}`);
|
|
231
233
|
await regenerator.run(`changed ${relative(process.cwd(), filePath)}`);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
+
regenerator.syncConfigWatcher(configWatcher);
|
|
235
|
+
regenerator.syncOutputWatcher(outputWatcher);
|
|
234
236
|
});
|
|
235
237
|
configWatcher.on("add", async (filePath) => {
|
|
236
238
|
logInfo(`${colorText("cyan", "add")} ${formatPath(filePath)}`);
|
|
237
239
|
await regenerator.run(`added ${relative(process.cwd(), filePath)}`);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
regenerator.syncConfigWatcher(configWatcher);
|
|
241
|
+
regenerator.syncOutputWatcher(outputWatcher);
|
|
240
242
|
});
|
|
241
243
|
configWatcher.on("unlink", async (filePath) => {
|
|
242
244
|
logInfo(`${colorText("yellow", "remove")} ${formatPath(filePath)}`);
|
|
243
245
|
await regenerator.run(`removed ${relative(process.cwd(), filePath)}`);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
regenerator.syncConfigWatcher(configWatcher);
|
|
247
|
+
regenerator.syncOutputWatcher(outputWatcher);
|
|
246
248
|
});
|
|
247
249
|
outputWatcher.on("addDir", (dirPath) => {
|
|
248
250
|
scheduleTargetsForPath(dirPath, `created ${relative(process.cwd(), dirPath)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts-alias.mjs","names":[],"sources":["../../src/scripts/ts-alias.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport console from 'console';\n// NOTE: dont use aliases here cause this file needs to be compiled first\nimport { existsSync } from 'fs';\nimport { dirname, isAbsolute, relative, resolve } from 'path';\nimport { fileURLToPath } from 'url';\nimport { parseArgs } from 'util';\n\nimport type { FSWatcher } from 'chokidar';\nimport { watch } from 'chokidar';\nimport { type TsConfigResult, parseTsconfig } from 'get-tsconfig';\nimport { replaceTscAliasPaths } from 'tsc-alias';\n\nimport { colorText } from '../utils/cli.js';\n\nconst RELEVANT_OUTPUT_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts'];\n\nconst LABEL = colorText('cyan', '[ts-alias]');\nconst formatPath = (filePath: string): string => colorText('dim', relative(process.cwd(), filePath));\nconst logInfo = (message: string): void => console.log(`${LABEL} ${message}`);\nconst logWarn = (message: string): void => console.warn(`${LABEL} ${colorText('yellow', message)}`);\nconst logError = (message: string): void => console.error(`${LABEL} ${colorText('red', message)}`);\n\nexport type AliasTarget = { configPath: string; outDir: string };\n\nexport function unique(items: string[]): string[] {\n return Array.from(new Set(items));\n}\n\n/**\n * If the path refers to a file then it returns it otherwise joins tsconfig.json\n */\nexport function resolveTsConfigPath(refAbsPath: string): string {\n if (refAbsPath.endsWith('.json')) return refAbsPath;\n return resolve(refAbsPath, 'tsconfig.json');\n}\n\nexport function resolveOutDir(tsconfigPath: string, outDir: string): string {\n if (isAbsolute(outDir)) return outDir;\n return resolve(dirname(tsconfigPath), outDir);\n}\n\nexport function isAliasOutputFile(filePath: string): boolean {\n return RELEVANT_OUTPUT_EXTENSIONS.some((ext) => filePath.endsWith(ext));\n}\n\nexport function isWithinDir(filePath: string, dirPath: string): boolean {\n const relPath = relative(dirPath, filePath);\n return relPath === '' || (!relPath.startsWith('..') && !isAbsolute(relPath));\n}\n\nexport async function discoverAliasTargets(\n entry: string,\n verbose: boolean\n): Promise<{ targets: AliasTarget[]; visitedConfigs: string[] }> {\n const loadedConfigs = new Map<string, TsConfigResult>();\n const visited = new Set<string>();\n const queue: string[] = [entry];\n\n while (queue.length) {\n const tsconfigPath = queue.shift()!;\n if (visited.has(tsconfigPath)) continue;\n visited.add(tsconfigPath);\n\n let res: TsConfigResult;\n\n try {\n const config = parseTsconfig(tsconfigPath);\n if (config) res = { path: tsconfigPath, config };\n else throw new Error('Null returned from getTsConfig');\n } catch (error) {\n logWarn(`Skipping unreadable config: ${formatPath(tsconfigPath)}`);\n if (verbose) console.warn(error);\n continue;\n }\n\n loadedConfigs.set(res.path, res);\n\n const refs = unique(\n (res.config.references ?? []).map((ref) => {\n const absPath = resolve(dirname(res.path), ref.path);\n return resolveTsConfigPath(absPath);\n })\n );\n\n for (const refPath of refs) queue.push(refPath);\n }\n\n const targets = Array.from(loadedConfigs.values())\n .map((res): AliasTarget | undefined => {\n const outDir = res.config.compilerOptions?.outDir;\n if (typeof outDir !== 'string' || outDir.length === 0) {\n if (verbose) logWarn(`Skipping ${formatPath(res.path)} (compilerOptions.outDir is not set)`);\n return undefined;\n }\n\n return { configPath: res.path, outDir: resolveOutDir(res.path, outDir) };\n })\n .filter((target): target is AliasTarget => target !== undefined);\n\n return { targets, visitedConfigs: Array.from(visited) };\n}\n\nexport async function processAliasTarget(target: AliasTarget): Promise<void> {\n if (!existsSync(target.outDir)) {\n logWarn(`Skipping ${formatPath(target.configPath)} (missing outDir ${formatPath(target.outDir)})`);\n return;\n }\n\n try {\n await replaceTscAliasPaths({ configFile: target.configPath, outDir: target.outDir });\n logInfo(`${colorText('green', 'updated')} ${formatPath(target.outDir)} <- ${formatPath(target.configPath)}`);\n } catch (error) {\n logError(`Failed processing ${formatPath(target.configPath)}`);\n console.error(error);\n }\n}\n\nexport async function syncWatcherPaths(\n watcher: FSWatcher,\n currentPaths: Set<string>,\n nextPaths: Set<string>\n): Promise<Set<string>> {\n const toUnwatch = Array.from(currentPaths).filter((filePath) => !nextPaths.has(filePath));\n if (toUnwatch.length > 0) await watcher.unwatch(toUnwatch);\n\n const toWatch = Array.from(nextPaths).filter((filePath) => !currentPaths.has(filePath));\n if (toWatch.length > 0) watcher.add(toWatch);\n\n return new Set(nextPaths);\n}\n\nexport function createRegenerator(\n entry: string,\n verbose: boolean\n): {\n run: (reason?: string) => Promise<void>;\n syncConfigWatcher: (watcher: FSWatcher) => Promise<void>;\n syncOutputWatcher: (watcher: FSWatcher) => Promise<void>;\n getTargets: () => AliasTarget[];\n} {\n let isRunning = false;\n let rerunRequested = false;\n let watchedConfigs = new Set<string>();\n let watchedOutputRoots = new Set<string>();\n let syncedConfigPaths = new Set<string>();\n let syncedOutputRoots = new Set<string>();\n let targets: AliasTarget[] = [];\n\n const run = async (reason?: string): Promise<void> => {\n if (isRunning) {\n rerunRequested = true;\n return;\n }\n isRunning = true;\n\n try {\n do {\n rerunRequested = false;\n if (reason) {\n logInfo(`${colorText('cyan', 'regenerate')} (${reason})`);\n reason = undefined;\n }\n\n const result = await discoverAliasTargets(entry, verbose);\n targets = result.targets;\n watchedConfigs = new Set(result.visitedConfigs);\n watchedOutputRoots = new Set(unique(result.targets.map((target) => dirname(target.outDir))));\n\n if (targets.length === 0) {\n logWarn('No tsconfig files with compilerOptions.outDir were found');\n } else {\n await Promise.all(targets.map((target) => processAliasTarget(target)));\n }\n } while (rerunRequested);\n } finally {\n isRunning = false;\n }\n };\n\n const syncConfigWatcher = async (watcher: FSWatcher): Promise<void> => {\n syncedConfigPaths = await syncWatcherPaths(watcher, syncedConfigPaths, watchedConfigs);\n };\n\n const syncOutputWatcher = async (watcher: FSWatcher): Promise<void> => {\n syncedOutputRoots = await syncWatcherPaths(watcher, syncedOutputRoots, watchedOutputRoots);\n };\n\n return { run, syncConfigWatcher, syncOutputWatcher, getTargets: () => targets };\n}\n\n// Main function\nexport async function main(): Promise<void> {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n config: { type: 'string', short: 'c' },\n watch: { type: 'boolean', short: 'w' },\n verbose: { type: 'boolean', short: 'v' }\n }\n });\n\n const entry = values.config ? resolve(values.config) : null;\n if (!entry) {\n logError('Missing required flag: --config <path/to/tsconfig.json>');\n process.exit(1);\n }\n if (!existsSync(entry)) {\n logError(`Config file not found: ${formatPath(entry)}`);\n process.exit(1);\n }\n\n const watchMode = values.watch === true;\n const verbose = values.verbose === true;\n const regenerator = createRegenerator(entry, verbose);\n\n await regenerator.run('initial run');\n\n if (!watchMode) return;\n\n logInfo('watch mode enabled');\n const configWatcher = watch([], {\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }\n });\n const outputWatcher = watch([], {\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }\n });\n\n await regenerator.syncConfigWatcher(configWatcher);\n await regenerator.syncOutputWatcher(outputWatcher);\n\n const pending = new Map<string, ReturnType<typeof setTimeout>>();\n const scheduleTarget = (target: AliasTarget, reason: string): void => {\n const key = `${target.configPath}::${target.outDir}`;\n const existing = pending.get(key);\n if (existing) clearTimeout(existing);\n\n pending.set(\n key,\n setTimeout(() => {\n pending.delete(key);\n void processAliasTarget(target);\n if (verbose) logInfo(`${colorText('cyan', 'reprocess')} (${reason})`);\n }, 200)\n );\n };\n\n const scheduleTargetsForPath = (filePath: string, reason: string): void => {\n const resolvedPath = resolve(filePath);\n\n for (const target of regenerator.getTargets()) {\n if (resolvedPath === target.outDir) {\n scheduleTarget(target, reason);\n continue;\n }\n if (isAliasOutputFile(resolvedPath) && isWithinDir(resolvedPath, target.outDir)) {\n scheduleTarget(target, reason);\n }\n }\n };\n\n configWatcher.on('change', async (filePath) => {\n logInfo(`${colorText('cyan', 'change')} ${formatPath(filePath)}`);\n await regenerator.run(`changed ${relative(process.cwd(), filePath)}`);\n await regenerator.syncConfigWatcher(configWatcher);\n await regenerator.syncOutputWatcher(outputWatcher);\n });\n\n configWatcher.on('add', async (filePath) => {\n logInfo(`${colorText('cyan', 'add')} ${formatPath(filePath)}`);\n await regenerator.run(`added ${relative(process.cwd(), filePath)}`);\n await regenerator.syncConfigWatcher(configWatcher);\n await regenerator.syncOutputWatcher(outputWatcher);\n });\n\n configWatcher.on('unlink', async (filePath) => {\n logInfo(`${colorText('yellow', 'remove')} ${formatPath(filePath)}`);\n await regenerator.run(`removed ${relative(process.cwd(), filePath)}`);\n await regenerator.syncConfigWatcher(configWatcher);\n await regenerator.syncOutputWatcher(outputWatcher);\n });\n\n outputWatcher.on('addDir', (dirPath) => {\n scheduleTargetsForPath(dirPath, `created ${relative(process.cwd(), dirPath)}`);\n });\n\n outputWatcher.on('add', (filePath) => {\n scheduleTargetsForPath(filePath, `added ${relative(process.cwd(), filePath)}`);\n });\n\n outputWatcher.on('change', (filePath) => {\n scheduleTargetsForPath(filePath, `changed ${relative(process.cwd(), filePath)}`);\n });\n}\n\nfunction isDirectExecution(): boolean {\n if (!process.argv[1]) return false;\n return resolve(process.argv[1]) === fileURLToPath(import.meta.url);\n}\n\nif (isDirectExecution()) {\n main().catch((error) => {\n logError('Unhandled error in ts-alias script');\n console.error(error);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ts-alias.mjs","names":[],"sources":["../../src/scripts/ts-alias.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport console from 'console';\n// NOTE: dont use aliases here cause this file needs to be compiled first\nimport { existsSync } from 'fs';\nimport { dirname, isAbsolute, relative, resolve } from 'path';\nimport { fileURLToPath } from 'url';\nimport { parseArgs } from 'util';\n\nimport type { FSWatcher } from 'chokidar';\nimport { watch } from 'chokidar';\nimport { type TsConfigResult, parseTsconfig } from 'get-tsconfig';\nimport { replaceTscAliasPaths } from 'tsc-alias';\n\nimport { colorText } from '../utils/cli.js';\n\nconst RELEVANT_OUTPUT_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts'];\n\nconst LABEL = colorText('cyan', '[ts-alias]');\nconst formatPath = (filePath: string): string => colorText('dim', relative(process.cwd(), filePath));\nconst logInfo = (message: string): void => console.log(`${LABEL} ${message}`);\nconst logWarn = (message: string): void => console.warn(`${LABEL} ${colorText('yellow', message)}`);\nconst logError = (message: string): void => console.error(`${LABEL} ${colorText('red', message)}`);\n\nexport type AliasTarget = { configPath: string; outDir: string };\n\nexport function unique(items: string[]): string[] {\n return Array.from(new Set(items));\n}\n\n/**\n * If the path refers to a file then it returns it otherwise joins tsconfig.json\n */\nexport function resolveTsConfigPath(refAbsPath: string): string {\n if (refAbsPath.endsWith('.json')) return refAbsPath;\n return resolve(refAbsPath, 'tsconfig.json');\n}\n\nexport function resolveOutDir(tsconfigPath: string, outDir: string): string {\n if (isAbsolute(outDir)) return outDir;\n return resolve(dirname(tsconfigPath), outDir);\n}\n\nexport function isAliasOutputFile(filePath: string): boolean {\n return RELEVANT_OUTPUT_EXTENSIONS.some((ext) => filePath.endsWith(ext));\n}\n\nexport function isWithinDir(filePath: string, dirPath: string): boolean {\n const relPath = relative(dirPath, filePath);\n return relPath === '' || (!relPath.startsWith('..') && !isAbsolute(relPath));\n}\n\nexport async function discoverAliasTargets(\n entry: string,\n verbose: boolean\n): Promise<{ targets: AliasTarget[]; visitedConfigs: string[] }> {\n const loadedConfigs = new Map<string, TsConfigResult>();\n const visited = new Set<string>();\n const queue: string[] = [entry];\n\n while (queue.length) {\n const tsconfigPath = queue.shift()!;\n if (visited.has(tsconfigPath)) continue;\n visited.add(tsconfigPath);\n\n let res: TsConfigResult;\n\n try {\n const config = parseTsconfig(tsconfigPath);\n if (config) res = { path: tsconfigPath, config };\n else throw new Error('Null returned from getTsConfig');\n } catch (error) {\n logWarn(`Skipping unreadable config: ${formatPath(tsconfigPath)}`);\n if (verbose) console.warn(error);\n continue;\n }\n\n loadedConfigs.set(res.path, res);\n\n const refs = unique(\n (res.config.references ?? []).map((ref) => {\n const absPath = resolve(dirname(res.path), ref.path);\n return resolveTsConfigPath(absPath);\n })\n );\n\n for (const refPath of refs) queue.push(refPath);\n }\n\n const targets = Array.from(loadedConfigs.values())\n .map((res): AliasTarget | undefined => {\n const outDir = res.config.compilerOptions?.outDir;\n if (typeof outDir !== 'string' || outDir.length === 0) {\n if (verbose) logWarn(`Skipping ${formatPath(res.path)} (compilerOptions.outDir is not set)`);\n return undefined;\n }\n\n return { configPath: res.path, outDir: resolveOutDir(res.path, outDir) };\n })\n .filter((target): target is AliasTarget => target !== undefined);\n\n return { targets, visitedConfigs: Array.from(visited) };\n}\n\nexport async function processAliasTarget(target: AliasTarget): Promise<void> {\n if (!existsSync(target.outDir)) {\n logWarn(`Skipping ${formatPath(target.configPath)} (missing outDir ${formatPath(target.outDir)})`);\n return;\n }\n\n try {\n await replaceTscAliasPaths({ configFile: target.configPath, outDir: target.outDir });\n logInfo(`${colorText('green', 'updated')} ${formatPath(target.outDir)} <- ${formatPath(target.configPath)}`);\n } catch (error) {\n logError(`Failed processing ${formatPath(target.configPath)}`);\n console.error(error);\n }\n}\n\nexport function syncWatcherPaths(watcher: FSWatcher, currentPaths: Set<string>, nextPaths: Set<string>): Set<string> {\n const toUnwatch = Array.from(currentPaths).filter((filePath) => !nextPaths.has(filePath));\n if (toUnwatch.length > 0) watcher.unwatch(toUnwatch);\n\n const toWatch = Array.from(nextPaths).filter((filePath) => !currentPaths.has(filePath));\n if (toWatch.length > 0) watcher.add(toWatch);\n\n return new Set(nextPaths);\n}\n\nexport function createRegenerator(\n entry: string,\n verbose: boolean\n): {\n run: (reason?: string) => Promise<void>;\n syncConfigWatcher: (watcher: FSWatcher) => void;\n syncOutputWatcher: (watcher: FSWatcher) => void;\n getTargets: () => AliasTarget[];\n} {\n let isRunning = false;\n let rerunRequested = false;\n let watchedConfigs = new Set<string>();\n let watchedOutputDirs = new Set<string>();\n let syncedConfigPaths = new Set<string>();\n let syncedOutputDirs = new Set<string>();\n let targets: AliasTarget[] = [];\n\n const run = async (reason?: string): Promise<void> => {\n if (isRunning) {\n rerunRequested = true;\n return;\n }\n isRunning = true;\n\n try {\n do {\n rerunRequested = false;\n if (reason) {\n logInfo(`${colorText('cyan', 'regenerate')} (${reason})`);\n reason = undefined;\n }\n\n const result = await discoverAliasTargets(entry, verbose);\n targets = result.targets;\n watchedConfigs = new Set(result.visitedConfigs);\n watchedOutputDirs = new Set(unique(result.targets.map((target) => target.outDir)));\n\n if (targets.length === 0) {\n logWarn('No tsconfig files with compilerOptions.outDir were found');\n } else {\n await Promise.all(targets.map((target) => processAliasTarget(target)));\n }\n } while (rerunRequested);\n } finally {\n isRunning = false;\n }\n };\n\n const syncConfigWatcher = (watcher: FSWatcher): void => {\n syncedConfigPaths = syncWatcherPaths(watcher, syncedConfigPaths, watchedConfigs);\n };\n\n const syncOutputWatcher = (watcher: FSWatcher): void => {\n syncedOutputDirs = syncWatcherPaths(watcher, syncedOutputDirs, watchedOutputDirs);\n };\n\n return { run, syncConfigWatcher, syncOutputWatcher, getTargets: () => targets };\n}\n\n// Main function\nexport async function main(): Promise<void> {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n config: { type: 'string', short: 'c' },\n watch: { type: 'boolean', short: 'w' },\n verbose: { type: 'boolean', short: 'v' }\n }\n });\n\n const entry = values.config ? resolve(values.config) : null;\n if (!entry) {\n logError('Missing required flag: --config <path/to/tsconfig.json>');\n process.exit(1);\n }\n if (!existsSync(entry)) {\n logError(`Config file not found: ${formatPath(entry)}`);\n process.exit(1);\n }\n\n const watchMode = values.watch === true;\n const verbose = values.verbose === true;\n const regenerator = createRegenerator(entry, verbose);\n\n await regenerator.run('initial run');\n\n if (!watchMode) return;\n\n logInfo('watch mode enabled');\n const configWatcher = watch([], {\n persistent: true,\n ignoreInitial: true,\n ignored: ['**/node_modules/**'],\n awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }\n });\n const outputWatcher = watch([], {\n persistent: true,\n ignoreInitial: true,\n ignored: ['**/node_modules/**'],\n awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }\n });\n\n regenerator.syncConfigWatcher(configWatcher);\n regenerator.syncOutputWatcher(outputWatcher);\n\n const pending = new Map<string, ReturnType<typeof setTimeout>>();\n const scheduleTarget = (target: AliasTarget, reason: string): void => {\n const key = `${target.configPath}::${target.outDir}`;\n const existing = pending.get(key);\n if (existing) clearTimeout(existing);\n\n pending.set(\n key,\n setTimeout(() => {\n pending.delete(key);\n void processAliasTarget(target);\n if (verbose) logInfo(`${colorText('cyan', 'reprocess')} (${reason})`);\n }, 200)\n );\n };\n\n const scheduleTargetsForPath = (filePath: string, reason: string): void => {\n const resolvedPath = resolve(filePath);\n\n for (const target of regenerator.getTargets()) {\n if (resolvedPath === target.outDir) {\n scheduleTarget(target, reason);\n continue;\n }\n if (isAliasOutputFile(resolvedPath) && isWithinDir(resolvedPath, target.outDir)) {\n scheduleTarget(target, reason);\n }\n }\n };\n\n configWatcher.on('change', async (filePath) => {\n logInfo(`${colorText('cyan', 'change')} ${formatPath(filePath)}`);\n await regenerator.run(`changed ${relative(process.cwd(), filePath)}`);\n regenerator.syncConfigWatcher(configWatcher);\n regenerator.syncOutputWatcher(outputWatcher);\n });\n\n configWatcher.on('add', async (filePath) => {\n logInfo(`${colorText('cyan', 'add')} ${formatPath(filePath)}`);\n await regenerator.run(`added ${relative(process.cwd(), filePath)}`);\n regenerator.syncConfigWatcher(configWatcher);\n regenerator.syncOutputWatcher(outputWatcher);\n });\n\n configWatcher.on('unlink', async (filePath) => {\n logInfo(`${colorText('yellow', 'remove')} ${formatPath(filePath)}`);\n await regenerator.run(`removed ${relative(process.cwd(), filePath)}`);\n regenerator.syncConfigWatcher(configWatcher);\n regenerator.syncOutputWatcher(outputWatcher);\n });\n\n outputWatcher.on('addDir', (dirPath) => {\n scheduleTargetsForPath(dirPath, `created ${relative(process.cwd(), dirPath)}`);\n });\n\n outputWatcher.on('add', (filePath) => {\n scheduleTargetsForPath(filePath, `added ${relative(process.cwd(), filePath)}`);\n });\n\n outputWatcher.on('change', (filePath) => {\n scheduleTargetsForPath(filePath, `changed ${relative(process.cwd(), filePath)}`);\n });\n}\n\nfunction isDirectExecution(): boolean {\n if (!process.argv[1]) return false;\n return resolve(process.argv[1]) === fileURLToPath(import.meta.url);\n}\n\nif (isDirectExecution()) {\n main().catch((error) => {\n logError('Unhandled error in ts-alias script');\n console.error(error);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|