ts-node-pack 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +47 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-node-pack",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Pack a TypeScript package into a Node-compatible npm tarball without modifying the source tree",
5
5
  "keywords": [
6
6
  "cli",
package/src/index.js CHANGED
@@ -83,21 +83,20 @@ export async function tsNodePack(
83
83
  log(`Copied ${packFiles.length} file(s) into staging`);
84
84
 
85
85
  // ── Phase 4: Decide whether to run tsc, generate config if so ────────
86
- // Three conditions trigger declaration emit:
87
- // 1. user passed --tsconfig (explicit opt-in)
88
- // 2. tsconfig.build.json exists (agoric convention for opt-in)
89
- // 3. any source contains .ts/.tsx/.mts (we'd be stripping them
90
- // anyway, and probably want their declarations)
91
- // For pure JS+JSDoc packages with only `tsconfig.json` and no .ts
92
- // sources, this skips tsc entirely matching what `npm pack` would
93
- // have done before ts-node-pack: ship .js files, no .d.ts.
86
+ // Trigger declaration emit only when there's something to derive:
87
+ // 1. user passed --tsconfig (explicit opt-in), OR
88
+ // 2. any source contains .ts/.tsx/.mts (we'd be stripping them
89
+ // anyway, and probably want their declarations).
90
+ // The mere presence of tsconfig.build.json is NOT enough — monorepos
91
+ // commonly keep one per package for a root project-references build
92
+ // (`tsc --build`) without intending each package to be independently
93
+ // emit-able. Pure JS+JSDoc packages with no .ts sources skip tsc and
94
+ // ship whatever .js files are already in the packlist, matching plain
95
+ // `npm pack` semantics.
94
96
  const hasTsSources = packFiles.some(
95
97
  (f) => /\.(ts|tsx|mts)$/.test(f) && !/\.d\.(ts|mts)$/.test(f),
96
98
  );
97
- const isExplicitOptIn =
98
- tsconfigPath !== null &&
99
- (tsconfig !== undefined || basename(tsconfigPath) === "tsconfig.build.json");
100
- const shouldRunTsc = tsconfigPath !== null && (isExplicitOptIn || hasTsSources);
99
+ const shouldRunTsc = tsconfigPath !== null && (tsconfig !== undefined || hasTsSources);
101
100
 
102
101
  if (shouldRunTsc) {
103
102
  log("Phase 4: Generating derived tsconfig...");
@@ -107,8 +106,21 @@ export async function tsNodePack(
107
106
  // location. Pin typeRoots when that directory exists. (TS 6.0
108
107
  // surfaces the missing resolution as TS2688 instead of the silent
109
108
  // "Cannot find module 'node:util'" cascade of earlier versions.)
110
- const atTypesDir = join(packageDir, "node_modules", "@types");
111
- const hasAtTypes = existsSync(atTypesDir);
109
+ // Walk upward to find the nearest ancestor that actually has
110
+ // node_modules/@types. Yarn 4's pnpm linker keeps `@types` only at
111
+ // the workspace root, so the package's own node_modules is empty.
112
+ const findAtTypes = (start ) => {
113
+ let dir = start;
114
+ while (true) {
115
+ const candidate = join(dir, "node_modules", "@types");
116
+ if (existsSync(candidate)) return candidate;
117
+ const parent = dirname(dir);
118
+ if (parent === dir) return null;
119
+ dir = parent;
120
+ }
121
+ };
122
+ const atTypesDir = findAtTypes(packageDir);
123
+ const hasAtTypes = atTypesDir !== null;
112
124
  const emitConfig = {
113
125
  extends: tsconfigPath,
114
126
  compilerOptions: {
@@ -236,14 +248,33 @@ function findLocalBin(startDir, name) {
236
248
  }
237
249
  }
238
250
 
239
- async function runTsc(emitConfigPath, cwd, log) {
251
+ async function findLocalTsc(cwd) {
240
252
  // Prefer a local tsc so users control the compiler version (and to avoid
241
253
  // npx resolving to macOS's /usr/bin/tsc — the TeX/Smalltalk compiler —
242
254
  // when no local install exists). In a monorepo, the package's own
243
255
  // node_modules/.bin may be empty while the workspace root has the
244
256
  // binary, so walk upward the same way npm's `$PATH` composition does.
245
257
  const binName = process.platform === "win32" ? "tsc.cmd" : "tsc";
246
- const localTsc = findLocalBin(cwd, binName);
258
+ const fromBin = findLocalBin(cwd, binName);
259
+ if (fromBin !== null) return fromBin;
260
+ // Yarn 4's pnpm/PnP linkers do not populate node_modules/.bin/. Fall back
261
+ // to `yarn bin tsc`, which resolves through the active linker and prints
262
+ // the absolute path of the tsc binary when the workspace depends on it.
263
+ try {
264
+ const { stdout } = await execFileAsync("yarn", ["bin", "tsc"], {
265
+ cwd,
266
+ maxBuffer: 1024 * 1024,
267
+ });
268
+ const candidate = stdout.trim().split("\n").pop();
269
+ if (candidate && existsSync(candidate)) return candidate;
270
+ } catch {
271
+ // `yarn` not on PATH or not a yarn project — fall through to npx.
272
+ }
273
+ return null;
274
+ }
275
+
276
+ async function runTsc(emitConfigPath, cwd, log) {
277
+ const localTsc = await findLocalTsc(cwd);
247
278
  const useLocal = localTsc !== null;
248
279
  const [cmd, argv] = useLocal
249
280
  ? [localTsc, ["-p", emitConfigPath]]