@fastkit/plugboy 0.3.0 → 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.
Files changed (62) hide show
  1. package/README.md +8 -5
  2. package/dist/cli.d.mts +5 -0
  3. package/dist/cli.mjs +33 -129
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/combine-rules-CWp-M491.mjs +66 -0
  6. package/dist/combine-rules-CWp-M491.mjs.map +1 -0
  7. package/dist/dependencies/bundle-require.d.mts +1 -0
  8. package/dist/dependencies/bundle-require.mjs +3 -3
  9. package/dist/dependencies/cac.d.mts +1 -0
  10. package/dist/dependencies/cac.mjs +3 -3
  11. package/dist/dependencies/glob.d.mts +1 -0
  12. package/dist/dependencies/glob.mjs +3 -3
  13. package/dist/dependencies/inquirer.d.mts +1 -0
  14. package/dist/dependencies/inquirer.mjs +3 -3
  15. package/dist/dependencies/pkg-types.d.mts +1 -0
  16. package/dist/dependencies/pkg-types.mjs +3 -3
  17. package/dist/dependencies/sort-package-json.d.mts +2 -0
  18. package/dist/dependencies/sort-package-json.mjs +5 -4
  19. package/dist/dependencies/sort-package-json.mjs.map +1 -1
  20. package/dist/dependencies/tsdown.d.mts +1 -0
  21. package/dist/dependencies/tsdown.mjs +3 -0
  22. package/dist/optimize-layer-CK8NR_VC.mjs +58 -0
  23. package/dist/optimize-layer-CK8NR_VC.mjs.map +1 -0
  24. package/dist/optimize-media-Bxy27Cj7.mjs +86 -0
  25. package/dist/optimize-media-Bxy27Cj7.mjs.map +1 -0
  26. package/dist/plugboy.d.mts +6284 -0
  27. package/dist/plugboy.mjs +3 -103
  28. package/dist/runtime-utils.d.mts +28 -0
  29. package/dist/runtime-utils.mjs +94 -0
  30. package/dist/runtime-utils.mjs.map +1 -0
  31. package/dist/workspace-BqcryYAT.mjs +1391 -0
  32. package/dist/workspace-BqcryYAT.mjs.map +1 -0
  33. package/env.d.ts +0 -18
  34. package/package.json +15 -12
  35. package/dist/chunk-IDJLTVUE.mjs +0 -1619
  36. package/dist/chunk-IDJLTVUE.mjs.map +0 -1
  37. package/dist/cli.d.ts +0 -3
  38. package/dist/combine-rules-2CRG6D4B.mjs +0 -69
  39. package/dist/combine-rules-2CRG6D4B.mjs.map +0 -1
  40. package/dist/dependencies/bundle-require.d.ts +0 -7
  41. package/dist/dependencies/bundle-require.mjs.map +0 -1
  42. package/dist/dependencies/cac.d.ts +0 -1
  43. package/dist/dependencies/cac.mjs.map +0 -1
  44. package/dist/dependencies/esbuild.d.ts +0 -1
  45. package/dist/dependencies/esbuild.mjs +0 -3
  46. package/dist/dependencies/esbuild.mjs.map +0 -1
  47. package/dist/dependencies/glob.d.ts +0 -1
  48. package/dist/dependencies/glob.mjs.map +0 -1
  49. package/dist/dependencies/inquirer.d.ts +0 -1
  50. package/dist/dependencies/inquirer.mjs.map +0 -1
  51. package/dist/dependencies/pkg-types.d.ts +0 -1
  52. package/dist/dependencies/pkg-types.mjs.map +0 -1
  53. package/dist/dependencies/sort-package-json.d.ts +0 -2
  54. package/dist/dependencies/tsup.d.ts +0 -1
  55. package/dist/dependencies/tsup.mjs +0 -3
  56. package/dist/dependencies/tsup.mjs.map +0 -1
  57. package/dist/optimize-layer-Q35C25P4.mjs +0 -61
  58. package/dist/optimize-layer-Q35C25P4.mjs.map +0 -1
  59. package/dist/optimize-media-ZZWDHLLV.mjs +0 -99
  60. package/dist/optimize-media-ZZWDHLLV.mjs.map +0 -1
  61. package/dist/plugboy.d.ts +0 -777
  62. 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