zshy 0.0.1 → 0.0.2

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/out/index.cjs ADDED
@@ -0,0 +1,491 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const globby_1 = require("globby");
41
+ const table_1 = require("table");
42
+ const fs = __importStar(require("node:fs"));
43
+ const path = __importStar(require("node:path/posix"));
44
+ const ts = __importStar(require("typescript"));
45
+ const arg_1 = __importDefault(require("arg"));
46
+ const utils_ts_1 = require("./utils.js");
47
+ function isSourceFile(filePath) {
48
+ return (filePath.endsWith(".ts") ||
49
+ filePath.endsWith(".mts") ||
50
+ filePath.endsWith(".cts") ||
51
+ filePath.endsWith(".tsx"));
52
+ }
53
+ function removeExtension(filePath) {
54
+ return filePath.split(".").slice(0, -1).join(".") || filePath;
55
+ }
56
+ async function main() {
57
+ console.log("💎 Starting zshy build...");
58
+ ///////////////////////////////////
59
+ /// parse command line args ///
60
+ ///////////////////////////////////
61
+ // Parse command line arguments using arg library
62
+ let args;
63
+ try {
64
+ args = (0, arg_1.default)({
65
+ "--project": String,
66
+ "--help": Boolean,
67
+ // Aliases
68
+ "-p": "--project",
69
+ "-h": "--help",
70
+ });
71
+ }
72
+ catch (error) {
73
+ if (error instanceof Error) {
74
+ console.error(`❌ ${error.message}`);
75
+ }
76
+ console.error(`Use --help for usage information`);
77
+ process.exit(1);
78
+ }
79
+ // Handle help flag
80
+ if (args["--help"]) {
81
+ console.log(`
82
+ Usage: zshy [options]
83
+
84
+ Options:
85
+ -p, --project <path> Path to tsconfig.json file
86
+ -h, --help Show this help message
87
+
88
+ Examples:
89
+ zshy # Use ./tsconfig.json
90
+ zshy -p ./tsconfig.build.json # Use specific tsconfig file
91
+ zshy --project ./tsconfig.prod.json
92
+ `);
93
+ process.exit(0);
94
+ }
95
+ const projectPath = args["--project"];
96
+ if (projectPath) {
97
+ console.log(`⚙️ Using custom project path: ${projectPath}`);
98
+ }
99
+ ///////////////////////////////////
100
+ /// find and read pkg json ///
101
+ ///////////////////////////////////
102
+ // Find package.json by scanning up the file system
103
+ let packageJsonPath = "./package.json";
104
+ let currentDir = process.cwd();
105
+ while (currentDir !== path.dirname(currentDir)) {
106
+ const candidatePath = path.join(currentDir, "package.json");
107
+ if (fs.existsSync(candidatePath)) {
108
+ packageJsonPath = candidatePath;
109
+ break;
110
+ }
111
+ currentDir = path.dirname(currentDir);
112
+ }
113
+ if (!fs.existsSync(packageJsonPath)) {
114
+ console.error("❌ package.json not found in current directory or any parent directories");
115
+ process.exit(1);
116
+ }
117
+ // read package.json and extract the "zshy" exports config
118
+ // console.log("📦 Extracting entry points from package.json exports...");
119
+ const pkgJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
120
+ const pkgJsonDir = path.dirname(packageJsonPath);
121
+ // print project root
122
+ console.log(`⚙️ Detected project root: ${pkgJsonDir}`);
123
+ console.log(`📦 Reading package.json from ./${path.relative(pkgJsonDir, packageJsonPath)}`);
124
+ /////////////////////////////////
125
+ /// parse zshy config ///
126
+ /////////////////////////////////
127
+ // const pkgJson = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
128
+ const CONFIG_KEY = "zshy";
129
+ let config;
130
+ if (!pkgJson[CONFIG_KEY]) {
131
+ console.error(`❌ No "${CONFIG_KEY}" key found in package.json`);
132
+ process.exit(1);
133
+ }
134
+ if (typeof pkgJson[CONFIG_KEY] === "string") {
135
+ config = {
136
+ exports: { ".": pkgJson[CONFIG_KEY] },
137
+ };
138
+ }
139
+ else if (typeof pkgJson[CONFIG_KEY] === "object") {
140
+ config = { ...pkgJson[CONFIG_KEY] };
141
+ if (typeof config.exports === "string") {
142
+ config.exports = { ".": config.exports };
143
+ }
144
+ else if (typeof config.exports === "undefined") {
145
+ console.error(`❌ Missing "exports" key in package.json#${CONFIG_KEY}`);
146
+ process.exit(1);
147
+ }
148
+ else if (typeof config.exports !== "object") {
149
+ console.error(`❌ Invalid "exports" key in package.json#${CONFIG_KEY}`);
150
+ process.exit(1);
151
+ }
152
+ // {
153
+ // exports: { ".": pkgJson[CONFIG_KEY].exports },
154
+ // };
155
+ }
156
+ else if (typeof pkgJson[CONFIG_KEY] === "undefined") {
157
+ console.error(`❌ Missing "${CONFIG_KEY}" key in package.json`);
158
+ process.exit(1);
159
+ }
160
+ else {
161
+ console.error(`❌ Invalid "${CONFIG_KEY}" key in package.json, expected string or object`);
162
+ process.exit(1);
163
+ }
164
+ ///////////////////////////
165
+ /// read tsconfig ///
166
+ ///////////////////////////
167
+ // Determine tsconfig.json path
168
+ let tsconfigPath;
169
+ if (projectPath) {
170
+ // Resolve the provided project path against current working directory
171
+ const resolvedProjectPath = path.resolve(process.cwd(), projectPath);
172
+ if (fs.existsSync(resolvedProjectPath)) {
173
+ if (fs.statSync(resolvedProjectPath).isDirectory()) {
174
+ console.error(`❌ Project path must be a tsconfig.json file, not a directory: ${resolvedProjectPath}`);
175
+ process.exit(1);
176
+ }
177
+ else {
178
+ // Use the file directly
179
+ tsconfigPath = resolvedProjectPath;
180
+ }
181
+ }
182
+ else {
183
+ console.error(`❌ Project file not found: ${resolvedProjectPath}`);
184
+ process.exit(1);
185
+ }
186
+ }
187
+ else {
188
+ // Default to tsconfig.json in the package.json directory
189
+ tsconfigPath = path.join(pkgJsonDir, "tsconfig.json");
190
+ }
191
+ const _parsedConfig = (0, utils_ts_1.readTsconfig)(tsconfigPath);
192
+ if (!fs.existsSync(tsconfigPath)) {
193
+ // Check if tsconfig.json exists
194
+ console.error(`❌ tsconfig.json not found at ${path.resolve(tsconfigPath)}`);
195
+ process.exit(1);
196
+ }
197
+ console.log(`📁 Reading tsconfig from ./${path.relative(pkgJsonDir, tsconfigPath)}`);
198
+ // if (_parsedConfig.rootDir) {
199
+ // console.error(
200
+ // `❌ rootDir is determined from your set of entrypoints; you can remove it from your tsconfig.json.`,
201
+ // );
202
+ // process.exit(1);
203
+ // }
204
+ // if (_parsedConfig.declarationDir) {
205
+ // console.error(
206
+ // `❌ declarationDir is not supported in zshy; you should remove it from your tsconfig.json.`,
207
+ // );
208
+ // process.exit(1);
209
+ // }
210
+ // set/override compiler options
211
+ delete _parsedConfig.customConditions; // can't be set for CommonJS builds
212
+ const outDir = path.resolve(pkgJsonDir, _parsedConfig?.outDir || "./dist");
213
+ const relOutDir = path.relative(pkgJsonDir, outDir);
214
+ const declarationDir = path.resolve(pkgJsonDir, _parsedConfig?.declarationDir || relOutDir);
215
+ const relDeclarationDir = path.relative(pkgJsonDir, declarationDir);
216
+ const tsconfigJson = {
217
+ ..._parsedConfig,
218
+ outDir,
219
+ target: _parsedConfig.target ?? ts.ScriptTarget.ES2020, // ensure compatible target for CommonJS
220
+ skipLibCheck: true, // skip library checks to reduce errors
221
+ declaration: true,
222
+ noEmit: false,
223
+ emitDeclarationOnly: false,
224
+ rewriteRelativeImportExtensions: true,
225
+ verbatimModuleSyntax: false,
226
+ };
227
+ if (relOutDir === "") {
228
+ if (!pkgJson.files) {
229
+ console.log('⚠️ You\'re building your code to the project root. This means your compiled files will be generated alongside your source files.\n ➜ Setting "files" in package.json to exclude TypeScript source from the published package.');
230
+ pkgJson.files = [
231
+ "**/*.js",
232
+ "**/*.mjs",
233
+ "**/*.cjs",
234
+ "**/*.d.ts",
235
+ "**/*.d.mts",
236
+ "**/*.d.cts",
237
+ ];
238
+ }
239
+ else {
240
+ console.warn(`⚠️ You're building your code to the project root. This means your compiled files will be generated alongside your source files.\n ➜ Ensure that your "files" in package.json excludes TypeScript source files, or your users may experience .d.ts resolution issues in some environments.
241
+
242
+ \`\`\`
243
+ "files": ["**/*.js", "**/*.mjs", "**/*.cjs", "**/*.d.ts", "**/*.d.mts", "**/*.d.cts"],
244
+ \`\`\`
245
+ `);
246
+ }
247
+ }
248
+ else {
249
+ if (!pkgJson.files) {
250
+ console.log(`⚠️ The "files" key is missing in package.json. Setting to "${relOutDir}".`);
251
+ pkgJson.files = [relOutDir];
252
+ if (relOutDir !== relDeclarationDir) {
253
+ pkgJson.files.push(relDeclarationDir);
254
+ }
255
+ }
256
+ }
257
+ /////////////////////////////////
258
+ /// extract entry points ///
259
+ /////////////////////////////////
260
+ // Extract entry points from zshy exports config
261
+ console.log("➡️ Determining entrypoints...");
262
+ const entryPatterns = [];
263
+ const rows = [["Subpath", "Entrypoint"]];
264
+ for (const [exportPath, sourcePath] of Object.entries(config.exports)) {
265
+ if (exportPath.includes("package.json"))
266
+ continue;
267
+ let cleanExportPath;
268
+ if (exportPath === ".") {
269
+ cleanExportPath = pkgJson.name;
270
+ }
271
+ else if (exportPath.startsWith("./")) {
272
+ cleanExportPath = pkgJson.name + "/" + exportPath.slice(2);
273
+ }
274
+ else {
275
+ console.error(`⚠️ Invalid subpath export "${exportPath}" — should start with "./"`);
276
+ process.exit(1);
277
+ }
278
+ if (typeof sourcePath === "string") {
279
+ if (sourcePath.includes("*")) {
280
+ if (!sourcePath.endsWith("/*")) {
281
+ console.error(`❌ Wildcard paths should not contain file extensions: ${sourcePath}`);
282
+ process.exit(1);
283
+ }
284
+ const pattern = sourcePath.slice(0, -2) + "/*.{ts,tsx,mts,cts}";
285
+ const wildcardFiles = await (0, globby_1.globby)([pattern], {
286
+ ignore: ["**/*.d.ts"],
287
+ cwd: pkgJsonDir,
288
+ deep: 1,
289
+ });
290
+ entryPatterns.push(...wildcardFiles);
291
+ rows.push([
292
+ `"${cleanExportPath}"`,
293
+ `${sourcePath} (${wildcardFiles.length} matches)`,
294
+ ]);
295
+ }
296
+ else if (isSourceFile(sourcePath)) {
297
+ entryPatterns.push(sourcePath);
298
+ rows.push([`"${cleanExportPath}"`, sourcePath]);
299
+ }
300
+ }
301
+ }
302
+ console.log(" " + (0, table_1.table)(rows).split("\n").join("\n ").trim());
303
+ ///////////////////////////////
304
+ /// compute entry points ///
305
+ ///////////////////////////////
306
+ // compute entry points
307
+ const entryPoints = await (0, utils_ts_1.getEntryPoints)(entryPatterns);
308
+ // disallow .mts and .cts files
309
+ if (entryPoints.some((ep) => ep.endsWith(".mts") || ep.endsWith(".cts"))) {
310
+ console.error("❌ Source files with .mts or .cts extensions are not supported. Please use regular .ts files.");
311
+ process.exit(1);
312
+ }
313
+ if (entryPoints.length === 0) {
314
+ console.error("❌ No entry points found matching the specified patterns in package.json#zshy exports");
315
+ process.exit(1);
316
+ }
317
+ ///////////////////////////////
318
+ /// compute root dir ///
319
+ ///////////////////////////////
320
+ // Compute common ancestor directory for all entry points
321
+ let rootDir;
322
+ if (tsconfigJson.rootDir) {
323
+ rootDir = path.resolve(tsconfigPath, tsconfigJson.rootDir);
324
+ }
325
+ else {
326
+ // compute rootDir from entrypoints
327
+ rootDir =
328
+ entryPoints.length > 0
329
+ ? entryPoints.reduce((common, entryPoint) => {
330
+ const entryDir = path.dirname(path.resolve(entryPoint));
331
+ const commonDir = path.resolve(common);
332
+ // Find the longest common path
333
+ const entryParts = entryDir.split(path.sep);
334
+ const commonParts = commonDir.split(path.sep);
335
+ let i = 0;
336
+ while (i < entryParts.length &&
337
+ i < commonParts.length &&
338
+ entryParts[i] === commonParts[i]) {
339
+ i++;
340
+ }
341
+ return commonParts.slice(0, i).join(path.sep) || path.sep;
342
+ }, path.dirname(path.resolve(entryPoints[0])))
343
+ : process.cwd();
344
+ }
345
+ // console.dir(_commonAncestor, { depth: null });
346
+ const relRootDir = path.relative(pkgJsonDir, rootDir);
347
+ console.log(`📂 Transpiling ${relRootDir ? `./${relRootDir}` : "."} (rootDir) to ${relOutDir ? `./${relOutDir}` : "."} (outDir)`);
348
+ if (relDeclarationDir !== relOutDir) {
349
+ console.log(`📂 Writing declaration files to ${relDeclarationDir ? `./${relDeclarationDir}` : "."} (declarationDir)`);
350
+ }
351
+ const isTypeModule = pkgJson.type === "module";
352
+ if (isTypeModule) {
353
+ console.log(`🟨 Package is an ES module (package.json#type is \"module\")`);
354
+ }
355
+ else {
356
+ console.log(`🐢 Package is a CommonJS module (${pkgJson.type === "commonjs" ? 'package.json#type is "commonjs"' : 'package.json#type not set to "module"'})`);
357
+ }
358
+ ///////////////////////////////
359
+ /// compile tsc ///
360
+ ///////////////////////////////
361
+ try {
362
+ // CJS
363
+ console.log(`🧱 Building CJS...${isTypeModule ? ` (rewriting .ts -> .cjs/.d.cts)` : ``}`);
364
+ await (0, utils_ts_1.compileProject)({
365
+ configPath: tsconfigPath,
366
+ mode: isTypeModule ? "cts" : "ts",
367
+ compilerOptions: {
368
+ ...tsconfigJson,
369
+ module: ts.ModuleKind.CommonJS,
370
+ moduleResolution: ts.ModuleResolutionKind.Node10,
371
+ outDir,
372
+ },
373
+ }, entryPoints);
374
+ // ESM
375
+ console.log(`🧱 Building ESM...${isTypeModule ? `` : ` (rewriting .ts -> .mjs/.d.mts)`}`);
376
+ await (0, utils_ts_1.compileProject)({
377
+ configPath: tsconfigPath,
378
+ mode: isTypeModule ? "ts" : "mts",
379
+ compilerOptions: {
380
+ ...tsconfigJson,
381
+ module: ts.ModuleKind.ESNext,
382
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
383
+ outDir,
384
+ },
385
+ }, entryPoints);
386
+ ///////////////////////////////
387
+ /// generate exports ///
388
+ ///////////////////////////////
389
+ // generate package.json exports
390
+ console.log("📦 Updating package.json exports...");
391
+ // Generate exports based on zshy config
392
+ const newExports = {};
393
+ const sourceDialects = config.sourceDialects || [];
394
+ for (const [exportPath, sourcePath] of Object.entries(config.exports)) {
395
+ if (exportPath.includes("package.json")) {
396
+ newExports[exportPath] = sourcePath;
397
+ continue;
398
+ }
399
+ if (typeof sourcePath === "string") {
400
+ if (sourcePath.endsWith("/*")) {
401
+ // Handle wildcard exports
402
+ const relSourcePath = "./" +
403
+ path.relative(pkgJsonDir, path.resolve(outDir, sourcePath.slice(0, -2))) +
404
+ "/*";
405
+ newExports[exportPath] = {
406
+ import: relSourcePath,
407
+ require: relSourcePath,
408
+ };
409
+ for (const sd of sourceDialects) {
410
+ newExports[exportPath] = {
411
+ [sd]: sourcePath,
412
+ ...newExports[exportPath],
413
+ };
414
+ }
415
+ }
416
+ else if (isSourceFile(sourcePath)) {
417
+ // Handle regular TypeScript entry points
418
+ // const basePath = sourcePath.slice(0, -3); // ./v4/index.ts
419
+ const absSourcePath = path.resolve(pkgJsonDir, sourcePath); // /path/to/v4/index.ts
420
+ const sourcePathRelativeToRootDir = path.relative(rootDir, absSourcePath); // index.ts
421
+ const outPath = path.resolve(pkgJsonDir, outDir, sourcePathRelativeToRootDir); // /path/to/dist/index.ts
422
+ const outPathNoExt = removeExtension(outPath); // /path/to/dist/index
423
+ // For declaration files, use declarationDir if it's different from outDir
424
+ const declarationPath = path.resolve(pkgJsonDir, declarationDir, sourcePathRelativeToRootDir); // /path/to/types/index.ts
425
+ const declarationPathNoExt = removeExtension(declarationPath); // /path/to/types/index
426
+ const esmFile = isTypeModule
427
+ ? `${outPathNoExt}.js`
428
+ : `${outPathNoExt}.mjs`; // ./v4/index.js or ./v4/index.mjs
429
+ const cjsFile = isTypeModule
430
+ ? `${outPathNoExt}.cjs`
431
+ : `${outPathNoExt}.js`;
432
+ const dtsFile = isTypeModule
433
+ ? `${declarationPathNoExt}.d.cts`
434
+ : `${declarationPathNoExt}.d.ts`;
435
+ const relEsmFile = "./" + path.relative(pkgJsonDir, esmFile);
436
+ const relCjsFile = "./" + path.relative(pkgJsonDir, cjsFile);
437
+ const relDtsFile = "./" + path.relative(pkgJsonDir, dtsFile);
438
+ newExports[exportPath] = {
439
+ types: relDtsFile,
440
+ import: relEsmFile,
441
+ require: relCjsFile,
442
+ // import: {
443
+ // types: relDtsFile,
444
+ // default: relEsmFile,
445
+ // },
446
+ // require: {
447
+ // types: relDtsFile,
448
+ // default: relCjsFile,
449
+ // },
450
+ };
451
+ if (exportPath === ".") {
452
+ pkgJson.main = relCjsFile;
453
+ pkgJson.module = relEsmFile;
454
+ pkgJson.types = relDtsFile;
455
+ }
456
+ for (const sd of sourceDialects) {
457
+ newExports[exportPath] = {
458
+ [sd]: sourcePath,
459
+ ...newExports[exportPath],
460
+ };
461
+ }
462
+ }
463
+ }
464
+ }
465
+ ///////////////////////////////
466
+ /// write pkg json ///
467
+ ///////////////////////////////
468
+ // Update package.json with new exports
469
+ pkgJson.exports = newExports;
470
+ fs.writeFileSync(packageJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
471
+ // console.log("✅ Updating package.json#exports");
472
+ console.log(" " + JSON.stringify(newExports, null, 2).split("\n").join("\n "));
473
+ // // run `@arethetypeswrong/cli --pack .` to check types
474
+ // console.log("🔍 Checking types with @arethetypeswrong/cli...");
475
+ // const { execSync } = await import("node:child_process");
476
+ // execSync(`npx @arethetypeswrong/cli --pack ${pkgJsonDir}`, {
477
+ // stdio: "inherit",
478
+ // cwd: pkgJsonDir,
479
+ // });
480
+ console.log("🎉 Build complete!");
481
+ }
482
+ catch (error) {
483
+ console.error("❌ Build failed:", error);
484
+ process.exit(1);
485
+ }
486
+ }
487
+ // Run the script
488
+ main().catch((error) => {
489
+ console.error("❌ Script failed:", error);
490
+ process.exit(1);
491
+ });
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/out/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};