tsdown 0.4.2 → 0.4.3
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/dist/features/output.d.ts +2 -2
- package/dist/features/shims.d.ts +2 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +115 -69
- package/dist/options.d.ts +7 -3
- package/dist/run.js +2 -2
- package/dist/utils/fs.d.ts +1 -0
- package/package.json +3 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function resolveOutputExtension(pkg: any, format:
|
|
1
|
+
import type { NormalizedFormat } from "../options.js";
|
|
2
|
+
export declare function resolveOutputExtension(pkg: any, format: NormalizedFormat): "mjs" | "cjs" | "js";
|
package/dist/index.d.ts
CHANGED
|
@@ -4,15 +4,13 @@ import { logger } from "./utils/logger.js";
|
|
|
4
4
|
* Build with tsdown.
|
|
5
5
|
*/
|
|
6
6
|
export declare function build(userOptions?: Omit<Options, "silent">): Promise<void>;
|
|
7
|
+
export declare const assetsDir: string;
|
|
7
8
|
/**
|
|
8
9
|
* Build a single configuration, without watch and shortcuts features.
|
|
9
10
|
*
|
|
10
11
|
* @param resolved Resolved options
|
|
11
12
|
*/
|
|
12
|
-
export declare function buildSingle(resolved: ResolvedOptions): Promise<
|
|
13
|
-
rebuild: () => Promise<void>;
|
|
14
|
-
close: () => Promise<void>;
|
|
15
|
-
} | undefined>;
|
|
13
|
+
export declare function buildSingle(resolved: ResolvedOptions): Promise<(() => Promise<void>) | undefined>;
|
|
16
14
|
/**
|
|
17
15
|
* Defines the configuration for tsdown.
|
|
18
16
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { debug, logger } from "./logger-Pk57TMWT.js";
|
|
2
2
|
import { ExternalPlugin } from "./external-9r3oq3tH.js";
|
|
3
|
+
import path, { dirname as dirname$1, normalize, sep, default as path$1, default as path$2, default as path$3, default as path$4, default as path$5 } from "node:path";
|
|
3
4
|
import process, { default as process$1, default as process$2, default as process$3 } from "node:process";
|
|
4
|
-
import {
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { build as rolldownBuild } from "rolldown";
|
|
5
7
|
import { transformPlugin } from "rolldown/experimental";
|
|
6
8
|
import { IsolatedDecl } from "unplugin-isolated-decl";
|
|
7
9
|
import { Unused } from "unplugin-unused";
|
|
8
10
|
import { access, readdir, rm, stat } from "node:fs/promises";
|
|
9
|
-
import path, { default as path$1, default as path$2 } from "node:path";
|
|
10
11
|
import { glob, glob as glob$1 } from "tinyglobby";
|
|
11
12
|
import { readPackageJSON } from "pkg-types";
|
|
12
13
|
import readline from "node:readline";
|
|
@@ -14,15 +15,33 @@ import pc, { default as pc$1, default as pc$2 } from "picocolors";
|
|
|
14
15
|
import { loadConfig } from "unconfig";
|
|
15
16
|
|
|
16
17
|
//#region src/utils/fs.ts
|
|
17
|
-
function fsExists(path$
|
|
18
|
-
return access(path$
|
|
18
|
+
function fsExists(path$6) {
|
|
19
|
+
return access(path$6).then(() => true, () => false);
|
|
20
|
+
}
|
|
21
|
+
function lowestCommonAncestor(...filepaths) {
|
|
22
|
+
if (filepaths.length === 0) return "";
|
|
23
|
+
if (filepaths.length === 1) return dirname$1(filepaths[0]);
|
|
24
|
+
filepaths = filepaths.map(normalize);
|
|
25
|
+
const [first, ...rest] = filepaths;
|
|
26
|
+
let ancestor = first.split(sep);
|
|
27
|
+
for (const filepath of rest) {
|
|
28
|
+
const directories = filepath.split(sep, ancestor.length);
|
|
29
|
+
let index = 0;
|
|
30
|
+
for (const directory of directories) if (directory === ancestor[index]) index += 1;
|
|
31
|
+
else {
|
|
32
|
+
ancestor = ancestor.slice(0, index);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
ancestor = ancestor.slice(0, index);
|
|
36
|
+
}
|
|
37
|
+
return ancestor.length <= 1 && ancestor[0] === "" ? sep + ancestor[0] : ancestor.join(sep);
|
|
19
38
|
}
|
|
20
39
|
|
|
21
40
|
//#endregion
|
|
22
41
|
//#region src/features/clean.ts
|
|
23
42
|
async function cleanOutDir(cwd, patterns) {
|
|
24
43
|
const files = [];
|
|
25
|
-
if (await fsExists(cwd)) files.push(...(await readdir(cwd)).map((file) => path$
|
|
44
|
+
if (await fsExists(cwd)) files.push(...(await readdir(cwd)).map((file) => path$5.resolve(cwd, file)));
|
|
26
45
|
if (patterns.length) files.push(...await glob$1(patterns, {
|
|
27
46
|
cwd,
|
|
28
47
|
absolute: true
|
|
@@ -40,7 +59,7 @@ async function cleanOutDir(cwd, patterns) {
|
|
|
40
59
|
//#endregion
|
|
41
60
|
//#region src/utils/package.ts
|
|
42
61
|
async function readPackageJson(dir) {
|
|
43
|
-
const packageJsonPath = path$
|
|
62
|
+
const packageJsonPath = path$4.join(dir, "package.json");
|
|
44
63
|
const exists = await fsExists(packageJsonPath);
|
|
45
64
|
if (!exists) return;
|
|
46
65
|
debug("Reading package.json:", packageJsonPath);
|
|
@@ -59,15 +78,24 @@ function getPackageType(pkg) {
|
|
|
59
78
|
function resolveOutputExtension(pkg, format) {
|
|
60
79
|
const moduleType = getPackageType(pkg);
|
|
61
80
|
switch (format) {
|
|
62
|
-
case "es":
|
|
63
|
-
case "
|
|
64
|
-
case "module": return moduleType === "module" ? "js" : "mjs";
|
|
65
|
-
case "cjs":
|
|
66
|
-
case "commonjs": return moduleType === "module" ? "cjs" : "js";
|
|
81
|
+
case "es": return moduleType === "module" ? "js" : "mjs";
|
|
82
|
+
case "cjs": return moduleType === "module" ? "cjs" : "js";
|
|
67
83
|
default: return "js";
|
|
68
84
|
}
|
|
69
85
|
}
|
|
70
86
|
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/features/shims.ts
|
|
89
|
+
function getShimsInject(format, platform) {
|
|
90
|
+
if (format === "es" && platform === "node") {
|
|
91
|
+
const shimFile = path$3.resolve(assetsDir, "esm-shims.js");
|
|
92
|
+
return {
|
|
93
|
+
__dirname: [shimFile, "__dirname"],
|
|
94
|
+
__filename: [shimFile, "__filename"]
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
71
99
|
//#endregion
|
|
72
100
|
//#region src/features/shortcuts.ts
|
|
73
101
|
function shortcuts(restart) {
|
|
@@ -168,9 +196,13 @@ async function resolveEntry(entry) {
|
|
|
168
196
|
if (typeof entry === "string") entry = [entry];
|
|
169
197
|
if (Array.isArray(entry)) {
|
|
170
198
|
const resolvedEntry = await glob(entry);
|
|
199
|
+
const base = lowestCommonAncestor(...resolvedEntry);
|
|
171
200
|
if (resolvedEntry.length > 0) {
|
|
172
|
-
entry
|
|
173
|
-
|
|
201
|
+
logger.info(`entry: ${pc$1.blue(resolvedEntry.join(", "))}`);
|
|
202
|
+
entry = Object.fromEntries(resolvedEntry.map((file) => {
|
|
203
|
+
const relative = path$2.relative(base, file);
|
|
204
|
+
return [relative.slice(0, relative.length - path$2.extname(relative).length), file];
|
|
205
|
+
}));
|
|
174
206
|
} else throw new Error(`Cannot find entry: ${entry}`);
|
|
175
207
|
} else {
|
|
176
208
|
const files = Object.values(entry);
|
|
@@ -192,16 +224,15 @@ async function resolveOptions(options) {
|
|
|
192
224
|
...subConfig,
|
|
193
225
|
...options
|
|
194
226
|
};
|
|
195
|
-
let { entry, format = ["es"], plugins = [], clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, watch = false, skipNodeModulesBundle = false } = subOptions;
|
|
227
|
+
let { entry, format = ["es"], plugins = [], clean = false, silent = false, treeshake = true, platform = "node", outDir = "dist", sourcemap = false, dts = false, unused = false, watch = false, shims = false, skipNodeModulesBundle = false } = subOptions;
|
|
196
228
|
entry = await resolveEntry(entry);
|
|
197
|
-
format = toArray(format, "es");
|
|
198
229
|
if (clean === true) clean = [];
|
|
199
230
|
return {
|
|
200
231
|
...subOptions,
|
|
201
232
|
entry,
|
|
202
233
|
plugins,
|
|
203
|
-
format,
|
|
204
|
-
outDir: path.resolve(outDir),
|
|
234
|
+
format: normalizeFormat(format),
|
|
235
|
+
outDir: path$1.resolve(outDir),
|
|
205
236
|
clean,
|
|
206
237
|
silent,
|
|
207
238
|
treeshake,
|
|
@@ -210,10 +241,23 @@ async function resolveOptions(options) {
|
|
|
210
241
|
dts,
|
|
211
242
|
unused,
|
|
212
243
|
watch,
|
|
244
|
+
shims,
|
|
213
245
|
skipNodeModulesBundle
|
|
214
246
|
};
|
|
215
247
|
})), configFile];
|
|
216
248
|
}
|
|
249
|
+
function normalizeFormat(format) {
|
|
250
|
+
return toArray(format, "es").map((format$1) => {
|
|
251
|
+
switch (format$1) {
|
|
252
|
+
case "es":
|
|
253
|
+
case "esm":
|
|
254
|
+
case "module": return "es";
|
|
255
|
+
case "cjs":
|
|
256
|
+
case "commonjs": return "cjs";
|
|
257
|
+
default: return format$1;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
217
261
|
async function loadConfigFile(options) {
|
|
218
262
|
let { config: filePath } = options;
|
|
219
263
|
if (filePath === false) return [[]];
|
|
@@ -221,11 +265,11 @@ async function loadConfigFile(options) {
|
|
|
221
265
|
let overrideConfig = false;
|
|
222
266
|
let stats;
|
|
223
267
|
if (typeof filePath === "string" && (stats = await stat(filePath).catch(() => null))) {
|
|
224
|
-
const resolved = path.resolve(filePath);
|
|
268
|
+
const resolved = path$1.resolve(filePath);
|
|
225
269
|
if (stats.isFile()) {
|
|
226
270
|
overrideConfig = true;
|
|
227
271
|
filePath = resolved;
|
|
228
|
-
cwd = path.dirname(filePath);
|
|
272
|
+
cwd = path$1.dirname(filePath);
|
|
229
273
|
} else cwd = resolved;
|
|
230
274
|
}
|
|
231
275
|
const { config, sources } = await loadConfig({
|
|
@@ -264,69 +308,71 @@ async function build(userOptions = {}) {
|
|
|
264
308
|
const [resolveds, configFile] = await resolveOptions(userOptions);
|
|
265
309
|
if (configFile) debug("Loaded config:", configFile);
|
|
266
310
|
else debug("No config file found");
|
|
267
|
-
const
|
|
311
|
+
const rebuilds = await Promise.all(resolveds.map(buildSingle));
|
|
268
312
|
const cleanCbs = [];
|
|
269
313
|
for (const [i, resolved] of resolveds.entries()) {
|
|
270
|
-
const
|
|
271
|
-
if (!
|
|
272
|
-
const watcher = await watchBuild(resolved,
|
|
273
|
-
cleanCbs.push(
|
|
274
|
-
await watcher.close();
|
|
275
|
-
await contexts[i].close();
|
|
276
|
-
});
|
|
314
|
+
const rebuild = rebuilds[i];
|
|
315
|
+
if (!rebuild) continue;
|
|
316
|
+
const watcher = await watchBuild(resolved, rebuild);
|
|
317
|
+
cleanCbs.push(() => watcher.close());
|
|
277
318
|
}
|
|
278
319
|
if (cleanCbs.length) shortcuts(async () => {
|
|
279
320
|
for (const clean of cleanCbs) await clean();
|
|
280
321
|
build(userOptions);
|
|
281
322
|
});
|
|
282
323
|
}
|
|
324
|
+
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
325
|
+
const assetsDir = path.resolve(dirname, "../assets");
|
|
283
326
|
async function buildSingle(resolved) {
|
|
284
|
-
const { entry, external, plugins, outDir, format, clean, platform, alias, treeshake, sourcemap, dts, minify, watch, unused, target, onSuccess } = resolved;
|
|
327
|
+
const { entry, external, plugins: userPlugins, outDir, format, clean, platform, alias, treeshake, sourcemap, dts, minify, watch, unused, target, define, shims, onSuccess } = resolved;
|
|
285
328
|
if (clean) await cleanOutDir(outDir, clean);
|
|
286
329
|
const pkg = await readPackageJson(process.cwd());
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
treeshake,
|
|
293
|
-
platform,
|
|
294
|
-
plugins: [
|
|
330
|
+
await rebuild(true);
|
|
331
|
+
if (watch) return () => rebuild();
|
|
332
|
+
async function rebuild(first) {
|
|
333
|
+
const startTime = performance.now();
|
|
334
|
+
const plugins = [
|
|
295
335
|
pkg && ExternalPlugin(pkg, resolved.skipNodeModulesBundle),
|
|
296
336
|
unused && Unused.rolldown(unused === true ? {} : unused),
|
|
297
337
|
dts && IsolatedDecl.rolldown(dts === true ? {} : dts),
|
|
298
|
-
target && transformPlugin({ target: typeof target === "string" ? target : target.join(",") }),
|
|
299
|
-
|
|
300
|
-
].filter((plugin) => !!plugin)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
338
|
+
target && transformPlugin({ target: target && (typeof target === "string" ? target : target.join(",")) }),
|
|
339
|
+
userPlugins
|
|
340
|
+
].filter((plugin) => !!plugin);
|
|
341
|
+
await Promise.all(format.map(async (format$1) => {
|
|
342
|
+
const inputOptions = {
|
|
343
|
+
input: entry,
|
|
344
|
+
external,
|
|
345
|
+
resolve: { alias },
|
|
346
|
+
treeshake,
|
|
347
|
+
platform,
|
|
348
|
+
define,
|
|
349
|
+
plugins,
|
|
350
|
+
...resolved.inputOptions,
|
|
351
|
+
inject: {
|
|
352
|
+
...shims && getShimsInject(format$1, platform),
|
|
353
|
+
...resolved.inputOptions?.inject
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
const extension = resolveOutputExtension(pkg, format$1);
|
|
357
|
+
let outputOptions = {
|
|
358
|
+
format: format$1,
|
|
359
|
+
name: resolved.globalName,
|
|
360
|
+
sourcemap,
|
|
361
|
+
dir: outDir,
|
|
362
|
+
minify,
|
|
363
|
+
entryFileNames: `[name].${extension}`,
|
|
364
|
+
chunkFileNames: `[name]-[hash].${extension}`
|
|
365
|
+
};
|
|
366
|
+
const userOutputOptions = typeof resolved.outputOptions === "function" ? await resolved.outputOptions(outputOptions, format$1) : resolved.outputOptions;
|
|
367
|
+
outputOptions = {
|
|
368
|
+
...outputOptions,
|
|
369
|
+
...userOutputOptions
|
|
370
|
+
};
|
|
371
|
+
await rolldownBuild({
|
|
372
|
+
...inputOptions,
|
|
373
|
+
output: outputOptions
|
|
374
|
+
});
|
|
375
|
+
}));
|
|
330
376
|
logger.success(`${first ? "Build" : "Rebuild"} complete in ${Math.round(performance.now() - startTime)}ms`);
|
|
331
377
|
await onSuccess?.();
|
|
332
378
|
}
|
|
@@ -336,4 +382,4 @@ function defineConfig(options) {
|
|
|
336
382
|
}
|
|
337
383
|
|
|
338
384
|
//#endregion
|
|
339
|
-
export { build, buildSingle, defineConfig, logger };
|
|
385
|
+
export { assetsDir, build, buildSingle, defineConfig, logger };
|
package/dist/options.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { External } from "./features/external.js";
|
|
2
2
|
import type { Arrayable, MarkPartial, MaybePromise, Overwrite } from "./utils/types.js";
|
|
3
|
-
import type { InputOptions, ModuleFormat, OutputOptions } from "rolldown";
|
|
3
|
+
import type { InputOptions, InternalModuleFormat, ModuleFormat, OutputOptions } from "rolldown";
|
|
4
4
|
import type { Options as IsolatedDeclOptions } from "unplugin-isolated-decl";
|
|
5
5
|
import type { Options as UnusedOptions } from "unplugin-unused";
|
|
6
6
|
export type Sourcemap = boolean | "inline" | "hidden";
|
|
@@ -24,8 +24,10 @@ export interface Options {
|
|
|
24
24
|
/** @default false */
|
|
25
25
|
minify?: boolean;
|
|
26
26
|
target?: string | string[];
|
|
27
|
+
define?: Record<string, string>;
|
|
27
28
|
/** @default 'node' */
|
|
28
29
|
platform?: "node" | "neutral" | "browser";
|
|
30
|
+
shims?: boolean;
|
|
29
31
|
/**
|
|
30
32
|
* Enable dts generation with `isolatedDeclarations` (experimental)
|
|
31
33
|
*/
|
|
@@ -48,8 +50,10 @@ export interface Options {
|
|
|
48
50
|
*/
|
|
49
51
|
export type Config = Arrayable<Omit<Options, "config">>;
|
|
50
52
|
export type ResolvedConfig = Extract<Config, any[]>;
|
|
51
|
-
export type
|
|
52
|
-
|
|
53
|
+
export type NormalizedFormat = Exclude<InternalModuleFormat, "app"> | "experimental-app";
|
|
54
|
+
export type ResolvedOptions = Omit<Overwrite<MarkPartial<Options, "globalName" | "inputOptions" | "outputOptions" | "minify" | "target" | "define" | "alias" | "external" | "onSuccess">, {
|
|
55
|
+
format: NormalizedFormat[];
|
|
53
56
|
clean: string[] | false;
|
|
54
57
|
}>, "config">;
|
|
55
58
|
export declare function resolveOptions(options: Options): Promise<[configs: ResolvedOptions[], configFile?: string]>;
|
|
59
|
+
export declare function normalizeFormat(format: ModuleFormat | ModuleFormat[]): NormalizedFormat[];
|
package/dist/run.js
CHANGED
|
@@ -5,13 +5,13 @@ import pc from "picocolors";
|
|
|
5
5
|
import { cac } from "cac";
|
|
6
6
|
|
|
7
7
|
//#region package.json
|
|
8
|
-
var version = "0.4.
|
|
8
|
+
var version = "0.4.3";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/cli.ts
|
|
12
12
|
async function runCLI() {
|
|
13
13
|
const cli = cac("tsdown");
|
|
14
|
-
cli.command("[...files]", "Bundle files", { ignoreOptionDefaultValue: true }).option("-c, --config <filename>", "Use a custom config file").option("--no-config", "Disable config file").option("--format <format>", "Bundle format: esm, cjs, iife", { default: "esm" }).option("--clean", "Clean output directory").option("--minify", "Minify output").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("--silent", "Suppress non-error logs").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("-w, --watch [path]", "Watch mode").action(async (input, flags) => {
|
|
14
|
+
cli.command("[...files]", "Bundle files", { ignoreOptionDefaultValue: true }).option("-c, --config <filename>", "Use a custom config file").option("--no-config", "Disable config file").option("--format <format>", "Bundle format: esm, cjs, iife", { default: "esm" }).option("--clean", "Clean output directory").option("--minify", "Minify output").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("--silent", "Suppress non-error logs").option("-d, --out-dir <dir>", "Output directory", { default: "dist" }).option("--treeshake", "Tree-shake bundle", { default: true }).option("--sourcemap", "Generate source map", { default: false }).option("--shims", "Enable cjs and esm shims ", { default: false }).option("--platform <platform>", "Target platform", { default: "node" }).option("-w, --watch [path]", "Watch mode").action(async (input, flags) => {
|
|
15
15
|
if (!("CONSOLA_LEVEL" in process.env)) logger.level = flags.silent ? 0 : 3;
|
|
16
16
|
logger.info(`tsdown ${pc.dim(`v${version}`)} powered by rolldown ${pc.dim(`v${rolldownVersion}`)}`);
|
|
17
17
|
const { build } = await import("./index.js");
|
package/dist/utils/fs.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsdown",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "An even faster bundler powered by Rolldown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"debug": "^4.3.7",
|
|
46
46
|
"picocolors": "^1.1.1",
|
|
47
47
|
"pkg-types": "^1.2.1",
|
|
48
|
-
"rolldown": "0.15.0-snapshot-
|
|
48
|
+
"rolldown": "0.15.0-snapshot-64a831c-20241207003504",
|
|
49
49
|
"tinyglobby": "^0.2.10",
|
|
50
50
|
"unconfig": "^0.6.0",
|
|
51
51
|
"unplugin-isolated-decl": "^0.9.3",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"@types/node": "^22.10.1",
|
|
59
59
|
"bumpp": "^9.8.1",
|
|
60
60
|
"eslint": "^9.16.0",
|
|
61
|
-
"execa": "^9.5.1",
|
|
62
61
|
"fdir": "^6.4.2",
|
|
63
62
|
"oxc-transform": "^0.39.0",
|
|
64
63
|
"prettier": "^3.4.2",
|
|
64
|
+
"tinyexec": "^0.3.1",
|
|
65
65
|
"tsup": "^8.3.5",
|
|
66
66
|
"tsx": "^4.19.2",
|
|
67
67
|
"typescript": "~5.7.2",
|