zshy 0.0.4 → 0.0.6
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.
- package/README.md +187 -66
- package/out/index.cjs +255 -84
- package/out/index.js +253 -82
- package/out/utils.cjs +69 -70
- package/out/utils.d.cts +5 -1
- package/out/utils.d.ts +5 -1
- package/out/utils.js +68 -70
- package/package.json +11 -23
- package/out/plugins/a.cjs +0 -4
- package/out/plugins/a.d.cts +0 -1
- package/out/plugins/a.d.ts +0 -1
- package/out/plugins/a.js +0 -1
- package/out/plugins/b.cjs +0 -4
- package/out/plugins/b.d.cts +0 -1
- package/out/plugins/b.d.ts +0 -1
- package/out/plugins/b.js +0 -1
package/out/utils.cjs
CHANGED
|
@@ -33,12 +33,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.formatForLog = formatForLog;
|
|
36
37
|
exports.getEntryPoints = getEntryPoints;
|
|
37
38
|
exports.readTsconfig = readTsconfig;
|
|
38
39
|
exports.compileProject = compileProject;
|
|
39
|
-
const globby_1 = require("globby");
|
|
40
40
|
const path = __importStar(require("node:path"));
|
|
41
|
+
const globby_1 = require("globby");
|
|
41
42
|
const ts = __importStar(require("typescript"));
|
|
43
|
+
function formatForLog(data) {
|
|
44
|
+
return JSON.stringify(data, null, 2).split("\n").join("\n ");
|
|
45
|
+
}
|
|
42
46
|
// Get entry points using the same logic as esbuild.mts
|
|
43
47
|
async function getEntryPoints(patterns) {
|
|
44
48
|
const results = [];
|
|
@@ -57,22 +61,27 @@ async function getEntryPoints(patterns) {
|
|
|
57
61
|
function readTsconfig(tsconfigPath) {
|
|
58
62
|
// Read and parse tsconfig.json
|
|
59
63
|
const configPath = path.resolve(tsconfigPath);
|
|
64
|
+
const configDir = path.dirname(configPath);
|
|
60
65
|
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
61
66
|
if (configFile.error) {
|
|
62
67
|
console.error("Error reading tsconfig.json:", ts.formatDiagnostic(configFile.error, {
|
|
63
|
-
getCurrentDirectory: () =>
|
|
68
|
+
getCurrentDirectory: () => configDir,
|
|
64
69
|
getCanonicalFileName: (fileName) => fileName,
|
|
65
70
|
getNewLine: () => ts.sys.newLine,
|
|
66
71
|
}));
|
|
67
72
|
process.exit(1);
|
|
68
73
|
}
|
|
69
|
-
// Parse the config
|
|
70
|
-
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config,
|
|
74
|
+
// Parse the config with explicit base path
|
|
75
|
+
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, {
|
|
76
|
+
...ts.sys,
|
|
77
|
+
// Override getCurrentDirectory to use the tsconfig directory
|
|
78
|
+
getCurrentDirectory: () => configDir,
|
|
79
|
+
}, configDir);
|
|
71
80
|
if (parsedConfig.errors.length > 0) {
|
|
72
81
|
console.error("❌ Error parsing tsconfig.json:");
|
|
73
82
|
for (const error of parsedConfig.errors) {
|
|
74
83
|
console.error(ts.formatDiagnostic(error, {
|
|
75
|
-
getCurrentDirectory: () =>
|
|
84
|
+
getCurrentDirectory: () => configDir,
|
|
76
85
|
getCanonicalFileName: (fileName) => fileName,
|
|
77
86
|
getNewLine: () => ts.sys.newLine,
|
|
78
87
|
}));
|
|
@@ -80,54 +89,49 @@ function readTsconfig(tsconfigPath) {
|
|
|
80
89
|
process.exit(1);
|
|
81
90
|
}
|
|
82
91
|
if (!parsedConfig.options) {
|
|
83
|
-
throw new Error("❌ Error reading tsconfig.json
|
|
92
|
+
throw new Error("❌ Error reading tsconfig.json#/compilerOptions");
|
|
84
93
|
}
|
|
85
94
|
return parsedConfig.options;
|
|
86
95
|
}
|
|
87
96
|
async function compileProject(config, entryPoints) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
// `🧱 Building${
|
|
93
|
-
// config.mode === "ts"
|
|
94
|
-
// ? ".js/.d.ts"
|
|
95
|
-
// : config.mode === "mts"
|
|
96
|
-
// ? ".mjs/.d.ts"
|
|
97
|
-
// : ".cjs/.d.ts"
|
|
98
|
-
// }...`,
|
|
99
|
-
// );
|
|
97
|
+
// Deduplicate entry points before compilation
|
|
98
|
+
const uniqueEntryPoints = [...new Set(entryPoints)];
|
|
99
|
+
// Track files that would be written
|
|
100
|
+
const writtenFiles = [];
|
|
100
101
|
// Create compiler host
|
|
101
102
|
const host = ts.createCompilerHost(config.compilerOptions);
|
|
102
103
|
const originalWriteFile = host.writeFile;
|
|
103
104
|
const jsExt = config.mode === "mts" ? ".mjs" : config.mode === "cts" ? ".cjs" : ".js";
|
|
104
|
-
const dtsExt = config.mode === "mts"
|
|
105
|
-
? ".d.mts"
|
|
106
|
-
: config.mode === "cts"
|
|
107
|
-
? ".d.cts"
|
|
108
|
-
: ".d.ts";
|
|
105
|
+
const dtsExt = config.mode === "mts" ? ".d.mts" : config.mode === "cts" ? ".d.cts" : ".d.ts";
|
|
109
106
|
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
|
|
110
107
|
// Transform output file extensions
|
|
111
108
|
let outputFileName = fileName;
|
|
112
109
|
const processedData = data;
|
|
113
|
-
// if (config.jsExtension) {
|
|
114
110
|
if (fileName.endsWith(".js")) {
|
|
115
111
|
outputFileName = fileName.replace(/\.js$/, jsExt);
|
|
116
112
|
}
|
|
117
|
-
// }
|
|
118
|
-
// if (config.dtsExtension) {
|
|
119
113
|
if (fileName.endsWith(".d.ts")) {
|
|
120
114
|
outputFileName = fileName.replace(/\.d\.ts$/, dtsExt);
|
|
121
115
|
}
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
if (originalWriteFile) {
|
|
116
|
+
// Track the file that would be written
|
|
117
|
+
writtenFiles.push(outputFileName);
|
|
118
|
+
if (!config.dryRun && originalWriteFile) {
|
|
125
119
|
originalWriteFile(outputFileName, processedData, writeByteOrderMark, onError, sourceFiles);
|
|
126
120
|
}
|
|
127
121
|
};
|
|
128
|
-
|
|
122
|
+
if (config.verbose) {
|
|
123
|
+
console.log(`🗣️ Resolved entrypoints: ${formatForLog(uniqueEntryPoints)}`);
|
|
124
|
+
console.log(`🗣️ Resolved compilerOptions: ${formatForLog({
|
|
125
|
+
...config.compilerOptions,
|
|
126
|
+
// resolve enum values to strings for better logging
|
|
127
|
+
module: ts.ModuleKind[config.compilerOptions.module],
|
|
128
|
+
moduleResolution: ts.ModuleResolutionKind[config.compilerOptions.moduleResolution],
|
|
129
|
+
target: ts.ScriptTarget[config.compilerOptions.target],
|
|
130
|
+
})}`);
|
|
131
|
+
}
|
|
132
|
+
// Create the TypeScript program using unique entry points
|
|
129
133
|
const program = ts.createProgram({
|
|
130
|
-
rootNames:
|
|
134
|
+
rootNames: uniqueEntryPoints,
|
|
131
135
|
options: config.compilerOptions,
|
|
132
136
|
host,
|
|
133
137
|
});
|
|
@@ -135,9 +139,7 @@ async function compileProject(config, entryPoints) {
|
|
|
135
139
|
const extensionRewriteTransformer = (context) => {
|
|
136
140
|
return (sourceFile) => {
|
|
137
141
|
const visitor = (node) => {
|
|
138
|
-
if (ts.isImportDeclaration(node) &&
|
|
139
|
-
node.moduleSpecifier &&
|
|
140
|
-
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
142
|
+
if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
141
143
|
const originalText = node.moduleSpecifier.text;
|
|
142
144
|
if (originalText.endsWith(".js")) {
|
|
143
145
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
@@ -156,9 +158,7 @@ async function compileProject(config, entryPoints) {
|
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
// Handle export declarations
|
|
159
|
-
if (ts.isExportDeclaration(node) &&
|
|
160
|
-
node.moduleSpecifier &&
|
|
161
|
-
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
161
|
+
if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
162
162
|
const originalText = node.moduleSpecifier.text;
|
|
163
163
|
if (originalText.endsWith(".js")) {
|
|
164
164
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
@@ -174,23 +174,19 @@ async function compileProject(config, entryPoints) {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
// Handle dynamic imports
|
|
177
|
-
if (ts.isCallExpression(node) &&
|
|
178
|
-
node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
177
|
+
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
179
178
|
const arg = node.arguments[0];
|
|
180
179
|
if (ts.isStringLiteral(arg)) {
|
|
181
180
|
const originalText = arg.text;
|
|
182
181
|
if (originalText.endsWith(".js")) {
|
|
183
182
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
184
|
-
// console.log(`Rewriting dynamic import from ${originalText} to
|
|
185
|
-
// ${newText}`);
|
|
186
183
|
return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [
|
|
187
184
|
ts.factory.createStringLiteral(newText),
|
|
188
185
|
...node.arguments.slice(1),
|
|
189
186
|
]);
|
|
190
187
|
}
|
|
191
188
|
// if dynamic import is extensionless, add .js extension
|
|
192
|
-
if (originalText.startsWith("./") ||
|
|
193
|
-
originalText.startsWith("../")) {
|
|
189
|
+
if (originalText.startsWith("./") || originalText.startsWith("../")) {
|
|
194
190
|
const hasExtension = path.extname(originalText) !== "";
|
|
195
191
|
if (!hasExtension) {
|
|
196
192
|
const newText = originalText + jsExt;
|
|
@@ -212,30 +208,25 @@ async function compileProject(config, entryPoints) {
|
|
|
212
208
|
if (diagnostics.length > 0) {
|
|
213
209
|
const errorCount = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error).length;
|
|
214
210
|
const warningCount = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning).length;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (errorCount > 5) {
|
|
230
|
-
console.log(`... and ${errorCount - 5} more errors`);
|
|
231
|
-
}
|
|
211
|
+
if (errorCount > 0 || warningCount > 0) {
|
|
212
|
+
console.log(`⚠️ Found ${errorCount} error(s) and ${warningCount} warning(s)`);
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
// Format diagnostics with color and context like tsc, keeping original order
|
|
216
|
+
const formatHost = {
|
|
217
|
+
getCurrentDirectory: () => process.cwd(),
|
|
218
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
219
|
+
getNewLine: () => ts.sys.newLine,
|
|
220
|
+
};
|
|
221
|
+
// Keep errors and warnings intermixed in their original order
|
|
222
|
+
const relevantDiagnostics = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning);
|
|
223
|
+
if (relevantDiagnostics.length > 0) {
|
|
224
|
+
console.log(ts.formatDiagnosticsWithColorAndContext(relevantDiagnostics, formatHost));
|
|
232
225
|
}
|
|
233
226
|
}
|
|
234
227
|
// emit the files
|
|
235
228
|
const emitResult = program.emit(undefined, undefined, undefined, undefined, {
|
|
236
|
-
before: [
|
|
237
|
-
extensionRewriteTransformer,
|
|
238
|
-
],
|
|
229
|
+
before: [extensionRewriteTransformer],
|
|
239
230
|
afterDeclarations: [extensionRewriteTransformer],
|
|
240
231
|
});
|
|
241
232
|
if (emitResult.emitSkipped) {
|
|
@@ -247,13 +238,21 @@ async function compileProject(config, entryPoints) {
|
|
|
247
238
|
}
|
|
248
239
|
// Report any emit diagnostics
|
|
249
240
|
if (emitResult.diagnostics.length > 0) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
241
|
+
const emitErrors = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error);
|
|
242
|
+
const emitWarnings = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning);
|
|
243
|
+
console.error(`❌ Found ${emitErrors.length} error(s) and ${emitWarnings.length} warning(s) during emit:`);
|
|
244
|
+
console.log();
|
|
245
|
+
const formatHost = {
|
|
246
|
+
getCurrentDirectory: () => process.cwd(),
|
|
247
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
248
|
+
getNewLine: () => ts.sys.newLine,
|
|
249
|
+
};
|
|
250
|
+
// Keep errors and warnings intermixed in their original order
|
|
251
|
+
const relevantEmitDiagnostics = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning);
|
|
252
|
+
if (relevantEmitDiagnostics.length > 0) {
|
|
253
|
+
console.log(ts.formatDiagnosticsWithColorAndContext(relevantEmitDiagnostics, formatHost));
|
|
257
254
|
}
|
|
258
255
|
}
|
|
256
|
+
// Return the list of files that were written or would be written
|
|
257
|
+
return writtenFiles;
|
|
259
258
|
}
|
package/out/utils.d.cts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
|
+
export declare function formatForLog(data: unknown): string;
|
|
2
3
|
export interface ProjectOptions {
|
|
3
4
|
configPath: string;
|
|
4
5
|
compilerOptions: ts.CompilerOptions & Required<Pick<ts.CompilerOptions, "module" | "moduleResolution" | "outDir">>;
|
|
5
6
|
mode: "cts" | "ts" | "mts";
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
packageRoot?: string;
|
|
6
10
|
}
|
|
7
11
|
export declare function getEntryPoints(patterns: string[]): Promise<string[]>;
|
|
8
12
|
export declare function readTsconfig(tsconfigPath: string): ts.CompilerOptions;
|
|
9
|
-
export declare function compileProject(config: ProjectOptions, entryPoints: string[]): Promise<
|
|
13
|
+
export declare function compileProject(config: ProjectOptions, entryPoints: string[]): Promise<string[]>;
|
package/out/utils.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
|
+
export declare function formatForLog(data: unknown): string;
|
|
2
3
|
export interface ProjectOptions {
|
|
3
4
|
configPath: string;
|
|
4
5
|
compilerOptions: ts.CompilerOptions & Required<Pick<ts.CompilerOptions, "module" | "moduleResolution" | "outDir">>;
|
|
5
6
|
mode: "cts" | "ts" | "mts";
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
packageRoot?: string;
|
|
6
10
|
}
|
|
7
11
|
export declare function getEntryPoints(patterns: string[]): Promise<string[]>;
|
|
8
12
|
export declare function readTsconfig(tsconfigPath: string): ts.CompilerOptions;
|
|
9
|
-
export declare function compileProject(config: ProjectOptions, entryPoints: string[]): Promise<
|
|
13
|
+
export declare function compileProject(config: ProjectOptions, entryPoints: string[]): Promise<string[]>;
|
package/out/utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { globby } from "globby";
|
|
2
1
|
import * as path from "node:path";
|
|
2
|
+
import { globby } from "globby";
|
|
3
3
|
import * as ts from "typescript";
|
|
4
|
+
export function formatForLog(data) {
|
|
5
|
+
return JSON.stringify(data, null, 2).split("\n").join("\n ");
|
|
6
|
+
}
|
|
4
7
|
// Get entry points using the same logic as esbuild.mts
|
|
5
8
|
export async function getEntryPoints(patterns) {
|
|
6
9
|
const results = [];
|
|
@@ -19,22 +22,27 @@ export async function getEntryPoints(patterns) {
|
|
|
19
22
|
export function readTsconfig(tsconfigPath) {
|
|
20
23
|
// Read and parse tsconfig.json
|
|
21
24
|
const configPath = path.resolve(tsconfigPath);
|
|
25
|
+
const configDir = path.dirname(configPath);
|
|
22
26
|
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
23
27
|
if (configFile.error) {
|
|
24
28
|
console.error("Error reading tsconfig.json:", ts.formatDiagnostic(configFile.error, {
|
|
25
|
-
getCurrentDirectory: () =>
|
|
29
|
+
getCurrentDirectory: () => configDir,
|
|
26
30
|
getCanonicalFileName: (fileName) => fileName,
|
|
27
31
|
getNewLine: () => ts.sys.newLine,
|
|
28
32
|
}));
|
|
29
33
|
process.exit(1);
|
|
30
34
|
}
|
|
31
|
-
// Parse the config
|
|
32
|
-
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config,
|
|
35
|
+
// Parse the config with explicit base path
|
|
36
|
+
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, {
|
|
37
|
+
...ts.sys,
|
|
38
|
+
// Override getCurrentDirectory to use the tsconfig directory
|
|
39
|
+
getCurrentDirectory: () => configDir,
|
|
40
|
+
}, configDir);
|
|
33
41
|
if (parsedConfig.errors.length > 0) {
|
|
34
42
|
console.error("❌ Error parsing tsconfig.json:");
|
|
35
43
|
for (const error of parsedConfig.errors) {
|
|
36
44
|
console.error(ts.formatDiagnostic(error, {
|
|
37
|
-
getCurrentDirectory: () =>
|
|
45
|
+
getCurrentDirectory: () => configDir,
|
|
38
46
|
getCanonicalFileName: (fileName) => fileName,
|
|
39
47
|
getNewLine: () => ts.sys.newLine,
|
|
40
48
|
}));
|
|
@@ -42,54 +50,49 @@ export function readTsconfig(tsconfigPath) {
|
|
|
42
50
|
process.exit(1);
|
|
43
51
|
}
|
|
44
52
|
if (!parsedConfig.options) {
|
|
45
|
-
throw new Error("❌ Error reading tsconfig.json
|
|
53
|
+
throw new Error("❌ Error reading tsconfig.json#/compilerOptions");
|
|
46
54
|
}
|
|
47
55
|
return parsedConfig.options;
|
|
48
56
|
}
|
|
49
57
|
export async function compileProject(config, entryPoints) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
// `🧱 Building${
|
|
55
|
-
// config.mode === "ts"
|
|
56
|
-
// ? ".js/.d.ts"
|
|
57
|
-
// : config.mode === "mts"
|
|
58
|
-
// ? ".mjs/.d.ts"
|
|
59
|
-
// : ".cjs/.d.ts"
|
|
60
|
-
// }...`,
|
|
61
|
-
// );
|
|
58
|
+
// Deduplicate entry points before compilation
|
|
59
|
+
const uniqueEntryPoints = [...new Set(entryPoints)];
|
|
60
|
+
// Track files that would be written
|
|
61
|
+
const writtenFiles = [];
|
|
62
62
|
// Create compiler host
|
|
63
63
|
const host = ts.createCompilerHost(config.compilerOptions);
|
|
64
64
|
const originalWriteFile = host.writeFile;
|
|
65
65
|
const jsExt = config.mode === "mts" ? ".mjs" : config.mode === "cts" ? ".cjs" : ".js";
|
|
66
|
-
const dtsExt = config.mode === "mts"
|
|
67
|
-
? ".d.mts"
|
|
68
|
-
: config.mode === "cts"
|
|
69
|
-
? ".d.cts"
|
|
70
|
-
: ".d.ts";
|
|
66
|
+
const dtsExt = config.mode === "mts" ? ".d.mts" : config.mode === "cts" ? ".d.cts" : ".d.ts";
|
|
71
67
|
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
|
|
72
68
|
// Transform output file extensions
|
|
73
69
|
let outputFileName = fileName;
|
|
74
70
|
const processedData = data;
|
|
75
|
-
// if (config.jsExtension) {
|
|
76
71
|
if (fileName.endsWith(".js")) {
|
|
77
72
|
outputFileName = fileName.replace(/\.js$/, jsExt);
|
|
78
73
|
}
|
|
79
|
-
// }
|
|
80
|
-
// if (config.dtsExtension) {
|
|
81
74
|
if (fileName.endsWith(".d.ts")) {
|
|
82
75
|
outputFileName = fileName.replace(/\.d\.ts$/, dtsExt);
|
|
83
76
|
}
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
if (originalWriteFile) {
|
|
77
|
+
// Track the file that would be written
|
|
78
|
+
writtenFiles.push(outputFileName);
|
|
79
|
+
if (!config.dryRun && originalWriteFile) {
|
|
87
80
|
originalWriteFile(outputFileName, processedData, writeByteOrderMark, onError, sourceFiles);
|
|
88
81
|
}
|
|
89
82
|
};
|
|
90
|
-
|
|
83
|
+
if (config.verbose) {
|
|
84
|
+
console.log(`🗣️ Resolved entrypoints: ${formatForLog(uniqueEntryPoints)}`);
|
|
85
|
+
console.log(`🗣️ Resolved compilerOptions: ${formatForLog({
|
|
86
|
+
...config.compilerOptions,
|
|
87
|
+
// resolve enum values to strings for better logging
|
|
88
|
+
module: ts.ModuleKind[config.compilerOptions.module],
|
|
89
|
+
moduleResolution: ts.ModuleResolutionKind[config.compilerOptions.moduleResolution],
|
|
90
|
+
target: ts.ScriptTarget[config.compilerOptions.target],
|
|
91
|
+
})}`);
|
|
92
|
+
}
|
|
93
|
+
// Create the TypeScript program using unique entry points
|
|
91
94
|
const program = ts.createProgram({
|
|
92
|
-
rootNames:
|
|
95
|
+
rootNames: uniqueEntryPoints,
|
|
93
96
|
options: config.compilerOptions,
|
|
94
97
|
host,
|
|
95
98
|
});
|
|
@@ -97,9 +100,7 @@ export async function compileProject(config, entryPoints) {
|
|
|
97
100
|
const extensionRewriteTransformer = (context) => {
|
|
98
101
|
return (sourceFile) => {
|
|
99
102
|
const visitor = (node) => {
|
|
100
|
-
if (ts.isImportDeclaration(node) &&
|
|
101
|
-
node.moduleSpecifier &&
|
|
102
|
-
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
103
|
+
if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
103
104
|
const originalText = node.moduleSpecifier.text;
|
|
104
105
|
if (originalText.endsWith(".js")) {
|
|
105
106
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
@@ -118,9 +119,7 @@ export async function compileProject(config, entryPoints) {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
// Handle export declarations
|
|
121
|
-
if (ts.isExportDeclaration(node) &&
|
|
122
|
-
node.moduleSpecifier &&
|
|
123
|
-
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
122
|
+
if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
124
123
|
const originalText = node.moduleSpecifier.text;
|
|
125
124
|
if (originalText.endsWith(".js")) {
|
|
126
125
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
@@ -136,23 +135,19 @@ export async function compileProject(config, entryPoints) {
|
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
// Handle dynamic imports
|
|
139
|
-
if (ts.isCallExpression(node) &&
|
|
140
|
-
node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
138
|
+
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
141
139
|
const arg = node.arguments[0];
|
|
142
140
|
if (ts.isStringLiteral(arg)) {
|
|
143
141
|
const originalText = arg.text;
|
|
144
142
|
if (originalText.endsWith(".js")) {
|
|
145
143
|
const newText = originalText.slice(0, -3) + jsExt;
|
|
146
|
-
// console.log(`Rewriting dynamic import from ${originalText} to
|
|
147
|
-
// ${newText}`);
|
|
148
144
|
return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [
|
|
149
145
|
ts.factory.createStringLiteral(newText),
|
|
150
146
|
...node.arguments.slice(1),
|
|
151
147
|
]);
|
|
152
148
|
}
|
|
153
149
|
// if dynamic import is extensionless, add .js extension
|
|
154
|
-
if (originalText.startsWith("./") ||
|
|
155
|
-
originalText.startsWith("../")) {
|
|
150
|
+
if (originalText.startsWith("./") || originalText.startsWith("../")) {
|
|
156
151
|
const hasExtension = path.extname(originalText) !== "";
|
|
157
152
|
if (!hasExtension) {
|
|
158
153
|
const newText = originalText + jsExt;
|
|
@@ -174,30 +169,25 @@ export async function compileProject(config, entryPoints) {
|
|
|
174
169
|
if (diagnostics.length > 0) {
|
|
175
170
|
const errorCount = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error).length;
|
|
176
171
|
const warningCount = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning).length;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (errorCount > 5) {
|
|
192
|
-
console.log(`... and ${errorCount - 5} more errors`);
|
|
193
|
-
}
|
|
172
|
+
if (errorCount > 0 || warningCount > 0) {
|
|
173
|
+
console.log(`⚠️ Found ${errorCount} error(s) and ${warningCount} warning(s)`);
|
|
174
|
+
console.log();
|
|
175
|
+
}
|
|
176
|
+
// Format diagnostics with color and context like tsc, keeping original order
|
|
177
|
+
const formatHost = {
|
|
178
|
+
getCurrentDirectory: () => process.cwd(),
|
|
179
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
180
|
+
getNewLine: () => ts.sys.newLine,
|
|
181
|
+
};
|
|
182
|
+
// Keep errors and warnings intermixed in their original order
|
|
183
|
+
const relevantDiagnostics = diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning);
|
|
184
|
+
if (relevantDiagnostics.length > 0) {
|
|
185
|
+
console.log(ts.formatDiagnosticsWithColorAndContext(relevantDiagnostics, formatHost));
|
|
194
186
|
}
|
|
195
187
|
}
|
|
196
188
|
// emit the files
|
|
197
189
|
const emitResult = program.emit(undefined, undefined, undefined, undefined, {
|
|
198
|
-
before: [
|
|
199
|
-
extensionRewriteTransformer,
|
|
200
|
-
],
|
|
190
|
+
before: [extensionRewriteTransformer],
|
|
201
191
|
afterDeclarations: [extensionRewriteTransformer],
|
|
202
192
|
});
|
|
203
193
|
if (emitResult.emitSkipped) {
|
|
@@ -209,13 +199,21 @@ export async function compileProject(config, entryPoints) {
|
|
|
209
199
|
}
|
|
210
200
|
// Report any emit diagnostics
|
|
211
201
|
if (emitResult.diagnostics.length > 0) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
202
|
+
const emitErrors = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error);
|
|
203
|
+
const emitWarnings = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Warning);
|
|
204
|
+
console.error(`❌ Found ${emitErrors.length} error(s) and ${emitWarnings.length} warning(s) during emit:`);
|
|
205
|
+
console.log();
|
|
206
|
+
const formatHost = {
|
|
207
|
+
getCurrentDirectory: () => process.cwd(),
|
|
208
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
209
|
+
getNewLine: () => ts.sys.newLine,
|
|
210
|
+
};
|
|
211
|
+
// Keep errors and warnings intermixed in their original order
|
|
212
|
+
const relevantEmitDiagnostics = emitResult.diagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error || d.category === ts.DiagnosticCategory.Warning);
|
|
213
|
+
if (relevantEmitDiagnostics.length > 0) {
|
|
214
|
+
console.log(ts.formatDiagnosticsWithColorAndContext(relevantEmitDiagnostics, formatHost));
|
|
219
215
|
}
|
|
220
216
|
}
|
|
217
|
+
// Return the list of files that were written or would be written
|
|
218
|
+
return writtenFiles;
|
|
221
219
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zshy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Gold-standard build tool for TypeScript libraries",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"typescript",
|
|
@@ -31,10 +32,7 @@
|
|
|
31
32
|
"url": "https://github.com/sponsors/colinhacks"
|
|
32
33
|
},
|
|
33
34
|
"module": "./out/index.js",
|
|
34
|
-
"
|
|
35
|
-
"bin": {
|
|
36
|
-
"zshy": "./out/index.js"
|
|
37
|
-
},
|
|
35
|
+
"bin": "./out/index.cjs",
|
|
38
36
|
"devDependencies": {
|
|
39
37
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
40
38
|
"@biomejs/biome": "^2.0.5",
|
|
@@ -42,7 +40,8 @@
|
|
|
42
40
|
"@types/react": "^19.1.8",
|
|
43
41
|
"react": "^19.1.0",
|
|
44
42
|
"tsx": "^4.20.3",
|
|
45
|
-
"typescript": "
|
|
43
|
+
"typescript": "^5.8.3",
|
|
44
|
+
"vitest": "^2.1.5"
|
|
46
45
|
},
|
|
47
46
|
"peerDependencies": {
|
|
48
47
|
"typescript": ">5.5.0"
|
|
@@ -53,18 +52,18 @@
|
|
|
53
52
|
"table": "^6.9.0"
|
|
54
53
|
},
|
|
55
54
|
"scripts": {
|
|
56
|
-
"build": "tsx src/index.ts"
|
|
55
|
+
"build": "tsx src/index.ts",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"clean": "git clean -qxdf . -e node_modules"
|
|
57
58
|
},
|
|
58
59
|
"zshy": {
|
|
59
60
|
"exports": {
|
|
60
|
-
".": "./src/index.ts"
|
|
61
|
-
"./utils": "./src/utils.ts",
|
|
62
|
-
"./plugins/*": "./src/plugins/*"
|
|
61
|
+
".": "./src/index.ts"
|
|
63
62
|
},
|
|
63
|
+
"bin": "./src/index.ts",
|
|
64
64
|
"sourceDialects": [
|
|
65
65
|
"@zod/source"
|
|
66
|
-
]
|
|
67
|
-
"tsconfig": "./tsconfig.build.json"
|
|
66
|
+
]
|
|
68
67
|
},
|
|
69
68
|
"main": "./out/index.cjs",
|
|
70
69
|
"types": "./out/index.d.cts",
|
|
@@ -74,17 +73,6 @@
|
|
|
74
73
|
"types": "./out/index.d.cts",
|
|
75
74
|
"import": "./out/index.js",
|
|
76
75
|
"require": "./out/index.cjs"
|
|
77
|
-
},
|
|
78
|
-
"./utils": {
|
|
79
|
-
"@zod/source": "./src/utils.ts",
|
|
80
|
-
"types": "./out/utils.d.cts",
|
|
81
|
-
"import": "./out/utils.js",
|
|
82
|
-
"require": "./out/utils.cjs"
|
|
83
|
-
},
|
|
84
|
-
"./plugins/*": {
|
|
85
|
-
"@zod/source": "./src/plugins/*",
|
|
86
|
-
"import": "./out/src/plugins/*",
|
|
87
|
-
"require": "./out/src/plugins/*"
|
|
88
76
|
}
|
|
89
77
|
},
|
|
90
78
|
"files": [
|
package/out/plugins/a.cjs
DELETED
package/out/plugins/a.d.cts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const a = "a";
|
package/out/plugins/a.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const a = "a";
|
package/out/plugins/a.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const a = "a";
|
package/out/plugins/b.cjs
DELETED
package/out/plugins/b.d.cts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const b = "b";
|
package/out/plugins/b.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const b = "b";
|
package/out/plugins/b.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const b = "b";
|