dtsroll 1.1.0 → 1.3.0

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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  _dtsroll_ is a CLI tool for bundling TypeScript declaration (`.d.ts`) files.
4
4
 
5
+ <p align="center">
6
+ <img width="600" src="./.github/screenshot.webp">
7
+ </p>
8
+
5
9
  ### Why bundle `.d.ts` files?
6
10
 
7
11
  - **Smaller distribution**
@@ -101,11 +105,28 @@ Provide resolution conditions to target specific entry points in dependencies, s
101
105
  ```ts
102
106
  import { dtsroll } from 'dtsroll'
103
107
 
104
- await dtsroll({
105
- // inputs?: string[];
106
- // external?: string[];
107
- // conditions?: string[];
108
- // dryRun?: boolean;
108
+ await dtsroll(options as {
109
+
110
+ /**
111
+ * CWD to find the package.json in
112
+ * @default process.cwd()
113
+ */
114
+ cwd?: string
115
+
116
+ /**
117
+ * Defaults to auto-detecting d.ts files from package.json
118
+ */
119
+ inputs?: string[]
120
+
121
+ /**
122
+ * Only used if there's no package.json
123
+ * Defaults to auto-detecting dependencies from package.json
124
+ */
125
+ external?: string[]
126
+
127
+ conditions?: string[]
128
+
129
+ dryRun?: boolean
109
130
  })
110
131
  ```
111
132
 
package/dist/cli.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { cli } from 'cleye';
3
- import { b as bgYellow, a as black, d as dtsroll } from './index-D3bowY1b.mjs';
4
- import { l as logOutput } from './log-output-D6QoPA8O.mjs';
3
+ import { b as bgYellow, a as black, d as dtsroll, l as logOutput } from './index-0B0-hvfH.mjs';
5
4
  import 'node:path';
6
5
  import 'node:fs/promises';
7
6
  import 'rollup';
@@ -10,7 +9,7 @@ import '@rollup/plugin-node-resolve';
10
9
  import 'byte-size';
11
10
 
12
11
  var name = "dtsroll";
13
- var version = "1.1.0";
12
+ var version = "1.3.0";
14
13
  var description = "Bundle dts files";
15
14
 
