@fastkit/plugboy 0.2.7 → 1.0.0-next.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 +355 -0
- package/dist/cli.d.mts +5 -0
- package/dist/cli.mjs +33 -128
- package/dist/cli.mjs.map +1 -1
- package/dist/combine-rules-CWp-M491.mjs +66 -0
- package/dist/combine-rules-CWp-M491.mjs.map +1 -0
- package/dist/dependencies/bundle-require.d.mts +1 -0
- package/dist/dependencies/bundle-require.mjs +3 -3
- package/dist/dependencies/cac.d.mts +1 -0
- package/dist/dependencies/cac.mjs +3 -3
- package/dist/dependencies/glob.d.mts +1 -0
- package/dist/dependencies/glob.mjs +3 -3
- package/dist/dependencies/inquirer.d.mts +1 -0
- package/dist/dependencies/inquirer.mjs +3 -3
- package/dist/dependencies/pkg-types.d.mts +1 -0
- package/dist/dependencies/pkg-types.mjs +3 -3
- package/dist/dependencies/sort-package-json.d.mts +2 -0
- package/dist/dependencies/sort-package-json.mjs +5 -4
- package/dist/dependencies/sort-package-json.mjs.map +1 -1
- package/dist/dependencies/tsdown.d.mts +1 -0
- package/dist/dependencies/tsdown.mjs +3 -0
- package/dist/optimize-layer-CK8NR_VC.mjs +58 -0
- package/dist/optimize-layer-CK8NR_VC.mjs.map +1 -0
- package/dist/optimize-media-Bxy27Cj7.mjs +86 -0
- package/dist/optimize-media-Bxy27Cj7.mjs.map +1 -0
- package/dist/plugboy.d.mts +6284 -0
- package/dist/plugboy.mjs +3 -103
- package/dist/runtime-utils.d.mts +28 -0
- package/dist/runtime-utils.mjs +94 -0
- package/dist/runtime-utils.mjs.map +1 -0
- package/dist/workspace-BqcryYAT.mjs +1391 -0
- package/dist/workspace-BqcryYAT.mjs.map +1 -0
- package/env.d.ts +0 -18
- package/package.json +21 -17
- package/dist/chunk-MN572VU2.mjs +0 -1616
- package/dist/chunk-MN572VU2.mjs.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/combine-rules-2CRG6D4B.mjs +0 -69
- package/dist/combine-rules-2CRG6D4B.mjs.map +0 -1
- package/dist/dependencies/bundle-require.d.ts +0 -7
- package/dist/dependencies/bundle-require.mjs.map +0 -1
- package/dist/dependencies/cac.d.ts +0 -1
- package/dist/dependencies/cac.mjs.map +0 -1
- package/dist/dependencies/esbuild.d.ts +0 -1
- package/dist/dependencies/esbuild.mjs +0 -3
- package/dist/dependencies/esbuild.mjs.map +0 -1
- package/dist/dependencies/glob.d.ts +0 -1
- package/dist/dependencies/glob.mjs.map +0 -1
- package/dist/dependencies/inquirer.d.ts +0 -1
- package/dist/dependencies/inquirer.mjs.map +0 -1
- package/dist/dependencies/pkg-types.d.ts +0 -1
- package/dist/dependencies/pkg-types.mjs.map +0 -1
- package/dist/dependencies/sort-package-json.d.ts +0 -2
- package/dist/dependencies/tsup.d.ts +0 -1
- package/dist/dependencies/tsup.mjs +0 -3
- package/dist/dependencies/tsup.mjs.map +0 -1
- package/dist/optimize-layer-Q35C25P4.mjs +0 -61
- package/dist/optimize-layer-Q35C25P4.mjs.map +0 -1
- package/dist/optimize-media-ZZWDHLLV.mjs +0 -99
- package/dist/optimize-media-ZZWDHLLV.mjs.map +0 -1
- package/dist/plugboy.d.ts +0 -777
- package/dist/plugboy.mjs.map +0 -1
|
@@ -0,0 +1,1391 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { glob } from "glob";
|
|
5
|
+
import { bundleRequire } from "bundle-require";
|
|
6
|
+
import fs$1 from "node:fs/promises";
|
|
7
|
+
import { build } from "tsdown";
|
|
8
|
+
import { execa } from "execa";
|
|
9
|
+
import { parse } from "acorn";
|
|
10
|
+
import sortPackageJson from "sort-package-json";
|
|
11
|
+
import * as prompts from "@inquirer/prompts";
|
|
12
|
+
|
|
13
|
+
//#region src/types/hook.ts
|
|
14
|
+
function createHooksDefaults() {
|
|
15
|
+
return {
|
|
16
|
+
setupWorkspace: [],
|
|
17
|
+
createWorkspace: [],
|
|
18
|
+
preparePackageJSON: []
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/types/dts.ts
|
|
24
|
+
function normalizeDTSPreserveTypeTarget(target) {
|
|
25
|
+
const { from, typeName } = target;
|
|
26
|
+
return {
|
|
27
|
+
from: typeof from === "string" ? new RegExp(`${from}`, "g") : from,
|
|
28
|
+
typeName
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function normalizeDTSPreserveTypeSettings(settings) {
|
|
32
|
+
return {
|
|
33
|
+
...settings,
|
|
34
|
+
targets: settings.targets.map(normalizeDTSPreserveTypeTarget)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function normalizeDTSSettings(settings) {
|
|
38
|
+
const { inline = false, compiler = "tsc", ignoreCompilerErrors = false, preserveType = [], normalizers = [] } = settings || {};
|
|
39
|
+
return {
|
|
40
|
+
inline,
|
|
41
|
+
compiler,
|
|
42
|
+
ignoreCompilerErrors,
|
|
43
|
+
preserveType: preserveType.map(normalizeDTSPreserveTypeSettings),
|
|
44
|
+
normalizers
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function mergeDTSSettingsList(...settingsList) {
|
|
48
|
+
const merged = {};
|
|
49
|
+
settingsList.forEach((settings) => {
|
|
50
|
+
if (!settings) return;
|
|
51
|
+
const { inline, preserveType, normalizers } = settings;
|
|
52
|
+
if (inline !== void 0) merged.inline = inline;
|
|
53
|
+
if (preserveType) {
|
|
54
|
+
merged.preserveType = merged.preserveType || [];
|
|
55
|
+
merged.preserveType.push(...preserveType);
|
|
56
|
+
}
|
|
57
|
+
if (normalizers) {
|
|
58
|
+
merged.normalizers = merged.normalizers || [];
|
|
59
|
+
merged.normalizers.push(...normalizers);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return normalizeDTSSettings(merged);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/types/css.ts
|
|
67
|
+
function resolveOptimizeCSSOptions(options) {
|
|
68
|
+
const resolved = {};
|
|
69
|
+
const { layer = true, media = true, combineRules, cssnano = true } = options;
|
|
70
|
+
if (layer !== false) resolved.layer = layer === true ? {} : layer;
|
|
71
|
+
if (media !== false) resolved.media = media === true ? {} : media;
|
|
72
|
+
if (combineRules) resolved.combineRules = combineRules;
|
|
73
|
+
if (cssnano !== false) resolved.cssnano = cssnano === true ? { preset: ["default", { normalizeWhitespace: false }] } : cssnano;
|
|
74
|
+
return resolved;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/types/workspace.ts
|
|
79
|
+
const WORKSPACE_REQUIRED_FIELDS = ["name", "version"];
|
|
80
|
+
const TSDOWN_SYNC_OPTIONS = [
|
|
81
|
+
"define",
|
|
82
|
+
"noExternal",
|
|
83
|
+
"external",
|
|
84
|
+
"skipNodeModulesBundle",
|
|
85
|
+
"onSuccess",
|
|
86
|
+
"copy"
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/types/project.ts
|
|
91
|
+
const PROJECT_REQUIRED_FIELDS = ["name"];
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/utils/general.ts
|
|
95
|
+
function isPromise(obj) {
|
|
96
|
+
return !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
|
|
97
|
+
}
|
|
98
|
+
async function resolveListable(raw) {
|
|
99
|
+
const result = [];
|
|
100
|
+
const list = Array.isArray(raw) ? raw : [raw];
|
|
101
|
+
for (let row of list) {
|
|
102
|
+
if (isPromise(row)) row = await row;
|
|
103
|
+
if (!row) continue;
|
|
104
|
+
if (Array.isArray(row)) {
|
|
105
|
+
result.push(...await resolveListable(row));
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
result.push(row);
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/utils/tsdown.ts
|
|
115
|
+
const _stringChunkToObject = (source) => {
|
|
116
|
+
if (typeof source === "object") return source;
|
|
117
|
+
return {
|
|
118
|
+
js: source,
|
|
119
|
+
dts: source,
|
|
120
|
+
css: source
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
const _resolveChunkAddonToObject = (source, ...args) => {
|
|
124
|
+
return _stringChunkToObject(typeof source === "function" ? source(...args) || {} : source);
|
|
125
|
+
};
|
|
126
|
+
const _mergeChunkAddonObjects = (base, override, position = "after") => {
|
|
127
|
+
const result = { ..._stringChunkToObject(base) };
|
|
128
|
+
for (const [_key, value] of Object.entries(_stringChunkToObject(override))) {
|
|
129
|
+
if (!value) continue;
|
|
130
|
+
const key = _key;
|
|
131
|
+
const baseValue = result[key];
|
|
132
|
+
const chunks = [value];
|
|
133
|
+
if (baseValue) if (position === "before") chunks.push(baseValue);
|
|
134
|
+
else chunks.unshift(baseValue);
|
|
135
|
+
result[key] = chunks.join("\n\n");
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
};
|
|
139
|
+
function mergeChunkAddons(base, override, position) {
|
|
140
|
+
if (!override) return base;
|
|
141
|
+
if (!base) return override;
|
|
142
|
+
if (typeof base === "function" || typeof override === "function") return (...args) => {
|
|
143
|
+
return _mergeChunkAddonObjects(_resolveChunkAddonToObject(base, ...args), _resolveChunkAddonToObject(override, ...args), position);
|
|
144
|
+
};
|
|
145
|
+
return _mergeChunkAddonObjects(base, override);
|
|
146
|
+
}
|
|
147
|
+
function isExternal(externalOption, id, parentId, isResolved) {
|
|
148
|
+
if (Array.isArray(externalOption)) return externalOption.some((e) => isExternal(e, id, parentId, isResolved));
|
|
149
|
+
if (typeof externalOption === "string") return id === externalOption;
|
|
150
|
+
if (externalOption instanceof RegExp) return externalOption.test(id);
|
|
151
|
+
if (typeof externalOption === "function") return externalOption(id, parentId, isResolved);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
function mergeExternals(base, override) {
|
|
155
|
+
if (!override) return base;
|
|
156
|
+
if (!base) return override;
|
|
157
|
+
const externals = [base, override];
|
|
158
|
+
return (id, parentId, isResolved) => {
|
|
159
|
+
return externals.some((external) => {
|
|
160
|
+
return isExternal(external, id, parentId, isResolved);
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function isNoExternal(noExternalOption, id, importer) {
|
|
165
|
+
if (Array.isArray(noExternalOption)) return noExternalOption.some((e) => isNoExternal(e, id, importer));
|
|
166
|
+
if (typeof noExternalOption === "string") return id === noExternalOption;
|
|
167
|
+
if (noExternalOption instanceof RegExp) return noExternalOption.test(id);
|
|
168
|
+
if (typeof noExternalOption === "function") return noExternalOption(id, importer);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
function mergeNoExternals(base, override) {
|
|
172
|
+
if (!override) return base;
|
|
173
|
+
if (!base) return override;
|
|
174
|
+
if (typeof base !== "function" && typeof override !== "function") {
|
|
175
|
+
const _base = Array.isArray(base) ? base.slice() : [base];
|
|
176
|
+
const _override = Array.isArray(override) ? override.slice() : [override];
|
|
177
|
+
return [..._base, ..._override];
|
|
178
|
+
}
|
|
179
|
+
const noExternals = [base, override];
|
|
180
|
+
return (id, importer) => {
|
|
181
|
+
return noExternals.some((spec) => {
|
|
182
|
+
return isNoExternal(spec, id, importer);
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//#endregion
|
|
188
|
+
//#region src/utils/exit-hook.ts
|
|
189
|
+
const EXIT_SIGNALS = [
|
|
190
|
+
"SIGINT",
|
|
191
|
+
"SIGTERM",
|
|
192
|
+
"SIGHUP"
|
|
193
|
+
];
|
|
194
|
+
const _callbacks = [];
|
|
195
|
+
function exitHook(cb) {
|
|
196
|
+
_callbacks.push(cb);
|
|
197
|
+
const off = () => {
|
|
198
|
+
const index = _callbacks.indexOf(cb);
|
|
199
|
+
if (index !== -1) _callbacks.splice(index, 1);
|
|
200
|
+
};
|
|
201
|
+
return off;
|
|
202
|
+
}
|
|
203
|
+
for (const signal of EXIT_SIGNALS) process.on(signal, async () => {
|
|
204
|
+
const callbacks = _callbacks.slice();
|
|
205
|
+
_callbacks.length = 0;
|
|
206
|
+
try {
|
|
207
|
+
await Promise.all(callbacks.map((cb) => cb()));
|
|
208
|
+
process.exit(0);
|
|
209
|
+
} catch (_err) {
|
|
210
|
+
console.error(_err);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region src/utils/file.ts
|
|
217
|
+
function getFilename(importMetaURL) {
|
|
218
|
+
return fileURLToPath(importMetaURL);
|
|
219
|
+
}
|
|
220
|
+
function getDirname(importMetaURL) {
|
|
221
|
+
return path.dirname(getFilename(importMetaURL));
|
|
222
|
+
}
|
|
223
|
+
const FILE_NOT_FOUND_EXCEPTION_CODES = ["ENOTDIR", "ENOENT"];
|
|
224
|
+
function isFileNotFoundException(source) {
|
|
225
|
+
return !!source && typeof source === "object" && FILE_NOT_FOUND_EXCEPTION_CODES.includes(source.code);
|
|
226
|
+
}
|
|
227
|
+
async function pathExists(target, type) {
|
|
228
|
+
try {
|
|
229
|
+
const stats = await fs.promises.stat(target);
|
|
230
|
+
if (!type) return true;
|
|
231
|
+
return type === "file" ? stats.isFile() : stats.isDirectory();
|
|
232
|
+
} catch (err) {
|
|
233
|
+
if (isFileNotFoundException(err)) return false;
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function normalizeFileMatcher(matcher) {
|
|
238
|
+
if (typeof matcher === "function") return matcher;
|
|
239
|
+
if (typeof matcher === "string") return (file) => file.name.includes(matcher);
|
|
240
|
+
return (file) => matcher.test(file.name);
|
|
241
|
+
}
|
|
242
|
+
async function findFile(dir, matcher, recursive = true) {
|
|
243
|
+
const files = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
244
|
+
const _matcher = normalizeFileMatcher(matcher);
|
|
245
|
+
const dirs = recursive ? [] : void 0;
|
|
246
|
+
for (const file of files) {
|
|
247
|
+
if (dirs && file.isDirectory()) {
|
|
248
|
+
dirs.push(file);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (await _matcher(file, dir)) return path.join(dir, file.name);
|
|
252
|
+
}
|
|
253
|
+
if (dirs) for (const subDir of dirs) {
|
|
254
|
+
const hit = await findFile(path.join(dir, subDir.name), _matcher, recursive);
|
|
255
|
+
if (hit) return hit;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const FIND_CONFIG_OR_RE = /\(.+?\)/g;
|
|
259
|
+
function parseFindConfigFileName(source) {
|
|
260
|
+
const matches = source.match(FIND_CONFIG_OR_RE);
|
|
261
|
+
if (!matches) return [source];
|
|
262
|
+
return matches.map((matched) => {
|
|
263
|
+
return matched.slice(1, matched.length - 1).split("|").map((part) => {
|
|
264
|
+
return parseFindConfigFileName(source.replace(matched, part));
|
|
265
|
+
}).flat();
|
|
266
|
+
}).flat();
|
|
267
|
+
}
|
|
268
|
+
function parseRawFindConfigFileName(source) {
|
|
269
|
+
return Array.isArray(source) ? source.map(parseFindConfigFileName).flat() : parseFindConfigFileName(source);
|
|
270
|
+
}
|
|
271
|
+
async function findConfig(fileNameOrSettings, dir = process.cwd(), currentDepth = 0) {
|
|
272
|
+
const settings = typeof fileNameOrSettings === "object" && !Array.isArray(fileNameOrSettings) ? fileNameOrSettings : { fileName: fileNameOrSettings };
|
|
273
|
+
const { fileName, test, depth = 10, allowMissing } = settings;
|
|
274
|
+
const fileNames = parseRawFindConfigFileName(fileName);
|
|
275
|
+
if (depth && currentDepth === depth) {
|
|
276
|
+
if (allowMissing) return null;
|
|
277
|
+
throw new Error(`Failed to retrieve the "${fileName}" file because the maximum depth was reached.`);
|
|
278
|
+
}
|
|
279
|
+
const next = (err) => {
|
|
280
|
+
const nextDir = path.dirname(dir);
|
|
281
|
+
if (nextDir !== dir) return findConfig(settings, nextDir, currentDepth + 1);
|
|
282
|
+
if (allowMissing) return null;
|
|
283
|
+
throw err || /* @__PURE__ */ new Error(`missing config "${fileName}"`);
|
|
284
|
+
};
|
|
285
|
+
const result = await (async () => {
|
|
286
|
+
for (const fileName of fileNames) try {
|
|
287
|
+
const _path = path.join(dir, fileName);
|
|
288
|
+
const _result = {
|
|
289
|
+
fileName,
|
|
290
|
+
dir,
|
|
291
|
+
path: _path,
|
|
292
|
+
code: await fs.promises.readFile(_path, "utf-8")
|
|
293
|
+
};
|
|
294
|
+
if (!test || test(_result)) return _result;
|
|
295
|
+
} catch (err) {
|
|
296
|
+
if (!isFileNotFoundException(err)) throw err;
|
|
297
|
+
}
|
|
298
|
+
})();
|
|
299
|
+
if (!result) return next();
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
function _rmrf(_path) {
|
|
303
|
+
return fs.promises.rm(_path, {
|
|
304
|
+
recursive: true,
|
|
305
|
+
force: true
|
|
306
|
+
}).catch((err) => {
|
|
307
|
+
if (isFileNotFoundException(err)) return;
|
|
308
|
+
throw err;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
async function rmrf(...paths) {
|
|
312
|
+
await Promise.all(paths.map((_path) => _rmrf(_path)));
|
|
313
|
+
}
|
|
314
|
+
function copyDirSync(srcDir, destDir) {
|
|
315
|
+
if (!fs.existsSync(srcDir)) return;
|
|
316
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
317
|
+
for (const file of fs.readdirSync(srcDir)) {
|
|
318
|
+
const srcFile = path.resolve(srcDir, file);
|
|
319
|
+
if (srcFile === destDir) continue;
|
|
320
|
+
const destFile = path.resolve(destDir, file);
|
|
321
|
+
if (fs.statSync(srcFile).isDirectory()) copyDirSync(srcFile, destFile);
|
|
322
|
+
else fs.copyFileSync(srcFile, destFile);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async function writeFileAtomic(filePath, content) {
|
|
326
|
+
const tempFile = `${filePath}.${process.pid}.tmp`;
|
|
327
|
+
const cleanup = () => {
|
|
328
|
+
return fs.promises.unlink(tempFile).catch(() => {});
|
|
329
|
+
};
|
|
330
|
+
const off = exitHook(cleanup);
|
|
331
|
+
try {
|
|
332
|
+
await fs.promises.writeFile(tempFile, content);
|
|
333
|
+
await fs.promises.rename(tempFile, filePath);
|
|
334
|
+
off();
|
|
335
|
+
} catch (error) {
|
|
336
|
+
off();
|
|
337
|
+
await cleanup();
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/utils/expose.ts
|
|
344
|
+
function resolveRawExposeEntriesSettings(rawSettings) {
|
|
345
|
+
return typeof rawSettings === "string" ? { dir: rawSettings } : rawSettings;
|
|
346
|
+
}
|
|
347
|
+
const TRIM_PATH_RE = /(^\.?\/|\/$)/g;
|
|
348
|
+
const TRIM_EXT_RE = /\.ts$/;
|
|
349
|
+
async function exposeEntries(rawSettings) {
|
|
350
|
+
const { dir: _dir, prefix: _prefix } = resolveRawExposeEntriesSettings(rawSettings);
|
|
351
|
+
const dir = path.resolve(_dir);
|
|
352
|
+
const prefix = _prefix ? _prefix.replace(TRIM_PATH_RE, "") : "";
|
|
353
|
+
const files = await glob(path.join(dir, "**/*.ts"));
|
|
354
|
+
const entries = {};
|
|
355
|
+
for (const file of files) {
|
|
356
|
+
const id = (prefix + file.replace(dir, "")).replace(TRIM_EXT_RE, "").replace(TRIM_PATH_RE, "");
|
|
357
|
+
entries[id] = { src: file };
|
|
358
|
+
}
|
|
359
|
+
return entries;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
//#endregion
|
|
363
|
+
//#region src/constants.ts
|
|
364
|
+
const PROJECT_CONFIG_BASENAME = "plugboy.project";
|
|
365
|
+
const WORKSPACE_CONFIG_BASENAME = "plugboy.workspace";
|
|
366
|
+
const PACKAGE_JSON_FILENAME = "package.json";
|
|
367
|
+
const WORKSPACE_SPEC_PREFIX = "workspace:";
|
|
368
|
+
const SEARCH_BUNDLE_EXTENSIONS_MATCH = "(ts|mjs|js|json)";
|
|
369
|
+
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region src/utils/project.ts
|
|
372
|
+
function isProjectPackageJson(json) {
|
|
373
|
+
return !!json.private && PROJECT_REQUIRED_FIELDS.every((filed) => !!json[filed]);
|
|
374
|
+
}
|
|
375
|
+
async function resolveUserProjectConfig(userConfig) {
|
|
376
|
+
const { workspacesDir = "packages", scripts = [], peerDependencies = {}, tsconfig, readme = (json) => `# ${json.name}\n`, plugins, optimizeCSS = true, hooks } = userConfig;
|
|
377
|
+
return {
|
|
378
|
+
workspacesDir,
|
|
379
|
+
scripts: Array.isArray(scripts) ? scripts : [{
|
|
380
|
+
name: "",
|
|
381
|
+
scripts
|
|
382
|
+
}],
|
|
383
|
+
peerDependencies,
|
|
384
|
+
tsconfig,
|
|
385
|
+
readme,
|
|
386
|
+
plugins: await resolveUserPluginOption(plugins),
|
|
387
|
+
optimizeCSS: optimizeCSS === true ? {} : optimizeCSS,
|
|
388
|
+
hooks
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function defineProjectConfig(config) {
|
|
392
|
+
return resolveUserProjectConfig(config);
|
|
393
|
+
}
|
|
394
|
+
async function loadProjectConfig(searchDir, depth) {
|
|
395
|
+
const hit = await findConfig({
|
|
396
|
+
fileName: `${PROJECT_CONFIG_BASENAME}.${SEARCH_BUNDLE_EXTENSIONS_MATCH}`,
|
|
397
|
+
depth,
|
|
398
|
+
allowMissing: true
|
|
399
|
+
}, searchDir);
|
|
400
|
+
return resolveUserProjectConfig(await (hit ? (await bundleRequire({ filepath: hit.path })).mod.default : {}));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
//#endregion
|
|
404
|
+
//#region src/utils/plugin.ts
|
|
405
|
+
async function resolveUserPluginOption(pluginOption) {
|
|
406
|
+
if (!pluginOption) return [];
|
|
407
|
+
const awaited = await pluginOption;
|
|
408
|
+
if (!awaited) return [];
|
|
409
|
+
if (Array.isArray(pluginOption)) return (await Promise.all(pluginOption.map((o) => resolveUserPluginOption(o)).flat())).flat();
|
|
410
|
+
return [awaited];
|
|
411
|
+
}
|
|
412
|
+
function definePlugin(options) {
|
|
413
|
+
return options;
|
|
414
|
+
}
|
|
415
|
+
async function extractProjectPlugins(searchDir) {
|
|
416
|
+
const config = await loadProjectConfig(searchDir);
|
|
417
|
+
return config ? config.plugins : [];
|
|
418
|
+
}
|
|
419
|
+
async function findProjectPlugin(pluginName, searchDir) {
|
|
420
|
+
return (await extractProjectPlugins(searchDir)).find((plugin) => plugin.name === pluginName);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/utils/workspace.ts
|
|
425
|
+
function isWorkspacePackageJson(json) {
|
|
426
|
+
return !json.private && WORKSPACE_REQUIRED_FIELDS.every((filed) => !!json[filed]);
|
|
427
|
+
}
|
|
428
|
+
function resolveRawWorkspaceEntry(entry) {
|
|
429
|
+
const { src, css } = typeof entry === "string" ? { src: entry } : entry;
|
|
430
|
+
return {
|
|
431
|
+
src,
|
|
432
|
+
css: css || src.endsWith(".css") || src.endsWith(".scss")
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function resolveRawWorkspaceEntries(entries) {
|
|
436
|
+
if (!entries) return {};
|
|
437
|
+
return Object.fromEntries(Object.entries(entries).map(([name, raw]) => [name, resolveRawWorkspaceEntry(raw)]));
|
|
438
|
+
}
|
|
439
|
+
async function resolveUserWorkspaceConfig(userConfig) {
|
|
440
|
+
const { ignoreProjectConfig = false, entries, plugins, optimizeCSS = true, hooks } = userConfig;
|
|
441
|
+
return {
|
|
442
|
+
...userConfig,
|
|
443
|
+
ignoreProjectConfig,
|
|
444
|
+
entries: resolveRawWorkspaceEntries(entries),
|
|
445
|
+
plugins: await resolveUserPluginOption(plugins),
|
|
446
|
+
optimizeCSS: optimizeCSS === true ? {} : optimizeCSS,
|
|
447
|
+
hooks
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function defineWorkspaceConfig(config) {
|
|
451
|
+
return resolveUserWorkspaceConfig(config);
|
|
452
|
+
}
|
|
453
|
+
async function loadWorkspaceConfig(searchDir, depth) {
|
|
454
|
+
const hit = await findConfig({
|
|
455
|
+
fileName: `${WORKSPACE_CONFIG_BASENAME}.${SEARCH_BUNDLE_EXTENSIONS_MATCH}`,
|
|
456
|
+
depth,
|
|
457
|
+
allowMissing: true
|
|
458
|
+
}, searchDir);
|
|
459
|
+
return resolveUserWorkspaceConfig(await (hit ? (await bundleRequire({ filepath: hit.path })).mod.default : {}));
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region src/utils/hook.ts
|
|
464
|
+
async function resolveUserHooks(...userHooks) {
|
|
465
|
+
const hooks = createHooksDefaults();
|
|
466
|
+
if (!userHooks) return hooks;
|
|
467
|
+
for (const userHook of userHooks) {
|
|
468
|
+
if (!userHook) continue;
|
|
469
|
+
for (const [hookName, _hooks] of Object.entries(userHook)) if (hooks) hooks[hookName].push(...await resolveListable(_hooks));
|
|
470
|
+
}
|
|
471
|
+
return hooks;
|
|
472
|
+
}
|
|
473
|
+
function buildHooks(resolvedHooks) {
|
|
474
|
+
const hooks = {};
|
|
475
|
+
Object.entries(resolvedHooks).forEach(([hookName, fns]) => {
|
|
476
|
+
hooks[hookName] = async (...args) => {
|
|
477
|
+
const results = [];
|
|
478
|
+
for (const fn of fns) results.push(await fn(...args));
|
|
479
|
+
return results;
|
|
480
|
+
};
|
|
481
|
+
});
|
|
482
|
+
return hooks;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
//#endregion
|
|
486
|
+
//#region src/path.ts
|
|
487
|
+
var Path = class Path {
|
|
488
|
+
_value;
|
|
489
|
+
_stats;
|
|
490
|
+
get value() {
|
|
491
|
+
return this._value;
|
|
492
|
+
}
|
|
493
|
+
set value(value) {
|
|
494
|
+
if (path.resolve(value) === this._value) return;
|
|
495
|
+
this._value = path.resolve(value);
|
|
496
|
+
delete this._stats;
|
|
497
|
+
}
|
|
498
|
+
get dirname() {
|
|
499
|
+
return path.dirname(this.value);
|
|
500
|
+
}
|
|
501
|
+
get basename() {
|
|
502
|
+
return path.basename(this.value);
|
|
503
|
+
}
|
|
504
|
+
get extname() {
|
|
505
|
+
return path.extname(this.value);
|
|
506
|
+
}
|
|
507
|
+
get stats() {
|
|
508
|
+
let { _stats } = this;
|
|
509
|
+
if (!_stats) {
|
|
510
|
+
_stats = fs.statSync(this.value);
|
|
511
|
+
this._stats = _stats;
|
|
512
|
+
}
|
|
513
|
+
return _stats;
|
|
514
|
+
}
|
|
515
|
+
get isDirectory() {
|
|
516
|
+
return this.stats.isDirectory;
|
|
517
|
+
}
|
|
518
|
+
get isFile() {
|
|
519
|
+
return this.stats.isFile;
|
|
520
|
+
}
|
|
521
|
+
constructor(value) {
|
|
522
|
+
this._value = path.resolve(value);
|
|
523
|
+
}
|
|
524
|
+
toString() {
|
|
525
|
+
return this.value;
|
|
526
|
+
}
|
|
527
|
+
valueOf() {
|
|
528
|
+
return this.value;
|
|
529
|
+
}
|
|
530
|
+
toJSON() {
|
|
531
|
+
return this.value;
|
|
532
|
+
}
|
|
533
|
+
relative(to) {
|
|
534
|
+
return new Path(path.relative(this.value, to));
|
|
535
|
+
}
|
|
536
|
+
join(...paths) {
|
|
537
|
+
return new Path(path.join(this.value, ...paths));
|
|
538
|
+
}
|
|
539
|
+
resolve(...paths) {
|
|
540
|
+
return new Path(path.resolve(this.value, ...paths));
|
|
541
|
+
}
|
|
542
|
+
_join(...paths) {
|
|
543
|
+
const _paths = paths.filter((_path) => !!_path);
|
|
544
|
+
return _paths.length ? path.join(this.value, ..._paths) : this.value;
|
|
545
|
+
}
|
|
546
|
+
async readdir(...paths) {
|
|
547
|
+
const dir = this._join(...paths);
|
|
548
|
+
return (await fs.promises.readdir(dir)).map((file) => new Path(path.join(dir, file)));
|
|
549
|
+
}
|
|
550
|
+
readFile(pathAppend, defaults) {
|
|
551
|
+
return new Promise((resolve, reject) => {
|
|
552
|
+
fs.readFile(this._join(pathAppend), "utf-8", (err, data) => {
|
|
553
|
+
if (err) {
|
|
554
|
+
if (defaults !== void 0 && isFileNotFoundException(err)) return resolve(defaults);
|
|
555
|
+
return reject(err);
|
|
556
|
+
}
|
|
557
|
+
resolve(data);
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
async readJSON(pathAppend, defaults) {
|
|
562
|
+
try {
|
|
563
|
+
const file = await this.readFile(pathAppend);
|
|
564
|
+
return JSON.parse(file);
|
|
565
|
+
} catch (err) {
|
|
566
|
+
if (defaults === void 0) throw err;
|
|
567
|
+
return defaults;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
//#endregion
|
|
573
|
+
//#region src/package.ts
|
|
574
|
+
async function getProjectPackageJson(searchDir, allowMissing) {
|
|
575
|
+
const hit = await findConfig({
|
|
576
|
+
fileName: PACKAGE_JSON_FILENAME,
|
|
577
|
+
allowMissing,
|
|
578
|
+
test: (result) => isProjectPackageJson(JSON.parse(result.code))
|
|
579
|
+
}, searchDir);
|
|
580
|
+
if (!hit) {
|
|
581
|
+
if (allowMissing) return null;
|
|
582
|
+
throw new Error("missing project package.");
|
|
583
|
+
}
|
|
584
|
+
return {
|
|
585
|
+
dir: new Path(hit.dir),
|
|
586
|
+
json: JSON.parse(hit.code)
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
async function getWorkspacePackageJson(searchDir, allowMissing) {
|
|
590
|
+
const hit = await findConfig({
|
|
591
|
+
fileName: PACKAGE_JSON_FILENAME,
|
|
592
|
+
allowMissing,
|
|
593
|
+
test: (result) => isWorkspacePackageJson(JSON.parse(result.code))
|
|
594
|
+
}, searchDir);
|
|
595
|
+
if (!hit) {
|
|
596
|
+
if (allowMissing) return null;
|
|
597
|
+
throw new Error("missing workspace package.");
|
|
598
|
+
}
|
|
599
|
+
return {
|
|
600
|
+
dir: new Path(hit.dir),
|
|
601
|
+
json: JSON.parse(hit.code)
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
async function findWorkspacePackages(dir) {
|
|
605
|
+
const results = [];
|
|
606
|
+
const searchDir = path.resolve(dir);
|
|
607
|
+
const dirs = await fs$1.readdir(searchDir);
|
|
608
|
+
(await Promise.all(dirs.map((dirName) => getWorkspacePackageJson(path.join(searchDir, dirName), true)))).forEach((pkg) => {
|
|
609
|
+
pkg && results.push(pkg);
|
|
610
|
+
});
|
|
611
|
+
return results;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
//#endregion
|
|
615
|
+
//#region src/workspace/dts.ts
|
|
616
|
+
async function runTsc(compiler, opts = {}, ignoreErrors) {
|
|
617
|
+
const { cwd = process.cwd(), outDir = path.join(cwd, "dist/dts") } = opts;
|
|
618
|
+
try {
|
|
619
|
+
await execa(compiler, [
|
|
620
|
+
"--declaration true",
|
|
621
|
+
"--skipLibCheck",
|
|
622
|
+
"--noEmit false",
|
|
623
|
+
"--emitDeclarationOnly",
|
|
624
|
+
`--outDir ${outDir}`
|
|
625
|
+
], {
|
|
626
|
+
cwd,
|
|
627
|
+
shell: true,
|
|
628
|
+
stdio: "inherit"
|
|
629
|
+
});
|
|
630
|
+
} catch (e) {
|
|
631
|
+
if (!ignoreErrors) throw e;
|
|
632
|
+
console.log(`Note: ${compiler} reported errors, but continuing with generated files...`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Emit DTS (declaration files)
|
|
637
|
+
*/
|
|
638
|
+
async function emitDTS(opts) {
|
|
639
|
+
const { compiler = "tsc", ignoreCompilerErrors = false, workspace, ...baseOpts } = opts;
|
|
640
|
+
if (typeof compiler === "function") await compiler({
|
|
641
|
+
...baseOpts,
|
|
642
|
+
workspace
|
|
643
|
+
});
|
|
644
|
+
else await runTsc(compiler, { ...baseOpts }, ignoreCompilerErrors);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
//#endregion
|
|
648
|
+
//#region src/env/constants.ts
|
|
649
|
+
const PLUGBOY_VAR_ENVS_FOR_BUNDLE = {
|
|
650
|
+
__PLUGBOY_STUB__: "false",
|
|
651
|
+
__PLUGBOY_DEV__: `#(typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') || (typeof import.meta !== 'undefined' && import.meta.env?.DEV === true)`
|
|
652
|
+
};
|
|
653
|
+
const PLUGBOY_VAR_ENVS_FOR_STUB = {
|
|
654
|
+
__PLUGBOY_STUB__: "true",
|
|
655
|
+
__PLUGBOY_DEV__: "true"
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region src/env/utils.ts
|
|
660
|
+
function applyPlugboyEnvs(config) {
|
|
661
|
+
const DEFINE_VAR_INJECTS = Object.fromEntries(Object.entries(PLUGBOY_VAR_ENVS_FOR_BUNDLE).map(([envName, value]) => {
|
|
662
|
+
return [envName, value.startsWith("#") ? `$$${envName}` : value];
|
|
663
|
+
}));
|
|
664
|
+
config.define = {
|
|
665
|
+
...config.define,
|
|
666
|
+
...DEFINE_VAR_INJECTS
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function getPlugboyEnvCodeForStub() {
|
|
670
|
+
return Object.entries(PLUGBOY_VAR_ENVS_FOR_STUB).map(([envName, variable]) => `globalThis.${envName} = ${variable};`).join("\n");
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
//#endregion
|
|
674
|
+
//#region src/env/plugin.ts
|
|
675
|
+
function findAfterImports(code) {
|
|
676
|
+
const ast = parse(code, {
|
|
677
|
+
sourceType: "module",
|
|
678
|
+
ecmaVersion: "latest"
|
|
679
|
+
});
|
|
680
|
+
let end = 0;
|
|
681
|
+
for (const node of ast.body) {
|
|
682
|
+
if (node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportDefaultDeclaration") {
|
|
683
|
+
end = Math.max(end, node.end);
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
return end;
|
|
689
|
+
}
|
|
690
|
+
const _replacements = [];
|
|
691
|
+
Object.entries(PLUGBOY_VAR_ENVS_FOR_BUNDLE).forEach(([envName, value]) => {
|
|
692
|
+
if (value.startsWith("#")) _replacements.push([`$$${envName}`, value.substring(1)]);
|
|
693
|
+
});
|
|
694
|
+
function WorkspaceEnvPlugin(_workspace) {
|
|
695
|
+
return {
|
|
696
|
+
name: "plugboy-workspace-env",
|
|
697
|
+
async renderChunk(code, _chunk) {
|
|
698
|
+
const injects = _replacements.filter(([envName]) => code.includes(envName));
|
|
699
|
+
if (injects.length) {
|
|
700
|
+
const MagicString = (await import("magic-string")).default;
|
|
701
|
+
const ms = new MagicString(code);
|
|
702
|
+
const insertPos = findAfterImports(code);
|
|
703
|
+
const injectCode = injects.map(([eventName, value]) => `const ${eventName} = ${value};`).join("\n");
|
|
704
|
+
ms.appendLeft(insertPos, `\n${injectCode}`);
|
|
705
|
+
return {
|
|
706
|
+
code: ms.toString(),
|
|
707
|
+
map: ms.generateMap({ hires: true })
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region src/workspace/builder.ts
|
|
716
|
+
const SHEBANG_MATCH_RE = /^(#!.+?)\n/;
|
|
717
|
+
var Builder = class {
|
|
718
|
+
workspace;
|
|
719
|
+
_tsdownOptions;
|
|
720
|
+
get entry() {
|
|
721
|
+
return this.workspace.entry;
|
|
722
|
+
}
|
|
723
|
+
get dts() {
|
|
724
|
+
return this.workspace.dts;
|
|
725
|
+
}
|
|
726
|
+
constructor(workspace) {
|
|
727
|
+
this.workspace = workspace;
|
|
728
|
+
}
|
|
729
|
+
async tsdownOptions(overrides) {
|
|
730
|
+
let { _tsdownOptions } = this;
|
|
731
|
+
if (_tsdownOptions) return _tsdownOptions;
|
|
732
|
+
const { entry, dts } = this;
|
|
733
|
+
_tsdownOptions = {
|
|
734
|
+
dts: dts.inline || typeof dts.compiler === "function" ? false : dts.compiler === "vue-tsc" ? { vue: true } : true,
|
|
735
|
+
treeshake: true,
|
|
736
|
+
plugins: this.workspace.plugins,
|
|
737
|
+
entry,
|
|
738
|
+
sourcemap: true,
|
|
739
|
+
clean: true,
|
|
740
|
+
...overrides
|
|
741
|
+
};
|
|
742
|
+
for (const opt of TSDOWN_SYNC_OPTIONS) _tsdownOptions[opt] = this.workspace.config[opt];
|
|
743
|
+
applyPlugboyEnvs(_tsdownOptions);
|
|
744
|
+
_tsdownOptions.external = mergeExternals(_tsdownOptions.external, [/^(@fastkit\/)?plugboy(?!\/runtime-utils)/, ...this.workspace.dependencies]);
|
|
745
|
+
this._tsdownOptions = _tsdownOptions;
|
|
746
|
+
return _tsdownOptions;
|
|
747
|
+
}
|
|
748
|
+
async _stubLinkJS(from, to) {
|
|
749
|
+
const fromParsed = path.parse(from);
|
|
750
|
+
const fromDir = fromParsed.dir;
|
|
751
|
+
const toParsed = path.parse(to);
|
|
752
|
+
const toRelativeDir = path.relative(fromDir, toParsed.dir);
|
|
753
|
+
const location = path.join(toRelativeDir, toParsed.base);
|
|
754
|
+
const shebang = (await fs$1.readFile(to, "utf-8")).match(SHEBANG_MATCH_RE)?.[1];
|
|
755
|
+
const disableChecks = "/* eslint-disable */\n// @ts-nocheck\n";
|
|
756
|
+
const code = `${disableChecks}${getPlugboyEnvCodeForStub()}\nexport * from '${location}';`;
|
|
757
|
+
const dtsPath = path.join(fromDir, `${fromParsed.name}.d.mts`);
|
|
758
|
+
const dtsCode = `${disableChecks}export * from '${location.replace(/\.ts$/, "")}';`;
|
|
759
|
+
const srcFromDir = path.dirname(from);
|
|
760
|
+
const dtsDir = path.dirname(dtsPath);
|
|
761
|
+
await Promise.all([srcFromDir, dtsDir].map((dir) => fs$1.mkdir(dir, { recursive: true })));
|
|
762
|
+
await Promise.all([fs$1.writeFile(from, `${shebang ? `${shebang}\n` : ""}${code}`), fs$1.writeFile(dtsPath, dtsCode)]);
|
|
763
|
+
}
|
|
764
|
+
async _stubLinkCSS(from) {
|
|
765
|
+
await fs$1.writeFile(from, `/* noop */`);
|
|
766
|
+
}
|
|
767
|
+
async copyPublicDir() {
|
|
768
|
+
const publicDir = this.workspace.dir.join("public").value;
|
|
769
|
+
await copyDirSync(publicDir, this.workspace.dirs.dist.value);
|
|
770
|
+
}
|
|
771
|
+
async stub() {
|
|
772
|
+
const links = this.workspace.getStubLinks();
|
|
773
|
+
await this.copyPublicDir();
|
|
774
|
+
await Promise.all(links.map((link) => {
|
|
775
|
+
if (link.type === "js") return this._stubLinkJS(link.from, link.to);
|
|
776
|
+
if (link.type === "css") return this._stubLinkCSS(link.from);
|
|
777
|
+
throw new Error(`non supported type`);
|
|
778
|
+
}));
|
|
779
|
+
await fs$1.writeFile(this.workspace.dirs.dist.join(".stub").value, "", "utf-8");
|
|
780
|
+
}
|
|
781
|
+
normalizeDTSBySettings(dts, settings) {
|
|
782
|
+
const { targets, pkg } = settings;
|
|
783
|
+
const packageIsOwn = this.workspace.json.name === pkg;
|
|
784
|
+
const pkgImports = (() => {
|
|
785
|
+
if (!pkg || packageIsOwn) return;
|
|
786
|
+
const importRe = new RegExp(`import {([^\\{\\}]+)} from '${pkg}'`);
|
|
787
|
+
const importMatched = dts.match(importRe);
|
|
788
|
+
const imports = importMatched && importMatched[1];
|
|
789
|
+
if (!imports) return;
|
|
790
|
+
return {
|
|
791
|
+
pkg,
|
|
792
|
+
importRe,
|
|
793
|
+
imports
|
|
794
|
+
};
|
|
795
|
+
})();
|
|
796
|
+
const hitTypeNames = [];
|
|
797
|
+
targets.forEach(({ from, typeName }) => {
|
|
798
|
+
if (dts.match(from)) {
|
|
799
|
+
hitTypeNames.push(typeName);
|
|
800
|
+
dts = dts.replace(from, typeName);
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
if (!hitTypeNames.length) return;
|
|
804
|
+
if (pkgImports) {
|
|
805
|
+
const { pkg, imports, importRe } = pkgImports;
|
|
806
|
+
const mods = imports.trim().split(",").map((row) => {
|
|
807
|
+
row = row.split(" as ")[0].trim();
|
|
808
|
+
return row;
|
|
809
|
+
});
|
|
810
|
+
const appends = [];
|
|
811
|
+
hitTypeNames.forEach((typeName) => {
|
|
812
|
+
if (!new RegExp(`(^|\n)import { ${typeName} } from '${pkg}'`).test(dts) && !mods.includes(typeName)) appends.push(typeName);
|
|
813
|
+
});
|
|
814
|
+
if (appends.length) dts = dts.replace(importRe, `import { $1, ${appends.join(", ")} } from '${pkg}'`);
|
|
815
|
+
} else if (pkg && !packageIsOwn) {
|
|
816
|
+
const mods = [];
|
|
817
|
+
hitTypeNames.forEach((typeName) => {
|
|
818
|
+
if (!dts.includes(`export declare type ${typeName} = `)) mods.push(typeName);
|
|
819
|
+
});
|
|
820
|
+
if (mods.length) dts = `import { ${mods.join(", ")} } from '${pkg}';\n${dts}`;
|
|
821
|
+
}
|
|
822
|
+
return dts;
|
|
823
|
+
}
|
|
824
|
+
async normalizeDTSFile(filePath) {
|
|
825
|
+
const dts = await fs$1.readFile(filePath, "utf-8");
|
|
826
|
+
const { preserveType, normalizers } = this.dts;
|
|
827
|
+
let normalized = dts;
|
|
828
|
+
let processed = false;
|
|
829
|
+
for (const settings of preserveType) {
|
|
830
|
+
const _normalized = this.normalizeDTSBySettings(normalized, settings);
|
|
831
|
+
if (_normalized) {
|
|
832
|
+
processed = true;
|
|
833
|
+
normalized = _normalized;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
for (const normalizer of normalizers) {
|
|
837
|
+
const _normalized = await normalizer(normalized, this);
|
|
838
|
+
if (_normalized && normalized !== _normalized) {
|
|
839
|
+
processed = true;
|
|
840
|
+
normalized = _normalized;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (!processed) return;
|
|
844
|
+
await fs$1.writeFile(filePath, normalized, "utf-8");
|
|
845
|
+
}
|
|
846
|
+
async normalizeDTSFiles(dtsFiles = this.workspace.dtsFiles) {
|
|
847
|
+
const { preserveType } = this.dts;
|
|
848
|
+
if (!preserveType.length || !dtsFiles.length) return;
|
|
849
|
+
await Promise.all(dtsFiles.map((filePath) => this.normalizeDTSFile(filePath)));
|
|
850
|
+
}
|
|
851
|
+
async emitDTSManually() {
|
|
852
|
+
const { dir, dirs, exports } = this.workspace;
|
|
853
|
+
const cwd = dir.value;
|
|
854
|
+
const outDir = dirs.dist.join(".dts-generate").value;
|
|
855
|
+
const dtsSrcDir = path.join(outDir, "src");
|
|
856
|
+
const dtsDest = dirs.dist.join(".dts").value;
|
|
857
|
+
await emitDTS({
|
|
858
|
+
cwd,
|
|
859
|
+
outDir,
|
|
860
|
+
workspace: this.workspace,
|
|
861
|
+
compiler: this.workspace.dts.compiler,
|
|
862
|
+
ignoreCompilerErrors: this.workspace.dts.ignoreCompilerErrors
|
|
863
|
+
});
|
|
864
|
+
await fs$1.rename(dtsSrcDir, dtsDest);
|
|
865
|
+
await rmrf(outDir);
|
|
866
|
+
const objectExports = [];
|
|
867
|
+
exports.forEach(({ at }) => {
|
|
868
|
+
typeof at === "object" && objectExports.push(at);
|
|
869
|
+
});
|
|
870
|
+
await Promise.all(objectExports.map(async (at) => {
|
|
871
|
+
const typesDir = path.dirname(at.types);
|
|
872
|
+
const dtsDestDir = path.dirname(at.dtsDest);
|
|
873
|
+
const relativeDir = path.relative(typesDir, dtsDestDir);
|
|
874
|
+
const code = `export * from './${path.join(relativeDir, path.basename(at.dtsDest).replace(/\.d\.m?ts$/, ""))}';`;
|
|
875
|
+
await fs$1.writeFile(at.types, code, "utf-8");
|
|
876
|
+
}));
|
|
877
|
+
const dtsFiles = await glob(path.join(dtsDest, "**/*.{d.ts,d.mts}"));
|
|
878
|
+
await this.normalizeDTSFiles(dtsFiles);
|
|
879
|
+
}
|
|
880
|
+
async build() {
|
|
881
|
+
await build(await this.tsdownOptions());
|
|
882
|
+
if (this.dts.inline || typeof this.dts.compiler === "function") await this.emitDTSManually();
|
|
883
|
+
else await this.normalizeDTSFiles();
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
//#endregion
|
|
888
|
+
//#region src/project/project.ts
|
|
889
|
+
/**
|
|
890
|
+
* Plugboy Project
|
|
891
|
+
*
|
|
892
|
+
* @remarks This instance is only created if the project consists of a mono-repo.
|
|
893
|
+
*/
|
|
894
|
+
var PlugboyProject = class {
|
|
895
|
+
/** Path instance of the project directory */
|
|
896
|
+
dir;
|
|
897
|
+
/** package.json */
|
|
898
|
+
json;
|
|
899
|
+
/**
|
|
900
|
+
* Project Configuration
|
|
901
|
+
* @see {@link ResolvedProjectConfig}
|
|
902
|
+
*/
|
|
903
|
+
config;
|
|
904
|
+
/** Names of all packages on which the project depends */
|
|
905
|
+
dependencies;
|
|
906
|
+
/** Directory names of all workspaces owned by the project */
|
|
907
|
+
resolvedWorkspaces;
|
|
908
|
+
/**
|
|
909
|
+
* Name of the project's package.json
|
|
910
|
+
*/
|
|
911
|
+
get name() {
|
|
912
|
+
return this.json.name;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Plug-in List
|
|
916
|
+
* @see {@link ResolvedProjectConfig.plugins}
|
|
917
|
+
*/
|
|
918
|
+
get plugins() {
|
|
919
|
+
return this.config.plugins;
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* List of all user hook settings
|
|
923
|
+
* @see {@link UserHooks}
|
|
924
|
+
*/
|
|
925
|
+
get hooks() {
|
|
926
|
+
const { hooks: _hooks, plugins } = this.config;
|
|
927
|
+
return [_hooks, ...plugins.map((plugin) => plugin.hooks)].filter((hook) => !!hook);
|
|
928
|
+
}
|
|
929
|
+
constructor(ctx) {
|
|
930
|
+
const { dir, json, config, resolvedWorkspaces } = ctx;
|
|
931
|
+
this.dir = dir;
|
|
932
|
+
this.json = json;
|
|
933
|
+
this.config = config;
|
|
934
|
+
const allDeps = {
|
|
935
|
+
...json.dependencies,
|
|
936
|
+
...json.devDependencies
|
|
937
|
+
};
|
|
938
|
+
this.dependencies = Object.keys(allDeps);
|
|
939
|
+
this.resolvedWorkspaces = resolvedWorkspaces;
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
async function getProject(searchDir, allowMissing, skipLoadConfig) {
|
|
943
|
+
const hit = await getProjectPackageJson(searchDir, allowMissing);
|
|
944
|
+
if (!hit) return null;
|
|
945
|
+
const { dir, json } = hit;
|
|
946
|
+
const resolvedWorkspaces = [];
|
|
947
|
+
const { workspaces = [] } = json;
|
|
948
|
+
if (!Array.isArray(workspaces)) throw new Error("workspaces only supports arrays.");
|
|
949
|
+
const workspaceHits = await glob(workspaces.map((workspace) => dir.join(workspace, PACKAGE_JSON_FILENAME).value));
|
|
950
|
+
for (const _hit of workspaceHits) {
|
|
951
|
+
if (!isWorkspacePackageJson(JSON.parse(await fs$1.readFile(_hit, "utf-8")))) continue;
|
|
952
|
+
resolvedWorkspaces.push(path.dirname(_hit));
|
|
953
|
+
}
|
|
954
|
+
resolvedWorkspaces.sort((a, b) => {
|
|
955
|
+
if (a < b) return -1;
|
|
956
|
+
if (a > b) return 1;
|
|
957
|
+
return 0;
|
|
958
|
+
});
|
|
959
|
+
return new PlugboyProject({
|
|
960
|
+
dir,
|
|
961
|
+
json,
|
|
962
|
+
config: skipLoadConfig ? await resolveUserProjectConfig({}) : await loadProjectConfig(dir.value, 0),
|
|
963
|
+
resolvedWorkspaces
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
//#endregion
|
|
968
|
+
//#region src/postcss/plugin.ts
|
|
969
|
+
async function getPostcss(options) {
|
|
970
|
+
const { layer, media, combineRules, cssnano } = options;
|
|
971
|
+
const [postcss, _layer, _media, _combineRules, _cssnano] = await Promise.all([
|
|
972
|
+
import("postcss").then((mod) => mod.default),
|
|
973
|
+
layer && import("./optimize-layer-CK8NR_VC.mjs").then((mod) => mod.OptimizeLayer(layer)),
|
|
974
|
+
media && import("./optimize-media-Bxy27Cj7.mjs").then((mod) => mod.OptimizeMedia(media)),
|
|
975
|
+
combineRules && import("./combine-rules-CWp-M491.mjs").then((mod) => mod.CombineRules(combineRules)),
|
|
976
|
+
cssnano && import("cssnano").then((mod) => mod.default(cssnano))
|
|
977
|
+
]);
|
|
978
|
+
const plugins = [];
|
|
979
|
+
_layer && plugins.push(_layer);
|
|
980
|
+
_media && plugins.push(_media);
|
|
981
|
+
_combineRules && plugins.push(_combineRules);
|
|
982
|
+
_cssnano && plugins.push(_cssnano);
|
|
983
|
+
return postcss(plugins);
|
|
984
|
+
}
|
|
985
|
+
const SOURCE_MAPPING_URL_COMMENT_RE = /\/\*# sourceMappingURL=.+? \*\//g;
|
|
986
|
+
const allLayerDefRe = /(^|\n)@layer\s+([a-zA-Z\d\-_$. ,]+);/g;
|
|
987
|
+
const layerDefTrimRe = /((^|\n)@layer\s+|;)/g;
|
|
988
|
+
async function optimizeCSS(asset, options) {
|
|
989
|
+
const postcss = await getPostcss(options);
|
|
990
|
+
function prepare(css) {
|
|
991
|
+
return (() => {
|
|
992
|
+
const matched = css.match(allLayerDefRe);
|
|
993
|
+
if (!matched) return "";
|
|
994
|
+
const layerNames = [];
|
|
995
|
+
matched.forEach((row) => {
|
|
996
|
+
row.replace(layerDefTrimRe, "").split(",").forEach((chunk) => layerNames.push(chunk.trim()));
|
|
997
|
+
});
|
|
998
|
+
return `@layer ${Array.from(new Set(layerNames)).join(", ")};\n`;
|
|
999
|
+
})() + css.replace(allLayerDefRe, "");
|
|
1000
|
+
}
|
|
1001
|
+
const css = prepare(asset.source.toString());
|
|
1002
|
+
asset.source = (await postcss.process(css, {
|
|
1003
|
+
from: asset.fileName,
|
|
1004
|
+
to: asset.fileName,
|
|
1005
|
+
map: { inline: false }
|
|
1006
|
+
})).css.replace(SOURCE_MAPPING_URL_COMMENT_RE, "");
|
|
1007
|
+
}
|
|
1008
|
+
function OptimizeCSSPlugin(workspace) {
|
|
1009
|
+
return {
|
|
1010
|
+
name: "plugboy-optimize-css",
|
|
1011
|
+
async generateBundle(_options, bundle) {
|
|
1012
|
+
const { optimizeCSSOptions } = workspace;
|
|
1013
|
+
if (!optimizeCSSOptions) return;
|
|
1014
|
+
for (const chunk of Object.values(bundle)) {
|
|
1015
|
+
if (chunk.type !== "asset" || !chunk.fileName.endsWith(".css")) continue;
|
|
1016
|
+
await optimizeCSS(chunk, optimizeCSSOptions);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
//#endregion
|
|
1023
|
+
//#region src/workspace/workspace.ts
|
|
1024
|
+
function extractWorkspaceObjectExport(at) {
|
|
1025
|
+
if (typeof at === "string") return at;
|
|
1026
|
+
const { types, import: _import } = at;
|
|
1027
|
+
return {
|
|
1028
|
+
types,
|
|
1029
|
+
import: _import
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
const WORKSPACE_PACKAGE_SYNC_FIELDS = [
|
|
1033
|
+
"repository",
|
|
1034
|
+
"author",
|
|
1035
|
+
"publishConfig",
|
|
1036
|
+
"license"
|
|
1037
|
+
];
|
|
1038
|
+
function syncWorkspacePackageFields(projectJSON, workspaceJSON) {
|
|
1039
|
+
for (const field of WORKSPACE_PACKAGE_SYNC_FIELDS) {
|
|
1040
|
+
const value = projectJSON[field];
|
|
1041
|
+
if (value && !workspaceJSON[field]) workspaceJSON[field] = value;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
const BUILD_TARGET_SRC_MATCH_RE = /\.(tsx?|s?css)$/;
|
|
1045
|
+
var PlugboyWorkspace = class {
|
|
1046
|
+
name;
|
|
1047
|
+
dir;
|
|
1048
|
+
config;
|
|
1049
|
+
project;
|
|
1050
|
+
dirs;
|
|
1051
|
+
dependencies;
|
|
1052
|
+
projectDependencies;
|
|
1053
|
+
meta;
|
|
1054
|
+
entry;
|
|
1055
|
+
exports;
|
|
1056
|
+
builder;
|
|
1057
|
+
plugins;
|
|
1058
|
+
hooks;
|
|
1059
|
+
dtsFiles = [];
|
|
1060
|
+
dts;
|
|
1061
|
+
optimizeCSSOptions;
|
|
1062
|
+
_json;
|
|
1063
|
+
get json() {
|
|
1064
|
+
return this._json;
|
|
1065
|
+
}
|
|
1066
|
+
constructor(ctx) {
|
|
1067
|
+
const { dir, json, config, project, dirs, dependencies, projectDependencies, meta, plugins, hooks, dts, optimizeCSS } = ctx;
|
|
1068
|
+
this.name = dir.basename;
|
|
1069
|
+
this.dir = dir;
|
|
1070
|
+
this._json = json;
|
|
1071
|
+
this.project = project;
|
|
1072
|
+
this.dirs = dirs;
|
|
1073
|
+
this.dependencies = dependencies;
|
|
1074
|
+
this.projectDependencies = projectDependencies;
|
|
1075
|
+
this.meta = meta;
|
|
1076
|
+
this.config = config;
|
|
1077
|
+
this.plugins = [
|
|
1078
|
+
...plugins,
|
|
1079
|
+
OptimizeCSSPlugin(this),
|
|
1080
|
+
WorkspaceEnvPlugin(this)
|
|
1081
|
+
];
|
|
1082
|
+
this.hooks = hooks;
|
|
1083
|
+
this.dts = dts;
|
|
1084
|
+
this.optimizeCSSOptions = optimizeCSS ? resolveOptimizeCSSOptions(optimizeCSS) : false;
|
|
1085
|
+
const entry = {};
|
|
1086
|
+
const exports = [{
|
|
1087
|
+
id: `./${PACKAGE_JSON_FILENAME}`,
|
|
1088
|
+
at: `./${PACKAGE_JSON_FILENAME}`
|
|
1089
|
+
}];
|
|
1090
|
+
Object.entries(config.entries).forEach(([id, { src, css }]) => {
|
|
1091
|
+
if (!BUILD_TARGET_SRC_MATCH_RE.test(src)) return;
|
|
1092
|
+
const normalizedId = id === "." ? this.name : id;
|
|
1093
|
+
const exportId = id.startsWith(".") ? id : `./${id}`;
|
|
1094
|
+
const srcIsCSS = src.endsWith(".css") || src.endsWith(".scss");
|
|
1095
|
+
const dest = `./dist/${normalizedId}.${srcIsCSS ? "css" : "mjs"}`;
|
|
1096
|
+
const destFullPath = dir.join(dest).value;
|
|
1097
|
+
entry[normalizedId] = src;
|
|
1098
|
+
if (css) {
|
|
1099
|
+
const cssDest = `./dist/${normalizedId}.css`;
|
|
1100
|
+
exports.push({
|
|
1101
|
+
id: `./${normalizedId}.css`,
|
|
1102
|
+
at: cssDest,
|
|
1103
|
+
stubLink: {
|
|
1104
|
+
type: "css",
|
|
1105
|
+
from: cssDest
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
if (srcIsCSS) return;
|
|
1109
|
+
}
|
|
1110
|
+
const types = `./dist/${normalizedId}.d.mts`;
|
|
1111
|
+
const dtsDest = `./dist/${src.replace(/^\.\/src/, ".dts").replace(/\.ts$/, ".d.mts")}`;
|
|
1112
|
+
this.dtsFiles.push(dir.join(types).value);
|
|
1113
|
+
exports.push({
|
|
1114
|
+
id: exportId,
|
|
1115
|
+
at: {
|
|
1116
|
+
src,
|
|
1117
|
+
types,
|
|
1118
|
+
dtsDest,
|
|
1119
|
+
import: { default: dest }
|
|
1120
|
+
},
|
|
1121
|
+
stubLink: {
|
|
1122
|
+
from: destFullPath,
|
|
1123
|
+
to: path.isAbsolute(src) ? src : dir.join(src).value,
|
|
1124
|
+
type: "js"
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
});
|
|
1128
|
+
this.entry = entry;
|
|
1129
|
+
this.exports = exports;
|
|
1130
|
+
this.builder = new Builder(this);
|
|
1131
|
+
}
|
|
1132
|
+
clean(withDepsAndCache) {
|
|
1133
|
+
const { dir, dirs } = this;
|
|
1134
|
+
const paths = [dirs.dist.value];
|
|
1135
|
+
if (withDepsAndCache) paths.push(dir.join("node_modules").value, dir.join(".turbo").value);
|
|
1136
|
+
return rmrf(...paths);
|
|
1137
|
+
}
|
|
1138
|
+
async preparePackageJSON() {
|
|
1139
|
+
const { exports, json, project } = this;
|
|
1140
|
+
const _exports = {};
|
|
1141
|
+
const typesVersions = {};
|
|
1142
|
+
let main;
|
|
1143
|
+
let mainTypes;
|
|
1144
|
+
exports.forEach(({ id, at }) => {
|
|
1145
|
+
const _at = extractWorkspaceObjectExport(at);
|
|
1146
|
+
_exports[id] = _at;
|
|
1147
|
+
if (typeof _at !== "object") return;
|
|
1148
|
+
const isMainExport = id === ".";
|
|
1149
|
+
const trimmedId = isMainExport ? id : id.replace(/^\.\//, "");
|
|
1150
|
+
typesVersions[trimmedId] = [_at.types];
|
|
1151
|
+
if (isMainExport) {
|
|
1152
|
+
main = _at.import.default;
|
|
1153
|
+
mainTypes = _at.types;
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
if (json.exports) Object.entries(json.exports).forEach(([id, at]) => {
|
|
1157
|
+
const types = Object.keys(at);
|
|
1158
|
+
if (types.length === 1 && types[0] === "types") _exports[id] = at;
|
|
1159
|
+
});
|
|
1160
|
+
_exports["./*"] = "./dist/*";
|
|
1161
|
+
const originalJSONString = JSON.stringify(json);
|
|
1162
|
+
const cloned = JSON.parse(originalJSONString);
|
|
1163
|
+
cloned.exports = _exports;
|
|
1164
|
+
cloned.typesVersions = { "*": typesVersions };
|
|
1165
|
+
if (main) cloned.main = main;
|
|
1166
|
+
if (mainTypes) cloned.types = mainTypes;
|
|
1167
|
+
const projectPeerDependencies = project?.config.peerDependencies;
|
|
1168
|
+
[
|
|
1169
|
+
"dependencies",
|
|
1170
|
+
"devDependencies",
|
|
1171
|
+
"peerDependencies"
|
|
1172
|
+
].forEach((prop) => {
|
|
1173
|
+
const deps = cloned[prop];
|
|
1174
|
+
if (!deps) return;
|
|
1175
|
+
Object.keys(deps).forEach((dep) => {
|
|
1176
|
+
if (deps[dep].startsWith(WORKSPACE_SPEC_PREFIX)) deps[dep] = `${WORKSPACE_SPEC_PREFIX}^`;
|
|
1177
|
+
else if (projectPeerDependencies && projectPeerDependencies[dep] && !deps[dep]) deps[dep] = projectPeerDependencies[dep];
|
|
1178
|
+
});
|
|
1179
|
+
});
|
|
1180
|
+
cloned.files = cloned.files || [];
|
|
1181
|
+
if (!cloned.files.some((file) => /(\.\/)?dist\/?/.test(file))) cloned.files.unshift("dist");
|
|
1182
|
+
if (project) syncWorkspacePackageFields(project.json, cloned);
|
|
1183
|
+
cloned.type = cloned.type || "module";
|
|
1184
|
+
await this.hooks.preparePackageJSON(json, this);
|
|
1185
|
+
const sorted = sortPackageJson(cloned);
|
|
1186
|
+
const toStr = JSON.stringify(sorted, null, 2);
|
|
1187
|
+
if (originalJSONString !== toStr) {
|
|
1188
|
+
await writeFileAtomic(this.dir.join(PACKAGE_JSON_FILENAME).value, toStr);
|
|
1189
|
+
this._json = sorted;
|
|
1190
|
+
}
|
|
1191
|
+
return sorted;
|
|
1192
|
+
}
|
|
1193
|
+
getStubLinks() {
|
|
1194
|
+
const links = [];
|
|
1195
|
+
this.exports.forEach(({ stubLink }) => {
|
|
1196
|
+
stubLink && links.push(stubLink);
|
|
1197
|
+
});
|
|
1198
|
+
return links;
|
|
1199
|
+
}
|
|
1200
|
+
async stub() {
|
|
1201
|
+
await this.clean();
|
|
1202
|
+
await fs$1.mkdir(this.dirs.dist.value);
|
|
1203
|
+
return this.builder.stub();
|
|
1204
|
+
}
|
|
1205
|
+
async build() {
|
|
1206
|
+
await this.clean();
|
|
1207
|
+
return this.builder.build();
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
async function getWorkspace(searchDir, allowMissing) {
|
|
1211
|
+
const hit = await getWorkspacePackageJson(searchDir, allowMissing);
|
|
1212
|
+
if (!hit) return null;
|
|
1213
|
+
const { dir, json } = hit;
|
|
1214
|
+
const config = await loadWorkspaceConfig(dir.value, 0);
|
|
1215
|
+
const project = await getProject(dir.value, true, config.ignoreProjectConfig);
|
|
1216
|
+
const dirs = {
|
|
1217
|
+
src: dir.join("src"),
|
|
1218
|
+
dist: dir.join("dist")
|
|
1219
|
+
};
|
|
1220
|
+
const { dependencies, peerDependencies, optionalDependencies } = json;
|
|
1221
|
+
const allDeps = {
|
|
1222
|
+
...dependencies,
|
|
1223
|
+
...peerDependencies,
|
|
1224
|
+
...optionalDependencies
|
|
1225
|
+
};
|
|
1226
|
+
const _dependencies = Object.keys(allDeps);
|
|
1227
|
+
const projectDependencies = Object.entries(allDeps).filter(([dep, spec]) => spec.startsWith(WORKSPACE_SPEC_PREFIX)).map(([dep]) => dep);
|
|
1228
|
+
const meta = {};
|
|
1229
|
+
const projectPlugins = project?.plugins || [];
|
|
1230
|
+
const projectHooks = project?.hooks || [];
|
|
1231
|
+
const plugins = [...projectPlugins, ...config.plugins];
|
|
1232
|
+
const _hooks = [...projectHooks];
|
|
1233
|
+
if (config.hooks) _hooks.push(config.hooks);
|
|
1234
|
+
for (const plugin of config.plugins) if (plugin.hooks) _hooks.push(plugin.hooks);
|
|
1235
|
+
const hooks = buildHooks(await resolveUserHooks(..._hooks));
|
|
1236
|
+
const dts = mergeDTSSettingsList(project?.config.dts, config.dts);
|
|
1237
|
+
let { optimizeCSS } = config;
|
|
1238
|
+
if (optimizeCSS !== false && project && project.config.optimizeCSS) optimizeCSS = {
|
|
1239
|
+
...project.config.optimizeCSS,
|
|
1240
|
+
...optimizeCSS
|
|
1241
|
+
};
|
|
1242
|
+
const ctx = {
|
|
1243
|
+
dir,
|
|
1244
|
+
json,
|
|
1245
|
+
config,
|
|
1246
|
+
project,
|
|
1247
|
+
dirs,
|
|
1248
|
+
dependencies: _dependencies,
|
|
1249
|
+
projectDependencies,
|
|
1250
|
+
meta,
|
|
1251
|
+
plugins,
|
|
1252
|
+
hooks,
|
|
1253
|
+
dts,
|
|
1254
|
+
optimizeCSS,
|
|
1255
|
+
mergeExternals: (override) => {
|
|
1256
|
+
config.external = mergeExternals(config.external, override);
|
|
1257
|
+
},
|
|
1258
|
+
mergeNoExternals: (override) => {
|
|
1259
|
+
config.noExternal = mergeNoExternals(config.noExternal, override);
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
await hooks.setupWorkspace(ctx, () => {
|
|
1263
|
+
return typeof workspace === "undefined" ? void 0 : workspace;
|
|
1264
|
+
});
|
|
1265
|
+
const workspace = new PlugboyWorkspace(ctx);
|
|
1266
|
+
await hooks.createWorkspace(workspace);
|
|
1267
|
+
return workspace;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
//#endregion
|
|
1271
|
+
//#region src/workspace/generate.ts
|
|
1272
|
+
async function generateWorkspace(workspaceName, cwd = process.cwd()) {
|
|
1273
|
+
const project = await getProject(cwd);
|
|
1274
|
+
const { config } = project;
|
|
1275
|
+
while (!workspaceName) {
|
|
1276
|
+
const value = await prompts.input({ message: "Enter a workspace name" });
|
|
1277
|
+
if (value) workspaceName = value;
|
|
1278
|
+
}
|
|
1279
|
+
const description = await prompts.input({
|
|
1280
|
+
default: workspaceName,
|
|
1281
|
+
message: "Please enter a description of your package"
|
|
1282
|
+
});
|
|
1283
|
+
let version;
|
|
1284
|
+
while (!version) {
|
|
1285
|
+
const value = await prompts.input({
|
|
1286
|
+
default: "0.0.0",
|
|
1287
|
+
message: "Please enter the initial version"
|
|
1288
|
+
});
|
|
1289
|
+
if (value) version = value;
|
|
1290
|
+
}
|
|
1291
|
+
const keywords = (await prompts.input({ message: "Enter as many keywords, if any, as needed, separated by commas" })).split(",").map((word) => word.trim()).filter((word) => word.length);
|
|
1292
|
+
const scriptsTemplates = config.scripts;
|
|
1293
|
+
let scriptsTemplate;
|
|
1294
|
+
if (scriptsTemplates && scriptsTemplates.length) {
|
|
1295
|
+
const value = await prompts.rawlist({
|
|
1296
|
+
message: "Select a scripts template",
|
|
1297
|
+
choices: [{
|
|
1298
|
+
name: "None",
|
|
1299
|
+
value: ""
|
|
1300
|
+
}, ...scriptsTemplates.map((tpl) => ({
|
|
1301
|
+
name: tpl.name,
|
|
1302
|
+
value: tpl.name
|
|
1303
|
+
}))]
|
|
1304
|
+
});
|
|
1305
|
+
scriptsTemplate = scriptsTemplates.find((tpl) => tpl.name === value);
|
|
1306
|
+
}
|
|
1307
|
+
const scripts = scriptsTemplate?.scripts || {};
|
|
1308
|
+
const peerDependencies = await (async () => {
|
|
1309
|
+
const deps = await prompts.checkbox({
|
|
1310
|
+
message: "Select the dependent packages, if any, to be used in the package",
|
|
1311
|
+
choices: Object.keys(config.peerDependencies).map((dep) => ({
|
|
1312
|
+
name: dep,
|
|
1313
|
+
value: dep
|
|
1314
|
+
}))
|
|
1315
|
+
});
|
|
1316
|
+
if (!deps.length) return;
|
|
1317
|
+
return Object.fromEntries(deps.map((dep) => [dep, config.peerDependencies[dep]]));
|
|
1318
|
+
})();
|
|
1319
|
+
const dependencies = await (async () => {
|
|
1320
|
+
const deps = await prompts.checkbox({
|
|
1321
|
+
message: "Select the internal package to be used, if any.",
|
|
1322
|
+
choices: project.resolvedWorkspaces.map((workspace) => {
|
|
1323
|
+
const name = path.basename(workspace);
|
|
1324
|
+
return {
|
|
1325
|
+
name,
|
|
1326
|
+
value: name
|
|
1327
|
+
};
|
|
1328
|
+
})
|
|
1329
|
+
});
|
|
1330
|
+
if (!deps.length) return;
|
|
1331
|
+
return Object.fromEntries(deps.map((dep) => [`@${project.name}/${dep}`, `${WORKSPACE_SPEC_PREFIX}^`]));
|
|
1332
|
+
})();
|
|
1333
|
+
const withGenSource = await prompts.confirm({
|
|
1334
|
+
message: "Generate source files?",
|
|
1335
|
+
default: true
|
|
1336
|
+
});
|
|
1337
|
+
const _json = {
|
|
1338
|
+
name: `@${project.name}/${workspaceName}`,
|
|
1339
|
+
type: "module",
|
|
1340
|
+
description,
|
|
1341
|
+
version,
|
|
1342
|
+
keywords,
|
|
1343
|
+
scripts,
|
|
1344
|
+
peerDependencies,
|
|
1345
|
+
dependencies
|
|
1346
|
+
};
|
|
1347
|
+
syncWorkspacePackageFields(project.json, _json);
|
|
1348
|
+
const json = sortPackageJson(_json);
|
|
1349
|
+
const workspaceDir = path.join(config.workspacesDir, workspaceName);
|
|
1350
|
+
console.log("");
|
|
1351
|
+
console.log("========================================");
|
|
1352
|
+
console.log(`Directory: ${workspaceDir}`);
|
|
1353
|
+
console.log(`Generate source: ${withGenSource ? "Yes" : "No"}`);
|
|
1354
|
+
console.log(json);
|
|
1355
|
+
console.log("========================================");
|
|
1356
|
+
if (!await prompts.confirm({
|
|
1357
|
+
message: "Is this OK?",
|
|
1358
|
+
default: true
|
|
1359
|
+
})) {
|
|
1360
|
+
console.log("Skipped.");
|
|
1361
|
+
process.exit(1);
|
|
1362
|
+
}
|
|
1363
|
+
await fs$1.mkdir(workspaceDir);
|
|
1364
|
+
await fs$1.writeFile(path.join(workspaceDir, "package.json"), JSON.stringify(json, null, 2));
|
|
1365
|
+
await fs$1.writeFile(path.join(workspaceDir, "README.md"), config.readme(json));
|
|
1366
|
+
if (withGenSource) {
|
|
1367
|
+
const srcDir = path.join(workspaceDir, "src");
|
|
1368
|
+
await fs$1.mkdir(srcDir);
|
|
1369
|
+
const indexCode = `export * from './${workspaceName}';\n`;
|
|
1370
|
+
const modCode = `export const PACKAGE_NAME = './${workspaceName}';\n`;
|
|
1371
|
+
await fs$1.writeFile(path.join(srcDir, "index.ts"), indexCode);
|
|
1372
|
+
await fs$1.writeFile(path.join(srcDir, `${workspaceName}.ts`), modCode);
|
|
1373
|
+
const { tsconfig } = config;
|
|
1374
|
+
if (tsconfig) await fs$1.writeFile(path.join(workspaceDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
1375
|
+
const configFileCode = `${`
|
|
1376
|
+
import { defineWorkspaceConfig } from '@fastkit/plugboy';
|
|
1377
|
+
|
|
1378
|
+
export default defineWorkspaceConfig({
|
|
1379
|
+
entries: {
|
|
1380
|
+
'.': './src/index.ts',
|
|
1381
|
+
},
|
|
1382
|
+
});
|
|
1383
|
+
`.trim()}\n`;
|
|
1384
|
+
await fs$1.writeFile(path.join(workspaceDir, `${WORKSPACE_CONFIG_BASENAME}.ts`), configFileCode);
|
|
1385
|
+
await (await getWorkspace(workspaceDir)).preparePackageJSON();
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
//#endregion
|
|
1390
|
+
export { normalizeDTSSettings as $, resolveRawExposeEntriesSettings as A, exitHook as B, findProjectPlugin as C, loadProjectConfig as D, isProjectPackageJson as E, getFilename as F, resolveListable as G, mergeExternals as H, isFileNotFoundException as I, WORKSPACE_REQUIRED_FIELDS as J, PROJECT_REQUIRED_FIELDS as K, pathExists as L, findConfig as M, findFile as N, resolveUserProjectConfig as O, getDirname as P, normalizeDTSPreserveTypeTarget as Q, rmrf as R, extractProjectPlugins as S, defineProjectConfig as T, mergeNoExternals as U, mergeChunkAddons as V, isPromise as W, mergeDTSSettingsList as X, resolveOptimizeCSSOptions as Y, normalizeDTSPreserveTypeSettings as Z, loadWorkspaceConfig as _, syncWorkspacePackageFields as a, resolveUserWorkspaceConfig as b, Builder as c, getWorkspacePackageJson as d, createHooksDefaults as et, Path as f, isWorkspacePackageJson as g, defineWorkspaceConfig as h, getWorkspace as i, copyDirSync as j, exposeEntries as k, findWorkspacePackages as l, resolveUserHooks as m, PlugboyWorkspace as n, PlugboyProject as o, buildHooks as p, TSDOWN_SYNC_OPTIONS as q, WORKSPACE_PACKAGE_SYNC_FIELDS as r, getProject as s, generateWorkspace as t, getProjectPackageJson as u, resolveRawWorkspaceEntries as v, resolveUserPluginOption as w, definePlugin as x, resolveRawWorkspaceEntry as y, writeFileAtomic as z };
|
|
1391
|
+
//# sourceMappingURL=workspace-BqcryYAT.mjs.map
|