tsdown 0.19.0-beta.3 → 0.19.0-beta.4
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/{src-CdIeTOkO.mjs → build-CczdykTO.mjs} +30 -21
- package/dist/build.d.mts +18 -0
- package/dist/build.mjs +3 -0
- package/dist/{config-DgP9n0Zr.d.mts → config-Cj-nN1Zu.d.mts} +1 -1
- package/dist/{config-mm6j0EhS.mjs → config-DCPo70ac.mjs} +150 -150
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +1 -1
- package/dist/debug-C60bWO35.mjs +22 -0
- package/dist/index.d.mts +6 -8
- package/dist/index.mjs +5 -4
- package/dist/{logger-D_2uXZBG.mjs → logger-C5G3WyAl.mjs} +1 -1
- package/dist/plugins.d.mts +1 -1
- package/dist/plugins.mjs +1 -1
- package/dist/run.mjs +5 -21
- package/dist/{types-Drx0i6TJ.d.mts → types-Dxm9xngg.d.mts} +1 -1
- package/package.json +3 -2
- package/dist/package-5WK85-g_.mjs +0 -5
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
2
|
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
3
|
-
import { a as globalLogger, c as matchPattern, d as promiseWithResolvers, f as resolveComma, h as toArray, l as noop, m as slash, o as prettyFormat, s as importWithError, t as LogLevels } from "./logger-
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
3
|
+
import { a as globalLogger, c as matchPattern, d as promiseWithResolvers, f as resolveComma, h as toArray, l as noop, m as slash, o as prettyFormat, s as importWithError, t as LogLevels } from "./logger-C5G3WyAl.mjs";
|
|
4
|
+
import { a as getPackageType, c as defaultCssBundleName, d as loadConfigFile, f as fsCopy, h as lowestCommonAncestor, i as resolveUserConfig, l as cleanChunks, m as fsRemove, o as writeExports, p as fsExists, r as mergeUserOptions, s as formatBytes, u as cleanOutDir } from "./config-DCPo70ac.mjs";
|
|
5
|
+
import { n as version } from "./debug-C60bWO35.mjs";
|
|
6
6
|
import { builtinModules, isBuiltin } from "node:module";
|
|
7
|
-
import {
|
|
7
|
+
import { blue, bold, dim, green, underline } from "ansis";
|
|
8
|
+
import { clearRequireCache } from "import-without-cache";
|
|
9
|
+
import * as Rolldown from "rolldown";
|
|
10
|
+
import { VERSION, build, watch } from "rolldown";
|
|
8
11
|
import path from "node:path";
|
|
12
|
+
import { createDebug } from "obug";
|
|
13
|
+
import { chmod, mkdtemp, readFile, writeFile } from "node:fs/promises";
|
|
9
14
|
import process from "node:process";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
10
16
|
import { formatWithOptions, inspect, promisify } from "node:util";
|
|
11
|
-
import { blue, bold, dim, green, underline } from "ansis";
|
|
12
|
-
import { createDebug } from "obug";
|
|
13
17
|
import { glob, isDynamicPattern } from "tinyglobby";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
15
18
|
import { RE_CSS, RE_DTS, RE_JS, RE_NODE_MODULES } from "rolldown-plugin-dts/filename";
|
|
16
|
-
import { clearRequireCache } from "import-without-cache";
|
|
17
|
-
import * as Rolldown from "rolldown";
|
|
18
|
-
import { VERSION, build, watch } from "rolldown";
|
|
19
19
|
const coerce = __cjs_require("semver/functions/coerce.js");
|
|
20
20
|
const satisfies = __cjs_require("semver/functions/satisfies.js");
|
|
21
21
|
import { Hookable } from "hookable";
|
|
@@ -537,6 +537,13 @@ function normalizeChunkFileName(chunkFileName) {
|
|
|
537
537
|
return chunkFileName.replace(RE_CHUNK_HASH, "").replace(RE_CHUNK_EXT, "");
|
|
538
538
|
}
|
|
539
539
|
|
|
540
|
+
//#endregion
|
|
541
|
+
//#region src/index.ts
|
|
542
|
+
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
543
|
+
const pkgRoot = path.resolve(dirname, "..");
|
|
544
|
+
/** @internal */
|
|
545
|
+
const shimFile = path.resolve(pkgRoot, "esm-shims.js");
|
|
546
|
+
|
|
540
547
|
//#endregion
|
|
541
548
|
//#region src/features/external.ts
|
|
542
549
|
const debug$2 = createDebug("tsdown:external");
|
|
@@ -998,7 +1005,7 @@ function shortcuts(restart) {
|
|
|
998
1005
|
}
|
|
999
1006
|
|
|
1000
1007
|
//#endregion
|
|
1001
|
-
//#region src/
|
|
1008
|
+
//#region src/build.ts
|
|
1002
1009
|
const asyncDispose = Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose");
|
|
1003
1010
|
/**
|
|
1004
1011
|
* Build with tsdown.
|
|
@@ -1006,6 +1013,16 @@ const asyncDispose = Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose");
|
|
|
1006
1013
|
async function build$1(userOptions = {}) {
|
|
1007
1014
|
globalLogger.level = userOptions.logLevel || "info";
|
|
1008
1015
|
const { configs, files: configFiles } = await resolveConfig(userOptions);
|
|
1016
|
+
return buildWithConfigs(configs, configFiles);
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* Build with `ResolvedConfigs`.
|
|
1020
|
+
*
|
|
1021
|
+
* Internal API, not for public use
|
|
1022
|
+
*
|
|
1023
|
+
* @private
|
|
1024
|
+
*/
|
|
1025
|
+
async function buildWithConfigs(configs, configFiles) {
|
|
1009
1026
|
let cleanPromise;
|
|
1010
1027
|
const clean = () => {
|
|
1011
1028
|
if (cleanPromise) return cleanPromise;
|
|
@@ -1018,7 +1035,7 @@ async function build$1(userOptions = {}) {
|
|
|
1018
1035
|
restarting = true;
|
|
1019
1036
|
await Promise.all(disposeCbs.map((cb) => cb()));
|
|
1020
1037
|
clearRequireCache();
|
|
1021
|
-
|
|
1038
|
+
buildWithConfigs(configs, configFiles);
|
|
1022
1039
|
}
|
|
1023
1040
|
const configChunksByPkg = initBundleByPkg(configs);
|
|
1024
1041
|
function done(bundle) {
|
|
@@ -1037,10 +1054,6 @@ async function build$1(userOptions = {}) {
|
|
|
1037
1054
|
}
|
|
1038
1055
|
/**
|
|
1039
1056
|
* Build a single configuration, without watch and shortcuts features.
|
|
1040
|
-
*
|
|
1041
|
-
* Internal API, not for public use
|
|
1042
|
-
*
|
|
1043
|
-
* @internal
|
|
1044
1057
|
* @param config Resolved options
|
|
1045
1058
|
*/
|
|
1046
1059
|
async function buildSingle(config, configFiles, isDualFormat, clean, restart, done) {
|
|
@@ -1138,10 +1151,6 @@ async function buildSingle(config, configFiles, isDualFormat, clean, restart, do
|
|
|
1138
1151
|
ab = executeOnSuccess(config);
|
|
1139
1152
|
}
|
|
1140
1153
|
}
|
|
1141
|
-
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
1142
|
-
const pkgRoot = path.resolve(dirname, "..");
|
|
1143
|
-
/** @internal */
|
|
1144
|
-
const shimFile = path.resolve(pkgRoot, "esm-shims.js");
|
|
1145
1154
|
|
|
1146
1155
|
//#endregion
|
|
1147
|
-
export {
|
|
1156
|
+
export { ReportPlugin as a, Rolldown as c, ShebangPlugin as i, shimFile as l, buildWithConfigs as n, NodeProtocolPlugin as o, WatchPlugin as r, ExternalPlugin as s, build$1 as t };
|
package/dist/build.d.mts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { i as InlineConfig, s as ResolvedConfig, w as TsdownBundle } from "./types-Dxm9xngg.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/build.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build with tsdown.
|
|
7
|
+
*/
|
|
8
|
+
declare function build(userOptions?: InlineConfig): Promise<TsdownBundle[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Build with `ResolvedConfigs`.
|
|
11
|
+
*
|
|
12
|
+
* Internal API, not for public use
|
|
13
|
+
*
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
declare function buildWithConfigs(configs: ResolvedConfig[], configFiles: string[]): Promise<TsdownBundle[]>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { build, buildWithConfigs };
|
package/dist/build.mjs
ADDED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as UserConfig, i as InlineConfig, m as UserConfigFn, p as UserConfigExport } from "./types-
|
|
1
|
+
import { f as UserConfig, i as InlineConfig, m as UserConfigFn, p as UserConfigExport } from "./types-Dxm9xngg.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/config/options.d.ts
|
|
4
4
|
declare function mergeConfig(defaults: UserConfig, overrides: UserConfig): UserConfig;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
2
|
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
3
|
-
import { a as globalLogger, c as matchPattern, f as resolveComma, h as toArray, i as getNameLabel, m as slash, n as createLogger, p as resolveRegex, r as generateColor, u as pkgExists } from "./logger-
|
|
4
|
-
import {
|
|
3
|
+
import { a as globalLogger, c as matchPattern, f as resolveComma, h as toArray, i as getNameLabel, m as slash, n as createLogger, p as resolveRegex, r as generateColor, u as pkgExists } from "./logger-C5G3WyAl.mjs";
|
|
4
|
+
import { blue, underline } from "ansis";
|
|
5
|
+
import { init, isSupported } from "import-without-cache";
|
|
5
6
|
import path from "node:path";
|
|
7
|
+
import { createDebug } from "obug";
|
|
8
|
+
import { access, cp, readFile, rm, stat } from "node:fs/promises";
|
|
6
9
|
import process, { env } from "node:process";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
import { createConfigCoreLoader } from "unconfig-core";
|
|
12
|
+
const picomatch = __cjs_require("picomatch");
|
|
7
13
|
import { parseEnv } from "node:util";
|
|
8
|
-
import { blue, underline } from "ansis";
|
|
9
14
|
import { createDefu } from "defu";
|
|
10
|
-
import { createDebug } from "obug";
|
|
11
15
|
import { glob, isDynamicPattern } from "tinyglobby";
|
|
12
|
-
import { pathToFileURL } from "node:url";
|
|
13
|
-
const picomatch = __cjs_require("picomatch");
|
|
14
16
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
15
17
|
import { RE_CSS, RE_DTS } from "rolldown-plugin-dts/filename";
|
|
16
18
|
const minVersion = __cjs_require("semver/ranges/min-version.js");
|
|
17
19
|
import { up } from "empathic/find";
|
|
18
20
|
import { up as up$1 } from "empathic/package";
|
|
19
|
-
import { init, isSupported } from "import-without-cache";
|
|
20
|
-
import { createConfigCoreLoader } from "unconfig-core";
|
|
21
21
|
|
|
22
22
|
//#region node_modules/.pnpm/is-in-ci@2.0.0/node_modules/is-in-ci/index.js
|
|
23
23
|
const check = (key) => key in env && env[key] !== "0" && env[key] !== "false";
|
|
@@ -68,9 +68,144 @@ function stripExtname(filePath) {
|
|
|
68
68
|
return filePath.slice(0, -ext.length);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/config/file.ts
|
|
73
|
+
const debug$3 = createDebug("tsdown:config:file");
|
|
74
|
+
async function loadViteConfig(prefix, cwd, configLoader) {
|
|
75
|
+
const loader = resolveConfigLoader(configLoader);
|
|
76
|
+
debug$3("Loading Vite config via loader: ", loader);
|
|
77
|
+
const parser = createParser(loader);
|
|
78
|
+
const [result] = await createConfigCoreLoader({
|
|
79
|
+
sources: [{
|
|
80
|
+
files: [`${prefix}.config`],
|
|
81
|
+
extensions: [
|
|
82
|
+
"js",
|
|
83
|
+
"mjs",
|
|
84
|
+
"ts",
|
|
85
|
+
"cjs",
|
|
86
|
+
"mts",
|
|
87
|
+
"mts"
|
|
88
|
+
],
|
|
89
|
+
parser
|
|
90
|
+
}],
|
|
91
|
+
cwd
|
|
92
|
+
}).load(true);
|
|
93
|
+
if (!result) return;
|
|
94
|
+
const { config, source } = result;
|
|
95
|
+
globalLogger.info(`Using Vite config: ${underline(source)}`);
|
|
96
|
+
const resolved = await config;
|
|
97
|
+
if (typeof resolved === "function") return resolved({
|
|
98
|
+
command: "build",
|
|
99
|
+
mode: "production"
|
|
100
|
+
});
|
|
101
|
+
return resolved;
|
|
102
|
+
}
|
|
103
|
+
const configPrefix = "tsdown.config";
|
|
104
|
+
async function loadConfigFile(inlineConfig, workspace) {
|
|
105
|
+
let cwd = inlineConfig.cwd || process.cwd();
|
|
106
|
+
let overrideConfig = false;
|
|
107
|
+
let { config: filePath } = inlineConfig;
|
|
108
|
+
if (filePath === false) return { configs: [{}] };
|
|
109
|
+
if (typeof filePath === "string") {
|
|
110
|
+
const stats = await fsStat(filePath);
|
|
111
|
+
if (stats) {
|
|
112
|
+
const resolved = path.resolve(filePath);
|
|
113
|
+
if (stats.isFile()) {
|
|
114
|
+
overrideConfig = true;
|
|
115
|
+
filePath = resolved;
|
|
116
|
+
cwd = path.dirname(filePath);
|
|
117
|
+
} else if (stats.isDirectory()) cwd = resolved;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const loader = resolveConfigLoader(inlineConfig.configLoader);
|
|
121
|
+
debug$3("Using config loader:", loader);
|
|
122
|
+
const parser = createParser(loader);
|
|
123
|
+
const [result] = await createConfigCoreLoader({
|
|
124
|
+
sources: overrideConfig ? [{
|
|
125
|
+
files: [filePath],
|
|
126
|
+
extensions: [],
|
|
127
|
+
parser
|
|
128
|
+
}] : [{
|
|
129
|
+
files: [configPrefix],
|
|
130
|
+
extensions: [
|
|
131
|
+
"ts",
|
|
132
|
+
"mts",
|
|
133
|
+
"cts",
|
|
134
|
+
"js",
|
|
135
|
+
"mjs",
|
|
136
|
+
"cjs",
|
|
137
|
+
"json"
|
|
138
|
+
],
|
|
139
|
+
parser
|
|
140
|
+
}, {
|
|
141
|
+
files: ["package.json"],
|
|
142
|
+
parser
|
|
143
|
+
}],
|
|
144
|
+
cwd,
|
|
145
|
+
stopAt: workspace && path.dirname(workspace)
|
|
146
|
+
}).load(true);
|
|
147
|
+
let exported = [];
|
|
148
|
+
let file;
|
|
149
|
+
if (result) {
|
|
150
|
+
({config: exported, source: file} = result);
|
|
151
|
+
globalLogger.info(`config file: ${underline(file)}`, loader === "native" ? "" : `(${loader})`);
|
|
152
|
+
exported = await exported;
|
|
153
|
+
if (typeof exported === "function") exported = await exported(inlineConfig, { ci: is_in_ci_default });
|
|
154
|
+
}
|
|
155
|
+
exported = toArray(exported);
|
|
156
|
+
if (exported.length === 0) exported.push({});
|
|
157
|
+
if (exported.some((config) => typeof config === "function")) throw new Error("Function should not be nested within multiple tsdown configurations. It must be at the top level.\nExample: export default defineConfig(() => [...])");
|
|
158
|
+
return {
|
|
159
|
+
configs: exported.map((config) => ({
|
|
160
|
+
...config,
|
|
161
|
+
cwd: config.cwd ? path.resolve(cwd, config.cwd) : cwd
|
|
162
|
+
})),
|
|
163
|
+
file
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const isBun = !!process.versions.bun;
|
|
167
|
+
const nativeTS = process.features.typescript || process.versions.deno;
|
|
168
|
+
const autoLoader = isBun || nativeTS && isSupported ? "native" : "unrun";
|
|
169
|
+
function resolveConfigLoader(configLoader = "auto") {
|
|
170
|
+
if (configLoader === "auto") return autoLoader;
|
|
171
|
+
else return configLoader === "native" ? "native" : "unrun";
|
|
172
|
+
}
|
|
173
|
+
function createParser(loader) {
|
|
174
|
+
return async (filepath) => {
|
|
175
|
+
const basename = path.basename(filepath);
|
|
176
|
+
const isPkgJson = basename === "package.json";
|
|
177
|
+
if (basename === configPrefix || isPkgJson || basename.endsWith(".json")) {
|
|
178
|
+
const contents = await readFile(filepath, "utf8");
|
|
179
|
+
const parsed = JSON.parse(contents);
|
|
180
|
+
if (isPkgJson) return parsed?.tsdown;
|
|
181
|
+
return parsed;
|
|
182
|
+
}
|
|
183
|
+
if (loader === "native") return nativeImport(filepath);
|
|
184
|
+
return unrunImport(filepath);
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async function nativeImport(id) {
|
|
188
|
+
const url = pathToFileURL(id);
|
|
189
|
+
const importAttributes = Object.create(null);
|
|
190
|
+
if (isSupported) {
|
|
191
|
+
importAttributes.cache = "no";
|
|
192
|
+
init({ skipNodeModules: true });
|
|
193
|
+
} else if (!isBun) url.searchParams.set("no-cache", crypto.randomUUID());
|
|
194
|
+
const mod = await import(url.href, { with: importAttributes }).catch((error) => {
|
|
195
|
+
if (error?.message?.includes?.("Cannot find module")) throw new Error(`Failed to load the config file. Try setting the --config-loader CLI flag to \`unrun\`.\n\n${error.message}`, { cause: error });
|
|
196
|
+
else throw error;
|
|
197
|
+
});
|
|
198
|
+
return mod.default || mod;
|
|
199
|
+
}
|
|
200
|
+
async function unrunImport(id) {
|
|
201
|
+
const { unrun } = await import("unrun");
|
|
202
|
+
const { module } = await unrun({ path: pathToFileURL(id).href });
|
|
203
|
+
return module;
|
|
204
|
+
}
|
|
205
|
+
|
|
71
206
|
//#endregion
|
|
72
207
|
//#region src/features/clean.ts
|
|
73
|
-
const debug$
|
|
208
|
+
const debug$2 = createDebug("tsdown:clean");
|
|
74
209
|
const RE_LAST_SLASH = /[/\\]$/;
|
|
75
210
|
async function cleanOutDir(configs) {
|
|
76
211
|
const removes = /* @__PURE__ */ new Set();
|
|
@@ -89,10 +224,10 @@ async function cleanOutDir(configs) {
|
|
|
89
224
|
if (!removes.size) return;
|
|
90
225
|
globalLogger.info(`Cleaning ${removes.size} files`);
|
|
91
226
|
await Promise.all([...removes].map(async (file) => {
|
|
92
|
-
debug$
|
|
227
|
+
debug$2("Removing", file);
|
|
93
228
|
await fsRemove(file);
|
|
94
229
|
}));
|
|
95
|
-
debug$
|
|
230
|
+
debug$2("Removed %d files", removes.size);
|
|
96
231
|
}
|
|
97
232
|
function resolveClean(clean, outDir, cwd) {
|
|
98
233
|
if (clean === true) clean = [slash(outDir)];
|
|
@@ -103,7 +238,7 @@ function resolveClean(clean, outDir, cwd) {
|
|
|
103
238
|
async function cleanChunks(outDir, chunks) {
|
|
104
239
|
await Promise.all(chunks.map(async (chunk) => {
|
|
105
240
|
const filePath = path.resolve(outDir, chunk.fileName);
|
|
106
|
-
debug$
|
|
241
|
+
debug$2("Removing chunk file", filePath);
|
|
107
242
|
await fsRemove(filePath);
|
|
108
243
|
}));
|
|
109
244
|
}
|
|
@@ -386,11 +521,11 @@ async function resolveTsconfig(logger, tsconfig, cwd, color, nameLabel) {
|
|
|
386
521
|
|
|
387
522
|
//#endregion
|
|
388
523
|
//#region src/utils/package.ts
|
|
389
|
-
const debug$
|
|
524
|
+
const debug$1 = createDebug("tsdown:package");
|
|
390
525
|
async function readPackageJson(dir) {
|
|
391
526
|
const packageJsonPath = up$1({ cwd: dir });
|
|
392
527
|
if (!packageJsonPath) return;
|
|
393
|
-
debug$
|
|
528
|
+
debug$1("Reading package.json:", packageJsonPath);
|
|
394
529
|
const contents = await readFile(packageJsonPath, "utf8");
|
|
395
530
|
return {
|
|
396
531
|
...JSON.parse(contents),
|
|
@@ -414,141 +549,6 @@ function normalizeFormat(format) {
|
|
|
414
549
|
}
|
|
415
550
|
}
|
|
416
551
|
|
|
417
|
-
//#endregion
|
|
418
|
-
//#region src/config/file.ts
|
|
419
|
-
const debug$1 = createDebug("tsdown:config:file");
|
|
420
|
-
async function loadViteConfig(prefix, cwd, configLoader) {
|
|
421
|
-
const loader = resolveConfigLoader(configLoader);
|
|
422
|
-
debug$1("Loading Vite config via loader: ", loader);
|
|
423
|
-
const parser = createParser(loader);
|
|
424
|
-
const [result] = await createConfigCoreLoader({
|
|
425
|
-
sources: [{
|
|
426
|
-
files: [`${prefix}.config`],
|
|
427
|
-
extensions: [
|
|
428
|
-
"js",
|
|
429
|
-
"mjs",
|
|
430
|
-
"ts",
|
|
431
|
-
"cjs",
|
|
432
|
-
"mts",
|
|
433
|
-
"mts"
|
|
434
|
-
],
|
|
435
|
-
parser
|
|
436
|
-
}],
|
|
437
|
-
cwd
|
|
438
|
-
}).load(true);
|
|
439
|
-
if (!result) return;
|
|
440
|
-
const { config, source } = result;
|
|
441
|
-
globalLogger.info(`Using Vite config: ${underline(source)}`);
|
|
442
|
-
const resolved = await config;
|
|
443
|
-
if (typeof resolved === "function") return resolved({
|
|
444
|
-
command: "build",
|
|
445
|
-
mode: "production"
|
|
446
|
-
});
|
|
447
|
-
return resolved;
|
|
448
|
-
}
|
|
449
|
-
const configPrefix = "tsdown.config";
|
|
450
|
-
async function loadConfigFile(inlineConfig, workspace) {
|
|
451
|
-
let cwd = inlineConfig.cwd || process.cwd();
|
|
452
|
-
let overrideConfig = false;
|
|
453
|
-
let { config: filePath } = inlineConfig;
|
|
454
|
-
if (filePath === false) return { configs: [{}] };
|
|
455
|
-
if (typeof filePath === "string") {
|
|
456
|
-
const stats = await fsStat(filePath);
|
|
457
|
-
if (stats) {
|
|
458
|
-
const resolved = path.resolve(filePath);
|
|
459
|
-
if (stats.isFile()) {
|
|
460
|
-
overrideConfig = true;
|
|
461
|
-
filePath = resolved;
|
|
462
|
-
cwd = path.dirname(filePath);
|
|
463
|
-
} else if (stats.isDirectory()) cwd = resolved;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
const loader = resolveConfigLoader(inlineConfig.configLoader);
|
|
467
|
-
debug$1("Using config loader:", loader);
|
|
468
|
-
const parser = createParser(loader);
|
|
469
|
-
const [result] = await createConfigCoreLoader({
|
|
470
|
-
sources: overrideConfig ? [{
|
|
471
|
-
files: [filePath],
|
|
472
|
-
extensions: [],
|
|
473
|
-
parser
|
|
474
|
-
}] : [{
|
|
475
|
-
files: [configPrefix],
|
|
476
|
-
extensions: [
|
|
477
|
-
"ts",
|
|
478
|
-
"mts",
|
|
479
|
-
"cts",
|
|
480
|
-
"js",
|
|
481
|
-
"mjs",
|
|
482
|
-
"cjs",
|
|
483
|
-
"json"
|
|
484
|
-
],
|
|
485
|
-
parser
|
|
486
|
-
}, {
|
|
487
|
-
files: ["package.json"],
|
|
488
|
-
parser
|
|
489
|
-
}],
|
|
490
|
-
cwd,
|
|
491
|
-
stopAt: workspace && path.dirname(workspace)
|
|
492
|
-
}).load(true);
|
|
493
|
-
let exported = [];
|
|
494
|
-
let file;
|
|
495
|
-
if (result) {
|
|
496
|
-
({config: exported, source: file} = result);
|
|
497
|
-
globalLogger.info(`config file: ${underline(file)}`, loader === "native" ? "" : `(${loader})`);
|
|
498
|
-
exported = await exported;
|
|
499
|
-
if (typeof exported === "function") exported = await exported(inlineConfig, { ci: is_in_ci_default });
|
|
500
|
-
}
|
|
501
|
-
exported = toArray(exported);
|
|
502
|
-
if (exported.length === 0) exported.push({});
|
|
503
|
-
if (exported.some((config) => typeof config === "function")) throw new Error("Function should not be nested within multiple tsdown configurations. It must be at the top level.\nExample: export default defineConfig(() => [...])");
|
|
504
|
-
return {
|
|
505
|
-
configs: exported.map((config) => ({
|
|
506
|
-
...config,
|
|
507
|
-
cwd: config.cwd ? path.resolve(cwd, config.cwd) : cwd
|
|
508
|
-
})),
|
|
509
|
-
file
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
const isBun = !!process.versions.bun;
|
|
513
|
-
const nativeTS = process.features.typescript || process.versions.deno;
|
|
514
|
-
const autoLoader = isBun || nativeTS && isSupported ? "native" : "unrun";
|
|
515
|
-
function resolveConfigLoader(configLoader = "auto") {
|
|
516
|
-
if (configLoader === "auto") return autoLoader;
|
|
517
|
-
else return configLoader === "native" ? "native" : "unrun";
|
|
518
|
-
}
|
|
519
|
-
function createParser(loader) {
|
|
520
|
-
return async (filepath) => {
|
|
521
|
-
const basename = path.basename(filepath);
|
|
522
|
-
const isPkgJson = basename === "package.json";
|
|
523
|
-
if (basename === configPrefix || isPkgJson || basename.endsWith(".json")) {
|
|
524
|
-
const contents = await readFile(filepath, "utf8");
|
|
525
|
-
const parsed = JSON.parse(contents);
|
|
526
|
-
if (isPkgJson) return parsed?.tsdown;
|
|
527
|
-
return parsed;
|
|
528
|
-
}
|
|
529
|
-
if (loader === "native") return nativeImport(filepath);
|
|
530
|
-
return unrunImport(filepath);
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
async function nativeImport(id) {
|
|
534
|
-
const url = pathToFileURL(id);
|
|
535
|
-
const importAttributes = Object.create(null);
|
|
536
|
-
if (isSupported) {
|
|
537
|
-
importAttributes.cache = "no";
|
|
538
|
-
init({ skipNodeModules: true });
|
|
539
|
-
} else if (!isBun) url.searchParams.set("no-cache", crypto.randomUUID());
|
|
540
|
-
const mod = await import(url.href, { with: importAttributes }).catch((error) => {
|
|
541
|
-
if (error?.message?.includes?.("Cannot find module")) throw new Error(`Failed to load the config file. Try setting the --config-loader CLI flag to \`unrun\`.\n\n${error.message}`, { cause: error });
|
|
542
|
-
else throw error;
|
|
543
|
-
});
|
|
544
|
-
return mod.default || mod;
|
|
545
|
-
}
|
|
546
|
-
async function unrunImport(id) {
|
|
547
|
-
const { unrun } = await import("unrun");
|
|
548
|
-
const { module } = await unrun({ path: pathToFileURL(id).href });
|
|
549
|
-
return module;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
552
|
//#endregion
|
|
553
553
|
//#region src/config/options.ts
|
|
554
554
|
const debug = createDebug("tsdown:config:options");
|
|
@@ -735,4 +735,4 @@ function defineConfig(options) {
|
|
|
735
735
|
}
|
|
736
736
|
|
|
737
737
|
//#endregion
|
|
738
|
-
export {
|
|
738
|
+
export { getPackageType as a, defaultCssBundleName as c, loadConfigFile as d, fsCopy as f, lowestCommonAncestor as h, resolveUserConfig as i, cleanChunks as l, fsRemove as m, mergeConfig as n, writeExports as o, fsExists as p, mergeUserOptions as r, formatBytes as s, defineConfig as t, cleanOutDir as u };
|
package/dist/config.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { f as UserConfig, m as UserConfigFn, p as UserConfigExport } from "./types-
|
|
2
|
-
import { n as mergeConfig, t as defineConfig } from "./config-
|
|
1
|
+
import { f as UserConfig, m as UserConfigFn, p as UserConfigExport } from "./types-Dxm9xngg.mjs";
|
|
2
|
+
import { n as mergeConfig, t as defineConfig } from "./config-Cj-nN1Zu.mjs";
|
|
3
3
|
export { UserConfig, UserConfigExport, UserConfigFn, defineConfig, mergeConfig };
|
package/dist/config.mjs
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { f as resolveComma, h as toArray } from "./logger-C5G3WyAl.mjs";
|
|
2
|
+
import { createDebug, enable, namespaces } from "obug";
|
|
3
|
+
|
|
4
|
+
//#region package.json
|
|
5
|
+
var version = "0.19.0-beta.4";
|
|
6
|
+
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/features/debug.ts
|
|
9
|
+
const debugLog = createDebug("tsdown:debug");
|
|
10
|
+
function enableDebug(debug) {
|
|
11
|
+
if (!debug) return;
|
|
12
|
+
let namespace;
|
|
13
|
+
if (debug === true) namespace = "tsdown:*";
|
|
14
|
+
else namespace = resolveComma(toArray(debug)).map((v) => `tsdown:${v}`).join(",");
|
|
15
|
+
const ns = namespaces();
|
|
16
|
+
if (ns) namespace += `,${ns}`;
|
|
17
|
+
enable(namespace);
|
|
18
|
+
debugLog("Debugging enabled", namespace);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { version as n, enableDebug as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { A as OutExtensionFactory, B as CopyOptions, C as RolldownChunk, D as ChunkAddonFunction, E as ChunkAddon, F as RolldownContext, I as TsdownHooks, L as DevtoolsOptions, M as PackageJsonWithPath, N as PackageType, O as ChunkAddonObject, P as BuildContext, R as CssOptions, S as ExportsOptions, T as AttwOptions, V as CopyOptionsFn, _ as ReportOptions, a as NoExternalFn, b as globalLogger, c as Sourcemap, d as UnusedOptions, f as UserConfig, g as Workspace, h as WithEnabled, i as InlineConfig, j as OutExtensionObject, k as OutExtensionContext, l as TreeshakingOptions, m as UserConfigFn, n as DtsOptions, o as NormalizedFormat, p as UserConfigExport, r as Format, s as ResolvedConfig, t as CIOption, u as TsdownInputOption, w as TsdownBundle, x as PublintOptions, y as Logger, z as CopyEntry } from "./types-
|
|
2
|
-
import {
|
|
1
|
+
import { A as OutExtensionFactory, B as CopyOptions, C as RolldownChunk, D as ChunkAddonFunction, E as ChunkAddon, F as RolldownContext, H as Arrayable, I as TsdownHooks, L as DevtoolsOptions, M as PackageJsonWithPath, N as PackageType, O as ChunkAddonObject, P as BuildContext, R as CssOptions, S as ExportsOptions, T as AttwOptions, V as CopyOptionsFn, _ as ReportOptions, a as NoExternalFn, b as globalLogger, c as Sourcemap, d as UnusedOptions, f as UserConfig, g as Workspace, h as WithEnabled, i as InlineConfig, j as OutExtensionObject, k as OutExtensionContext, l as TreeshakingOptions, m as UserConfigFn, n as DtsOptions, o as NormalizedFormat, p as UserConfigExport, r as Format, s as ResolvedConfig, t as CIOption, u as TsdownInputOption, w as TsdownBundle, x as PublintOptions, y as Logger, z as CopyEntry } from "./types-Dxm9xngg.mjs";
|
|
2
|
+
import { build, buildWithConfigs } from "./build.mjs";
|
|
3
|
+
import { n as mergeConfig, t as defineConfig } from "./config-Cj-nN1Zu.mjs";
|
|
3
4
|
import * as Rolldown from "rolldown";
|
|
4
5
|
|
|
5
|
-
//#region src/
|
|
6
|
-
|
|
7
|
-
* Build with tsdown.
|
|
8
|
-
*/
|
|
9
|
-
declare function build(userOptions?: InlineConfig): Promise<TsdownBundle[]>;
|
|
6
|
+
//#region src/features/debug.d.ts
|
|
7
|
+
declare function enableDebug(debug?: boolean | Arrayable<string>): void;
|
|
10
8
|
//#endregion
|
|
11
|
-
export { AttwOptions, BuildContext, CIOption, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, CssOptions, DevtoolsOptions, DtsOptions, ExportsOptions, Format, InlineConfig, type Logger, NoExternalFn, NormalizedFormat, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageJsonWithPath, PackageType, PublintOptions, ReportOptions, ResolvedConfig, Rolldown, RolldownChunk, RolldownContext, Sourcemap, TreeshakingOptions, TsdownBundle, TsdownHooks, TsdownInputOption, UnusedOptions, UserConfig, UserConfigExport, UserConfigFn, WithEnabled, Workspace, build, defineConfig, globalLogger, mergeConfig };
|
|
9
|
+
export { AttwOptions, BuildContext, CIOption, ChunkAddon, ChunkAddonFunction, ChunkAddonObject, CopyEntry, CopyOptions, CopyOptionsFn, CssOptions, DevtoolsOptions, DtsOptions, ExportsOptions, Format, InlineConfig, type Logger, NoExternalFn, NormalizedFormat, OutExtensionContext, OutExtensionFactory, OutExtensionObject, PackageJsonWithPath, PackageType, PublintOptions, ReportOptions, ResolvedConfig, Rolldown, RolldownChunk, RolldownContext, Sourcemap, TreeshakingOptions, TsdownBundle, TsdownHooks, TsdownInputOption, UnusedOptions, UserConfig, UserConfigExport, UserConfigFn, WithEnabled, Workspace, build, buildWithConfigs, defineConfig, enableDebug, globalLogger, mergeConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { a as globalLogger } from "./logger-
|
|
2
|
-
import { n as mergeConfig, t as defineConfig } from "./config-
|
|
3
|
-
import {
|
|
1
|
+
import { a as globalLogger } from "./logger-C5G3WyAl.mjs";
|
|
2
|
+
import { n as mergeConfig, t as defineConfig } from "./config-DCPo70ac.mjs";
|
|
3
|
+
import { c as Rolldown, l as shimFile, n as buildWithConfigs, t as build } from "./build-CczdykTO.mjs";
|
|
4
|
+
import { t as enableDebug } from "./debug-C60bWO35.mjs";
|
|
4
5
|
|
|
5
|
-
export { Rolldown, build,
|
|
6
|
+
export { Rolldown, build, buildWithConfigs, defineConfig, enableDebug, globalLogger, mergeConfig, shimFile };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
2
|
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import process from "node:process";
|
|
5
4
|
import { bgRed, bgYellow, blue, green, rgb, yellow } from "ansis";
|
|
5
|
+
import process from "node:process";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
const picomatch = __cjs_require("picomatch");
|
|
8
8
|
|
package/dist/plugins.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as ResolvedConfig, v as ReportPlugin, w as TsdownBundle, y as Logger } from "./types-
|
|
1
|
+
import { s as ResolvedConfig, v as ReportPlugin, w as TsdownBundle, y as Logger } from "./types-Dxm9xngg.mjs";
|
|
2
2
|
import { Plugin } from "rolldown";
|
|
3
3
|
|
|
4
4
|
//#region src/features/external.d.ts
|
package/dist/plugins.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as ReportPlugin, i as ShebangPlugin, o as NodeProtocolPlugin, r as WatchPlugin, s as ExternalPlugin } from "./build-CczdykTO.mjs";
|
|
2
2
|
|
|
3
3
|
export { ExternalPlugin, NodeProtocolPlugin, ReportPlugin, ShebangPlugin, WatchPlugin };
|
package/dist/run.mjs
CHANGED
|
@@ -1,29 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as globalLogger
|
|
3
|
-
import {
|
|
2
|
+
import { a as globalLogger } from "./logger-C5G3WyAl.mjs";
|
|
3
|
+
import { n as version, t as enableDebug } from "./debug-C60bWO35.mjs";
|
|
4
4
|
import module from "node:module";
|
|
5
|
-
import process from "node:process";
|
|
6
5
|
import { dim } from "ansis";
|
|
7
|
-
import { createDebug, enable, namespaces } from "obug";
|
|
8
6
|
import { VERSION } from "rolldown";
|
|
7
|
+
import process from "node:process";
|
|
9
8
|
import { x } from "tinyexec";
|
|
10
9
|
import { cac } from "cac";
|
|
11
10
|
|
|
12
|
-
//#region src/features/debug.ts
|
|
13
|
-
const debugLog = createDebug("tsdown:debug");
|
|
14
|
-
function enableDebug(cliOptions) {
|
|
15
|
-
const { debug } = cliOptions;
|
|
16
|
-
if (!debug) return;
|
|
17
|
-
let namespace;
|
|
18
|
-
if (debug === true) namespace = "tsdown:*";
|
|
19
|
-
else namespace = resolveComma(toArray(debug)).map((v) => `tsdown:${v}`).join(",");
|
|
20
|
-
const ns = namespaces();
|
|
21
|
-
if (ns) namespace += `,${ns}`;
|
|
22
|
-
enable(namespace);
|
|
23
|
-
debugLog("Debugging enabled", namespace);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
//#endregion
|
|
27
11
|
//#region src/cli.ts
|
|
28
12
|
const cli = cac("tsdown");
|
|
29
13
|
cli.help().version(version);
|
|
@@ -33,7 +17,7 @@ cli.command("[...files]", "Bundle files", {
|
|
|
33
17
|
}).option("-c, --config <filename>", "Use a custom config file").option("--config-loader <loader>", "Config loader to use: auto, native, unrun", { default: "auto" }).option("--no-config", "Disable config file").option("-f, --format <format>", "Bundle format: esm, cjs, iife, umd", { default: "esm" }).option("--clean", "Clean output directory, --no-clean to disable").option("--external <module>", "Mark dependencies as external").option("--minify", "Minify output").option("--devtools", "Enable devtools integration").option("--debug [feat]", "Show debug logs").option("--target <target>", "Bundle target, e.g \"es2015\", \"esnext\"").option("-l, --logLevel <level>", "Set log level: info, warn, error, silent").option("--fail-on-warn", "Fail on warnings", { default: true }).option("--no-write", "Disable writing files to disk, incompatible with watch mode").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("--dts", "Generate dts files").option("--publint", "Enable publint", { default: false }).option("--attw", "Enable Are the types wrong integration", { default: false }).option("--unused", "Enable unused dependencies check", { default: false }).option("-w, --watch [path]", "Watch mode").option("--ignore-watch <path>", "Ignore custom paths in watch mode").option("--from-vite [vitest]", "Reuse config from Vite or Vitest").option("--report", "Size report", { default: true }).option("--env.* <value>", "Define compile-time env variables").option("--env-file <file>", "Load environment variables from a file, when used together with --env, variables in --env take precedence").option("--env-prefix <prefix>", "Prefix for env variables to inject into the bundle", { default: "TSDOWN_" }).option("--on-success <command>", "Command to run on success").option("--copy <dir>", "Copy files to output dir").option("--public-dir <dir>", "Alias for --copy, deprecated").option("--tsconfig <tsconfig>", "Set tsconfig path").option("--unbundle", "Unbundle mode").option("-W, --workspace [dir]", "Enable workspace mode").option("-F, --filter <pattern>", "Filter configs (cwd or name), e.g. /pkg-name$/ or pkg-name").option("--exports", "Generate export-related metadata for package.json (experimental)").action(async (input, flags) => {
|
|
34
18
|
globalLogger.level = flags.logLevel || "info";
|
|
35
19
|
globalLogger.info(`tsdown ${dim`v${version}`} powered by rolldown ${dim`v${VERSION}`}`);
|
|
36
|
-
const { build: build$1 } = await import("./
|
|
20
|
+
const { build: build$1 } = await import("./build.mjs");
|
|
37
21
|
if (input.length > 0) flags.entry = input;
|
|
38
22
|
await build$1(flags);
|
|
39
23
|
});
|
|
@@ -57,7 +41,7 @@ cli.command("migrate", "[deprecated] Migrate from tsup to tsdown. Use \"npx tsdo
|
|
|
57
41
|
});
|
|
58
42
|
async function runCLI() {
|
|
59
43
|
cli.parse(process.argv, { run: false });
|
|
60
|
-
enableDebug(cli.options);
|
|
44
|
+
enableDebug(cli.options.debug);
|
|
61
45
|
try {
|
|
62
46
|
await cli.runMatchedCommand();
|
|
63
47
|
} catch (error) {
|
|
@@ -1018,4 +1018,4 @@ type ResolvedConfig = Overwrite<MarkPartial<Omit<UserConfig, "workspace" | "from
|
|
|
1018
1018
|
unused: false | UnusedOptions;
|
|
1019
1019
|
}>;
|
|
1020
1020
|
//#endregion
|
|
1021
|
-
export { OutExtensionFactory as A, CopyOptions as B, RolldownChunk as C, ChunkAddonFunction as D, ChunkAddon as E, RolldownContext as F, TsdownHooks as I, DevtoolsOptions as L, PackageJsonWithPath as M, PackageType as N, ChunkAddonObject as O, BuildContext as P, CssOptions as R, ExportsOptions as S, AttwOptions as T, CopyOptionsFn as V, ReportOptions as _, NoExternalFn as a, globalLogger as b, Sourcemap as c, UnusedOptions as d, UserConfig as f, Workspace as g, WithEnabled as h, InlineConfig as i, OutExtensionObject as j, OutExtensionContext as k, TreeshakingOptions as l, UserConfigFn as m, DtsOptions as n, NormalizedFormat as o, UserConfigExport as p, Format as r, ResolvedConfig as s, CIOption as t, TsdownInputOption as u, ReportPlugin as v, TsdownBundle as w, PublintOptions as x, Logger as y, CopyEntry as z };
|
|
1021
|
+
export { OutExtensionFactory as A, CopyOptions as B, RolldownChunk as C, ChunkAddonFunction as D, ChunkAddon as E, RolldownContext as F, Arrayable as H, TsdownHooks as I, DevtoolsOptions as L, PackageJsonWithPath as M, PackageType as N, ChunkAddonObject as O, BuildContext as P, CssOptions as R, ExportsOptions as S, AttwOptions as T, CopyOptionsFn as V, ReportOptions as _, NoExternalFn as a, globalLogger as b, Sourcemap as c, UnusedOptions as d, UserConfig as f, Workspace as g, WithEnabled as h, InlineConfig as i, OutExtensionObject as j, OutExtensionContext as k, TreeshakingOptions as l, UserConfigFn as m, DtsOptions as n, NormalizedFormat as o, UserConfigExport as p, Format as r, ResolvedConfig as s, CIOption as t, TsdownInputOption as u, ReportPlugin as v, TsdownBundle as w, PublintOptions as x, Logger as y, CopyEntry as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsdown",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.19.0-beta.
|
|
4
|
+
"version": "0.19.0-beta.4",
|
|
5
5
|
"description": "The Elegant Bundler for Libraries",
|
|
6
6
|
"author": "Kevin Deng <sxzz@sxzz.moe>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"exports": {
|
|
18
18
|
".": "./dist/index.mjs",
|
|
19
|
+
"./build": "./dist/build.mjs",
|
|
19
20
|
"./config": "./dist/config.mjs",
|
|
20
21
|
"./plugins": "./dist/plugins.mjs",
|
|
21
22
|
"./run": "./dist/run.mjs",
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"@types/node": "^25.0.3",
|
|
100
101
|
"@types/picomatch": "^4.0.2",
|
|
101
102
|
"@types/semver": "^7.7.1",
|
|
102
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
103
|
+
"@typescript/native-preview": "7.0.0-dev.20260107.1",
|
|
103
104
|
"@unocss/eslint-plugin": "^66.5.12",
|
|
104
105
|
"@vitejs/devtools": "^0.0.0-alpha.22",
|
|
105
106
|
"@vitest/coverage-v8": "4.0.16",
|