16
15
  const argv = cli({
@@ -3,6 +3,7 @@ import fs from 'node:fs/promises';
3
3
  import { rollup } from 'rollup';
4
4
  import { dts } from 'rollup-plugin-dts';
5
5
  import nodeResolve from '@rollup/plugin-node-resolve';
6
+ import byteSize from 'byte-size';
6
7
 
7
8
  let enabled = true;
8
9
  // Support both browser and node environments
@@ -90,8 +91,116 @@ const magenta = kolorist(35, 39);
90
91
  const lightYellow = kolorist(93, 39);
91
92
  const bgYellow = kolorist(43, 49);
92
93
 
93
- const dtsExtension = ".d.ts";
94
+ const cwd = process.cwd();
95
+
96
+ const isPath = (filePath) => filePath[0] === "." || path.isAbsolute(filePath);
97
+ const normalizePath = (filepath) => filepath.replaceAll("\\", "/");
98
+
94
99
  const warningSignUnicode = "\u26A0";
100
+ const warningPrefix = yellow("Warning:");
101
+ const logOutput = (dtsOutput) => {
102
+ console.log(underline("dtsroll"));
103
+ const { inputs } = dtsOutput;
104
+ const isCliInput = inputs[0]?.[1] === void 0;
105
+ console.log(bold(`
106
+ \u{1F4E5} Entry points${isCliInput ? "" : " in package.json"}`));
107
+ console.log(
108
+ inputs.map(([inputFile, inputSource, error]) => {
109
+ const relativeInputFile = path.relative(cwd, inputFile);
110
+ const logPath2 = normalizePath(
111
+ relativeInputFile.length < inputFile.length ? relativeInputFile : inputFile
112
+ );
113
+ if (error) {
114
+ return ` ${lightYellow(`${warningSignUnicode} ${logPath2} ${dim(error)}`)}`;
115
+ }
116
+ return ` \u2192 ${green(logPath2)}${inputSource ? ` ${dim(`from ${inputSource}`)}` : ""}`;
117
+ }).join("\n")
118
+ );
119
+ if ("error" in dtsOutput) {
120
+ console.error(`${red("Error:")} ${dtsOutput.error}`);
121
+ return;
122
+ }
123
+ const {
124
+ outputDirectory,
125
+ output: {
126
+ entries: outputEntries,
127
+ chunks: outputChunks
128
+ },
129
+ size,
130
+ externals
131
+ } = dtsOutput;
132
+ const outputDirectoryRelative = path.relative(cwd, outputDirectory);
133
+ const logPath = `${normalizePath(
134
+ outputDirectoryRelative.length < outputDirectory.length ? outputDirectoryRelative : outputDirectory
135
+ )}/`;
136
+ const logChunk = ({
137
+ file,
138
+ indent,
139
+ bullet,
140
+ color
141
+ }) => {
142
+ const sizeFormatted = byteSize(file.size).toString();
143
+ let log = `${indent}${bullet} ${dim(color(logPath))}${color(file.fileName)} ${sizeFormatted}`;
144
+ const { moduleIds, moduleToPackage } = file;
145
+ log += `
146
+ ${moduleIds.sort().map((moduleId, index) => {
147
+ const isLast = index === moduleIds.length - 1;
148
+ const prefix = `${indent} ${isLast ? "\u2514\u2500 " : "\u251C\u2500 "}`;
149
+ const relativeModuleId = path.relative(cwd, moduleId);
150
+ const logModuleId = normalizePath(
151
+ relativeModuleId.length < moduleId.length ? relativeModuleId : moduleId
152
+ );
153
+ const bareSpecifier = moduleToPackage[moduleId];
154
+ if (bareSpecifier) {
155
+ return `${prefix}${dim(`${magenta(bareSpecifier)} (${logModuleId})`)}`;
156
+ }
157
+ return `${prefix}${dim(logModuleId)}`;
158
+ }).join("\n")}`;
159
+ return log;
160
+ };
161
+ console.log(bold("\n\u{1F4A0} Bundled output"));
162
+ console.log(
163
+ outputEntries.map((file) => logChunk({
164
+ file,
165
+ indent: " ",
166
+ bullet: "\u25CF",
167
+ color: green
168
+ })).join("\n\n")
169
+ );
170
+ if (outputChunks.length > 0) {
171
+ console.log(bold("\n Chunks"));
172
+ console.log(
173
+ outputChunks.map((file) => logChunk({
174
+ file,
175
+ indent: " ",
176
+ bullet: "\u25A0",
177
+ color: yellow
178
+ })).join("\n\n")
179
+ );
180
+ }
181
+ console.log(bold("\n\u2696\uFE0F Size savings"));
182
+ const difference = size.input - size.output;
183
+ const direction = difference > 0 ? "decrease" : "increase";
184
+ const percentage = (Math.abs(difference / size.input) * 100).toFixed(0);
185
+ console.log(` Input source size: ${byteSize(size.input).toString()}`);
186
+ console.log(` Bundled output size: ${byteSize(size.output).toString()}${difference === 0 ? "" : ` (${percentage}% ${direction})`}`);
187
+ if (externals.length > 0) {
188
+ console.log(bold("\n\u{1F4E6} External packages"));
189
+ console.log(
190
+ externals.map(([packageName, reason, devTypePackage]) => {
191
+ let stdout = ` \u2500 ${magenta(packageName)} ${dim(`externalized ${reason}`)}`;
192
+ if (devTypePackage) {
193
+ stdout += `
194
+ ${warningPrefix} ${magenta(devTypePackage)} should not be in devDependencies if ${magenta(packageName)} is externalized`;
195
+ }
196
+ return stdout;
197
+ }).sort().join("\n")
198
+ );
199
+ }
200
+ };
201
+
202
+ const dtsExtensions = [".d.ts", ".d.cts", ".d.mts"];
203
+ const isDts = (fileName) => dtsExtensions.some((extension) => fileName.endsWith(extension));
95
204
 
96
205
  const isValidIdentifier = /^[$_\p{ID_Start}][$\u200C\u200D\p{ID_Continue}]*$/u;
97
206
  const reservedWords = /* @__PURE__ */ new Set([
@@ -189,7 +298,7 @@ const readPackageJson = async (filePath) => {
189
298
  const getDtsEntryPoints = (packageJson, packageJsonDirectory) => {
190
299
  const entryPoints = {};
191
300
  const addEntry = (subpath, from) => {
192
- if (!subpath.endsWith(dtsExtension)) {
301
+ if (!isDts(subpath)) {
193
302
  return;
194
303
  }
195
304
  const entryPath = path.join(packageJsonDirectory, subpath);
@@ -238,8 +347,8 @@ const getExternals = (packageJson) => {
238
347
  }
239
348
  return external;
240
349
  };
241
- const getPackageJson = async () => {
242
- const packageJsonPath = path.resolve("package.json");
350
+ const getPackageJson = async (cwd) => {
351
+ const packageJsonPath = path.resolve(cwd, "package.json");
243
352
  const exists = await pathExists(packageJsonPath);
244
353
  if (!exists) {
245
354
  return;
@@ -282,8 +391,7 @@ const validateInput = async (inputFiles) => {
282
391
  const inputNormalized = isCliInput ? inputFiles.map((i) => [i]) : Object.entries(inputFiles);
283
392
  return await Promise.all(inputNormalized.map(
284
393
  async ([inputFile, inputSource]) => {
285
- const notDts = !inputFile.endsWith(dtsExtension);
286
- if (notDts) {
394
+ if (!isDts(inputFile)) {
287
395
  return [inputFile, inputSource, "Ignoring non-d.ts input"];
288
396
  }
289
397
  const exists = await pathExists(inputFile);
@@ -295,8 +403,6 @@ const validateInput = async (inputFiles) => {
295
403
  ));
296
404
  };
297
405
 
298
- const isPath = ([firstCharacter]) => firstCharacter === "." || firstCharacter === path.sep;
299
-
300
406
  const createExternalizePlugin = (configuredExternals) => {
301
407
  const resolvedBareSpecifiers = /* @__PURE__ */ new Map();
302
408
  const importPath = /* @__PURE__ */ new Map();
@@ -330,11 +436,11 @@ const createExternalizePlugin = (configuredExternals) => {
330
436
  }
331
437
  if (packageName) {
332
438
  externalized.set(packageName, "because unresolvable");
439
+ return {
440
+ id,
441
+ external: true
442
+ };
333
443
  }
334
- return {
335
- id,
336
- external: true
337
- };
338
444
  }
339
445
  };
340
446
  const getPackageEntryPoint = (subpackagePath) => {
@@ -371,17 +477,15 @@ const removeBundledModulesPlugin = (outputDirectory, sizeRef) => {
371
477
  },
372
478
  async generateBundle(options, bundle) {
373
479
  const modules = Object.values(bundle);
374
- const bundledSourceFiles = Array.from(new Set(
375
- modules.flatMap(({ moduleIds }) => moduleIds).filter((moduleId) => (
376
- // To avoid deleting files from symlinked dependencies
377
- moduleId.startsWith(outputDirectory) && !moduleId.includes(nodeModules)
378
- ))
379
- ));
380
- const fileSizes = bundledSourceFiles.map((moduleId) => this.getModuleInfo(moduleId).meta);
480
+ const bundledFiles = Array.from(new Set(modules.flatMap(({ moduleIds }) => moduleIds)));
481
+ const fileSizes = bundledFiles.map((moduleId) => this.getModuleInfo(moduleId).meta);
381
482
  const totalSize = fileSizes.reduce((total, { size }) => total + size, 0);
382
483
  sizeRef.value = totalSize;
383
484
  const outputFiles = new Set(modules.map(({ fileName }) => path.join(options.dir, fileName)));
384
- deleteFiles = bundledSourceFiles.filter((moduleId) => !outputFiles.has(moduleId));
485
+ deleteFiles = bundledFiles.filter((moduleId) => (
486
+ // To avoid deleting files from symlinked dependencies
487
+ moduleId.startsWith(outputDirectory) && !moduleId.includes(nodeModules) && !outputFiles.has(moduleId)
488
+ ));
385
489
  },
386
490
  writeBundle: async () => {
387
491
  await Promise.all(
@@ -393,7 +497,7 @@ const removeBundledModulesPlugin = (outputDirectory, sizeRef) => {
393
497
 
394
498
  const createInputMap = (input, outputDirectory) => Object.fromEntries(
395
499
  input.map((inputFile) => [
396
- inputFile.slice(outputDirectory.length + 1).slice(0, -dtsExtension.length),
500
+ inputFile.slice(outputDirectory.length + 1),
397
501
  inputFile
398
502
  ])
399
503
  );
@@ -409,13 +513,14 @@ const build = async (input, outputDirectory, externals, mode, conditions) => {
409
513
  output: {
410
514
  // sourcemap: true,
411
515
  dir: outputDirectory,
516
+ entryFileNames: "[name]",
412
517
  chunkFileNames: "_dtsroll-chunks/[name].ts"
413
518
  },
414
519
  plugins: [
415
520
  externalizePlugin,
416
521
  removeBundledModulesPlugin(outputDirectory, sizeRef),
417
522
  nodeResolve({
418
- extensions: [".ts", dtsExtension],
523
+ extensions: [".ts", ...dtsExtensions],
419
524
  exportConditions: conditions
420
525
  }),
421
526
  dts({
@@ -442,16 +547,17 @@ const build = async (input, outputDirectory, externals, mode, conditions) => {
442
547
  };
443
548
 
444
549
  const dtsroll = async ({
550
+ cwd = process.cwd(),
445
551
  inputs,
446
552
  external,
447
553
  conditions,
448
554
  dryRun
449
555
  } = {}) => {
450
- const pkgJson = await getPackageJson();
556
+ const pkgJson = await getPackageJson(cwd);
451
557
  const externals = pkgJson ? pkgJson.getExternals() : /* @__PURE__ */ new Map();
452
558
  if (external && external.length > 0) {
453
559
  if (pkgJson) {
454
- console.warn(`${yellow("Warning:")} The --external flag is only supported when there is no package.json`);
560
+ console.warn(`${warningPrefix} The --external flag is only supported when there is no package.json`);
455
561
  } else {
456
562
  for (const externalDependency of external) {
457
563
  externals.set(externalDependency, "by --external flag");
@@ -531,4 +637,4 @@ const dtsroll = async ({
531
637
  };
532
638
  };
533
639
 
534
- export { black as a, bgYellow as b, bold as c, dtsroll as d, dim as e, green as g, lightYellow as l, magenta as m, red as r, underline as u, warningSignUnicode as w, yellow as y };
640
+ export { black as a, bgYellow as b, dtsroll as d, logOutput as l };
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ type Externals = [
11
11
  ][];
12
12
  type ValidatedInput = [
13
13
  inputPath: string,
14
- inputSource: string,
14
+ inputSource: string | undefined,
15
15
  error?: string
16
16
  ];
17
17
  type DtsrollOutput = {
@@ -32,11 +32,12 @@ type DtsrollOutput = {
32
32
  };
33
33
 
34
34
  type Options = {
35
+ cwd?: string;
35
36
  inputs?: string[];
36
37
  external?: string[];
37
38
  conditions?: string[];
38
39
  dryRun?: boolean;
39
40
  };
40
- declare const dtsroll: ({ inputs, external, conditions, dryRun, }?: Options) => Promise<DtsrollOutput>;
41
+ declare const dtsroll: ({ cwd, inputs, external, conditions, dryRun, }?: Options) => Promise<DtsrollOutput>;
41
42
 
42
43
  export { type DtsrollOutput, type Options, dtsroll };
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import 'node:path';
2
- export { d as dtsroll } from './index-D3bowY1b.mjs';
2
+ export { d as dtsroll } from './index-0B0-hvfH.mjs';
3
3
  import 'node:fs/promises';
4
4
  import 'rollup';
5
5
  import 'rollup-plugin-dts';
6
6
  import '@rollup/plugin-node-resolve';
7
+ import 'byte-size';
package/dist/vite.mjs CHANGED
@@ -1,18 +1,23 @@
1
- import { l as logOutput } from './log-output-D6QoPA8O.mjs';
2
- import { d as dtsroll } from './index-D3bowY1b.mjs';
1
+ import { d as dtsroll, l as logOutput } from './index-0B0-hvfH.mjs';
3
2
  import 'node:path';
4
- import 'byte-size';
5
3
  import 'node:fs/promises';
6
4
  import 'rollup';
7
5
  import 'rollup-plugin-dts';
8
6
  import '@rollup/plugin-node-resolve';
7
+ import 'byte-size';
9
8
 
10
9
  const dtsrollPlugin = (options) => {
11
10
  let built = false;
11
+ let cwd;
12
+ let noLog = false;
12
13
  return {
13
14
  name: "dtsroll",
14
15
  apply: "build",
15
16
  enforce: "post",
17
+ config: ({ root, logLevel }) => {
18
+ cwd = root;
19
+ noLog = logLevel === "silent";
20
+ },
16
21
  writeBundle: {
17
22
  sequential: true,
18
23
  order: "post",
@@ -20,9 +25,15 @@ const dtsrollPlugin = (options) => {
20
25
  if (built) {
21
26
  return;
22
27
  }
23
- logOutput(await dtsroll(options));
24
- console.log();
28
+ const output = await dtsroll({
29
+ cwd,
30
+ ...options
31
+ });
25
32
  built = true;
33
+ if (!noLog) {
34
+ logOutput(output);
35
+ console.log();
36
+ }
26
37
  }
27
38
  }
28
39
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dtsroll",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Bundle dts files",
5
5
  "keywords": [
6
6
  "bundle",
@@ -1,100 +0,0 @@
1
- import path from 'node:path';
2
- import byteSize from 'byte-size';
3
- import { u as underline, c as bold, l as lightYellow, w as warningSignUnicode, e as dim, g as green, r as red, m as magenta, y as yellow } from './index-D3bowY1b.mjs';
4
-
5
- const cwd = process.cwd();
6
-
7
- const logOutput = (dtsOutput) => {
8
- console.log(underline("dtsroll"));
9
- const { inputs } = dtsOutput;
10
- const isCliInput = inputs[0][1] === void 0;
11
- console.log(bold(`
12
- \u{1F4E5} Entry points${isCliInput ? "" : " in package.json"}`));
13
- console.log(
14
- inputs.map(([inputFile, inputSource, error]) => {
15
- const relativeInputFile = path.relative(cwd, inputFile);
16
- const logPath2 = relativeInputFile.length < inputFile.length ? relativeInputFile : inputFile;
17
- if (error) {
18
- return ` ${lightYellow(`${warningSignUnicode} ${logPath2} ${dim(error)}`)}`;
19
- }
20
- return ` \u2192 ${green(logPath2)}${inputSource ? ` ${dim(`from ${inputSource}`)}` : ""}`;
21
- }).join("\n")
22
- );
23
- if ("error" in dtsOutput) {
24
- console.error(`${red("Error:")} ${dtsOutput.error}`);
25
- return;
26
- }
27
- const {
28
- outputDirectory,
29
- output: {
30
- entries: outputEntries,
31
- chunks: outputChunks
32
- },
33
- size,
34
- externals
35
- } = dtsOutput;
36
- const outputDirectoryRelative = path.relative(cwd, outputDirectory);
37
- const logPath = (outputDirectoryRelative.length < outputDirectory.length ? outputDirectoryRelative : outputDirectory) + path.sep;
38
- const logChunk = ({
39
- file,
40
- indent,
41
- bullet,
42
- color
43
- }) => {
44
- const sizeFormatted = byteSize(file.size).toString();
45
- let log = `${indent}${bullet} ${dim(color(logPath))}${color(file.fileName)} ${sizeFormatted}`;
46
- const { moduleIds, moduleToPackage } = file;
47
- log += `
48
- ${moduleIds.sort().map((moduleId, index) => {
49
- const isLast = index === moduleIds.length - 1;
50
- const prefix = `${indent} ${isLast ? "\u2514\u2500 " : "\u251C\u2500 "}`;
51
- const relativeModuleId = path.relative(cwd, moduleId);
52
- const logModuleId = relativeModuleId.length < moduleId.length ? relativeModuleId : moduleId;
53
- const bareSpecifier = moduleToPackage[moduleId];
54
- if (bareSpecifier) {
55
- return `${prefix}${dim(`${magenta(bareSpecifier)} (${logModuleId})`)}`;
56
- }
57
- return `${prefix}${dim(logModuleId)}`;
58
- }).join("\n")}`;
59
- return log;
60
- };
61
- console.log(bold("\n\u{1F4A0} Bundled output"));
62
- console.log(
63
- outputEntries.map((file) => logChunk({
64
- file,
65
- indent: " ",
66
- bullet: "\u25CF",
67
- color: green
68
- })).join("\n\n")
69
- );
70
- if (outputChunks.length > 0) {
71
- console.log(bold("\n Chunks"));
72
- console.log(
73
- outputChunks.map((file) => logChunk({
74
- file,
75
- indent: " ",
76
- bullet: "\u25A0",
77
- color: yellow
78
- })).join("\n\n")
79
- );
80
- }
81
- console.log(bold("\n\u2696\uFE0F Size savings"));
82
- const percentage = ((size.input - size.output) / size.input * 100).toFixed(0);
83
- console.log(` Input source size: ${byteSize(size.input).toString()}`);
84
- console.log(` Bundled output size: ${byteSize(size.output).toString()} (${percentage}% decrease)`);
85
- if (externals.length > 0) {
86
- console.log(bold("\n\u{1F4E6} External packages"));
87
- console.log(
88
- externals.map(([packageName, reason, devTypePackage]) => {
89
- let stdout = ` \u2500 ${magenta(packageName)} ${dim(`externalized ${reason}`)}`;
90
- if (devTypePackage) {
91
- stdout += `
92
- ${yellow("Warning:")} ${magenta(devTypePackage)} should not be in devDependencies if ${magenta(packageName)} is externalized`;
93
- }
94
- return stdout;
95
- }).sort().join("\n")
96
- );
97
- }
98
- };
99
-
100
- export { logOutput as l };