@powerlines/nx 0.10.9 → 0.10.11

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 (44) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/{chunk-WUF54G5K.js → chunk-32RH3DSY.js} +1408 -1228
  3. package/dist/{chunk-QJEIBIEZ.js → chunk-7SWNXVZN.js} +2 -2
  4. package/dist/{chunk-VP7AMTR6.js → chunk-DKRIOFPB.js} +2 -2
  5. package/dist/{chunk-DVGRVHRD.mjs → chunk-FMYWKI25.mjs} +2 -14
  6. package/dist/{chunk-IUHTUUDE.js → chunk-FZWXH2M7.js} +2 -2
  7. package/dist/{chunk-L5RBARDS.js → chunk-HAP4APOA.js} +3 -3
  8. package/dist/{chunk-M647TAWI.mjs → chunk-IWLY4VEK.mjs} +1 -1
  9. package/dist/{chunk-3TWAKTYR.mjs → chunk-K7X3KSVW.mjs} +1 -1
  10. package/dist/{chunk-4S5RU53T.js → chunk-KJAIPQKC.js} +2 -2
  11. package/dist/{chunk-T52ZTHWM.mjs → chunk-KNIZUAS5.mjs} +1 -1
  12. package/dist/{chunk-UOTRU26N.js → chunk-LTCZN4I4.js} +1 -19
  13. package/dist/{chunk-R4LYPNZD.mjs → chunk-NSFCCGL7.mjs} +1 -1
  14. package/dist/{chunk-QWEMU3V4.mjs → chunk-NSLIDWKJ.mjs} +1 -1
  15. package/dist/{chunk-B3UMNKEM.js → chunk-QJLAFC2D.js} +2 -2
  16. package/dist/{chunk-AX3G6RLK.mjs → chunk-RIB65IPA.mjs} +1 -1
  17. package/dist/{chunk-3WPWHDP3.mjs → chunk-WMZ45WVV.mjs} +1411 -1231
  18. package/dist/executors.js +12 -12
  19. package/dist/executors.mjs +7 -7
  20. package/dist/index.js +14 -14
  21. package/dist/index.mjs +8 -8
  22. package/dist/src/base/base-executor.js +3 -3
  23. package/dist/src/base/base-executor.mjs +2 -2
  24. package/dist/src/executors/build/executor.js +5 -5
  25. package/dist/src/executors/build/executor.mjs +3 -3
  26. package/dist/src/executors/build/schema.d.ts +85 -0
  27. package/dist/src/executors/clean/executor.js +5 -5
  28. package/dist/src/executors/clean/executor.mjs +3 -3
  29. package/dist/src/executors/clean/schema.d.ts +75 -0
  30. package/dist/src/executors/docs/executor.js +5 -5
  31. package/dist/src/executors/docs/executor.mjs +3 -3
  32. package/dist/src/executors/docs/schema.d.ts +75 -0
  33. package/dist/src/executors/lint/executor.js +5 -5
  34. package/dist/src/executors/lint/executor.mjs +3 -3
  35. package/dist/src/executors/lint/schema.d.ts +75 -0
  36. package/dist/src/executors/prepare/executor.js +5 -5
  37. package/dist/src/executors/prepare/executor.mjs +3 -3
  38. package/dist/src/executors/prepare/schema.d.ts +75 -0
  39. package/dist/src/executors/prepare/schema.json +77 -0
  40. package/dist/src/generators/sync/schema.d.ts +15 -0
  41. package/dist/src/generators/sync/schema.json +19 -0
  42. package/dist/src/plugin/index.js +3 -3
  43. package/dist/src/plugin/index.mjs +2 -2
  44. package/package.json +7 -7
@@ -1,9 +1,9 @@
1
- import { __VFS_CACHE__, __VFS_RESOLVER__, __VFS_VIRTUAL__, __VFS_UNIFIED__, __VFS_INIT__, __VFS_REVERT__, loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, getChecksum, loadUserConfigFile, writeMetaFile } from './chunk-DVGRVHRD.mjs';
1
+ import { loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, getChecksum, loadUserConfigFile, writeMetaFile } from './chunk-FMYWKI25.mjs';
2
2
  import { __name } from './chunk-O6YSETKJ.mjs';
3
3
  import { getLogFn, getLogLevel, writeError } from '@storm-software/config-tools/logger';
4
4
  import { withRunExecutor } from '@storm-software/workspace-tools/base/base-executor';
5
5
  import { isError } from '@stryke/type-checks/is-error';
6
- import defu3, { defu } from 'defu';
6
+ import defu2, { defu } from 'defu';
7
7
  import { transformAsync } from '@babel/core';
8
8
  import { formatLogMessage } from '@storm-software/config-tools/logger/console';
9
9
  import { LogLevelLabel } from '@storm-software/config-tools/types';
@@ -15,7 +15,7 @@ import { install } from '@stryke/fs/install';
15
15
  import { listFiles, listFilesSync } from '@stryke/fs/list-files';
16
16
  import { isPackageExists, isPackageListed, doesPackageMatch, getPackageListing } from '@stryke/fs/package-fns';
17
17
  import { resolvePackage } from '@stryke/fs/resolve';
18
- import { joinPaths } from '@stryke/path/join-paths';
18
+ import { joinPaths as joinPaths$1 } from '@stryke/path/join-paths';
19
19
  import { replacePath, replaceExtension } from '@stryke/path/replace';
20
20
  import { isFunction } from '@stryke/type-checks/is-function';
21
21
  import { isNumber } from '@stryke/type-checks/is-number';
@@ -36,28 +36,30 @@ import { getUnique, getUniqueBy } from '@stryke/helpers/get-unique';
36
36
  import { omit } from '@stryke/helpers/omit';
37
37
  import { StormJSON } from '@stryke/json/storm-json';
38
38
  import { appendPath } from '@stryke/path/append';
39
- import { findFilePath, findFileDotExtensionSafe, hasFileExtension, relativePath, findFileName } from '@stryke/path/file-path-fns';
39
+ import { findFileDotExtensionSafe, findFilePath, hasFileExtension, relativePath, findFileName } from '@stryke/path/file-path-fns';
40
40
  import { isAbsolutePath, isAbsolute } from '@stryke/path/is-type';
41
- import { joinPaths as joinPaths$1 } from '@stryke/path/join';
41
+ import { joinPaths } from '@stryke/path/join';
42
42
  import { isNull } from '@stryke/type-checks/is-null';
43
43
  import { isString } from '@stryke/type-checks/is-string';
44
44
  import { uuid } from '@stryke/unique-id/uuid';
45
45
  import { parseAsync } from 'oxc-parser';
46
46
  import { parseTypeDefinition } from '@stryke/convert/parse-type-definition';
47
47
  import { isFile } from '@stryke/fs/is-file';
48
- import { getColor } from '@storm-software/config-tools/utilities/colors';
49
- import { noop } from '@stryke/helpers/noop';
50
- import { isUndefined } from '@stryke/type-checks/is-undefined';
51
- import { createJiti } from 'jiti';
48
+ import * as $ from '@stryke/capnp';
52
49
  import { bufferToString } from '@stryke/convert/buffer-to-string';
53
- import { isParentPath } from '@stryke/path/is-parent-path';
50
+ import { readFileBuffer, readFileBufferSync, writeFileBuffer } from '@stryke/fs/buffer';
54
51
  import { prettyBytes } from '@stryke/string-format/pretty-bytes';
55
52
  import { isBuffer } from '@stryke/type-checks/is-buffer';
56
- import { Volume } from 'memfs';
57
53
  import { Blob } from 'node:buffer';
58
54
  import fs from 'node:fs';
59
55
  import { resolveConfig, format } from 'prettier';
56
+ import { getColor } from '@storm-software/config-tools/utilities/colors';
57
+ import { noop } from '@stryke/helpers/noop';
58
+ import { isUndefined } from '@stryke/type-checks/is-undefined';
59
+ import { isParentPath } from '@stryke/path/is-parent-path';
60
+ import { Volume } from 'memfs/lib/node/volume';
60
61
  import { Union } from 'unionfs';
62
+ import { createJiti } from 'jiti';
61
63
  import { isObject } from '@stryke/type-checks/is-object';
62
64
  import ts2, { createProgram, createCompilerHost, getPreEmitDiagnostics, getLineAndCharacterOfPosition, flattenDiagnosticMessageText } from 'typescript';
63
65
  import { getPackageName, hasPackageVersion, getPackageVersion } from '@stryke/string-format/package';
@@ -66,12 +68,12 @@ import { loadTsConfig } from '@stryke/fs/tsconfig';
66
68
  import { writeFile as writeFile$1 } from '@stryke/fs/write-file';
67
69
  import { isDevelopmentMode, isTestMode } from '@stryke/env/environment-checks';
68
70
  import { createVitePlugin, createEsbuildPlugin, createWebpackPlugin, createRolldownPlugin, createRollupPlugin, createRspackPlugin, createUnloaderPlugin } from 'unplugin';
71
+ import { camelCase } from '@stryke/string-format/camel-case';
69
72
  import { match, tsconfigPathsToRegExp } from 'bundle-require';
70
73
  import '@stryke/fs/read-file';
71
74
  import 'magic-string';
72
75
  import { defineNuxtModule, addVitePlugin, addWebpackPlugin } from '@nuxt/kit';
73
76
  import '@nuxt/schema';
74
- import * as $ from '@stryke/capnp';
75
77
 
76
78
  function resolveModulePath(nodePath, state) {
77
79
  if (!t.isStringLiteral(nodePath.node)) {
@@ -176,7 +178,7 @@ var moduleResolverBabelPlugin = /* @__PURE__ */ __name((context) => {
176
178
  }, "moduleResolverBabelPlugin");
177
179
  var DEFAULT_ENVIRONMENT = "default";
178
180
  function createEnvironment(name, userConfig) {
179
- return defu3(userConfig.environments?.[name] ?? {}, {
181
+ return defu2(userConfig.environments?.[name] ?? {}, {
180
182
  name,
181
183
  title: userConfig.title || titleCase(userConfig.name),
182
184
  ssr: false,
@@ -219,8 +221,17 @@ function createDefaultEnvironment(userConfig) {
219
221
  return createEnvironment(DEFAULT_ENVIRONMENT, userConfig);
220
222
  }
221
223
  __name(createDefaultEnvironment, "createDefaultEnvironment");
224
+ function replacePathTokens(context, path) {
225
+ if (!path) {
226
+ return path;
227
+ }
228
+ return path.replaceAll("{workspaceRoot}", context.workspaceConfig.workspaceRoot).replaceAll("{root}", context.config.projectRoot).replaceAll("{projectRoot}", context.config.projectRoot).replaceAll("{powerlinesPath}", context.powerlinesPath).replaceAll("{cachePath}", context.cachePath).replaceAll("{dataPath}", context.dataPath).replaceAll("{logPath}", context.envPaths.log).replaceAll("{tempPath}", context.envPaths.temp).replaceAll("{configPath}", context.envPaths.config).replaceAll("{artifactsPath}", replacePath(context.artifactsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{builtinPath}", replacePath(context.builtinsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{entryPath}", replacePath(context.entryPath, context.workspaceConfig.workspaceRoot));
229
+ }
230
+ __name(replacePathTokens, "replacePathTokens");
231
+
232
+ // ../powerlines/src/lib/entry.ts
222
233
  function resolveEntryInputFile(context, typeDefinition) {
223
- return replacePath(typeDefinition.file, joinPaths(context.workspaceConfig.workspaceRoot, context.config.projectRoot));
234
+ return replacePath(typeDefinition.file, joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot));
224
235
  }
225
236
  __name(resolveEntryInputFile, "resolveEntryInputFile");
226
237
  function resolveEntryInput(context, typeDefinition) {
@@ -231,7 +242,7 @@ function resolveEntryInput(context, typeDefinition) {
231
242
  }
232
243
  __name(resolveEntryInput, "resolveEntryInput");
233
244
  function resolveEntryOutput(context, typeDefinition) {
234
- return replaceExtension(replacePath(replacePath(replacePath(replacePath(replacePath(typeDefinition.file, joinPaths(context.workspaceConfig.workspaceRoot, context.config.sourceRoot)), joinPaths(context.workspaceConfig.workspaceRoot, context.config.projectRoot)), context.config.sourceRoot), context.config.projectRoot), replacePath(context.config.sourceRoot, context.config.projectRoot)));
245
+ return replaceExtension(replacePath(replacePath(replacePath(replacePath(replacePath(typeDefinition.file, joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.sourceRoot)), joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot)), context.config.sourceRoot), context.config.projectRoot), replacePath(context.config.sourceRoot, context.config.projectRoot)));
235
246
  }
236
247
  __name(resolveEntryOutput, "resolveEntryOutput");
237
248
  function resolveEntry(context, typeDefinition) {
@@ -244,7 +255,7 @@ function resolveEntry(context, typeDefinition) {
244
255
  }
245
256
  __name(resolveEntry, "resolveEntry");
246
257
  function resolveEntriesSync(context, typeDefinitions) {
247
- return typeDefinitions.map((typeDefinition) => {
258
+ return typeDefinitions.map((entry) => isString(entry) ? replacePathTokens(context, entry) : replacePathTokens(context, entry.file)).map((typeDefinition) => {
248
259
  const parsed = parseTypeDefinition(typeDefinition);
249
260
  const filePath = appendPath(parsed.file, context.config.projectRoot);
250
261
  if (isFile(filePath)) {
@@ -266,6 +277,232 @@ function getUniqueEntries(entries = []) {
266
277
  }));
267
278
  }
268
279
  __name(getUniqueEntries, "getUniqueEntries");
280
+ BigInt("0xa56c61324b9d6e49");
281
+ var FileMetadata_KeyValuePair = class extends $.Struct {
282
+ static {
283
+ __name(this, "FileMetadata_KeyValuePair");
284
+ }
285
+ static _capnp = {
286
+ displayName: "KeyValuePair",
287
+ id: "eabb26cf58b2a14c",
288
+ size: new $.ObjectSize(0, 2)
289
+ };
290
+ get key() {
291
+ return $.utils.getText(0, this);
292
+ }
293
+ set key(value) {
294
+ $.utils.setText(0, value, this);
295
+ }
296
+ get value() {
297
+ return $.utils.getText(1, this);
298
+ }
299
+ set value(value) {
300
+ $.utils.setText(1, value, this);
301
+ }
302
+ toString() {
303
+ return "FileMetadata_KeyValuePair_" + super.toString();
304
+ }
305
+ };
306
+ var FileMetadata = class _FileMetadata extends $.Struct {
307
+ static {
308
+ __name(this, "FileMetadata");
309
+ }
310
+ static KeyValuePair = FileMetadata_KeyValuePair;
311
+ static _capnp = {
312
+ displayName: "FileMetadata",
313
+ id: "8e2cab5d7e28c7b3",
314
+ size: new $.ObjectSize(0, 4),
315
+ defaultVariant: "normal"
316
+ };
317
+ static _Properties;
318
+ /**
319
+ * The variant of the file.
320
+ *
321
+ */
322
+ get id() {
323
+ return $.utils.getText(0, this);
324
+ }
325
+ set id(value) {
326
+ $.utils.setText(0, value, this);
327
+ }
328
+ /**
329
+ * The output mode of the file.
330
+ *
331
+ */
332
+ get variant() {
333
+ return $.utils.getText(1, this, _FileMetadata._capnp.defaultVariant);
334
+ }
335
+ set variant(value) {
336
+ $.utils.setText(1, value, this);
337
+ }
338
+ /**
339
+ * Additional metadata associated with the file.
340
+ *
341
+ */
342
+ get mode() {
343
+ return $.utils.getText(2, this);
344
+ }
345
+ set mode(value) {
346
+ $.utils.setText(2, value, this);
347
+ }
348
+ _adoptProperties(value) {
349
+ $.utils.adopt(value, $.utils.getPointer(3, this));
350
+ }
351
+ _disownProperties() {
352
+ return $.utils.disown(this.properties);
353
+ }
354
+ get properties() {
355
+ return $.utils.getList(3, _FileMetadata._Properties, this);
356
+ }
357
+ _hasProperties() {
358
+ return !$.utils.isNull($.utils.getPointer(3, this));
359
+ }
360
+ _initProperties(length) {
361
+ return $.utils.initList(3, _FileMetadata._Properties, length, this);
362
+ }
363
+ set properties(value) {
364
+ $.utils.copyFrom(value, $.utils.getPointer(3, this));
365
+ }
366
+ toString() {
367
+ return "FileMetadata_" + super.toString();
368
+ }
369
+ };
370
+ var FileIdentifier = class extends $.Struct {
371
+ static {
372
+ __name(this, "FileIdentifier");
373
+ }
374
+ static _capnp = {
375
+ displayName: "FileIdentifier",
376
+ id: "e12b8732389d7406",
377
+ size: new $.ObjectSize(0, 2)
378
+ };
379
+ /**
380
+ * An additional identifier for the file.
381
+ *
382
+ */
383
+ get path() {
384
+ return $.utils.getText(0, this);
385
+ }
386
+ set path(value) {
387
+ $.utils.setText(0, value, this);
388
+ }
389
+ get id() {
390
+ return $.utils.getText(1, this);
391
+ }
392
+ set id(value) {
393
+ $.utils.setText(1, value, this);
394
+ }
395
+ toString() {
396
+ return "FileIdentifier_" + super.toString();
397
+ }
398
+ };
399
+ var FileData = class extends $.Struct {
400
+ static {
401
+ __name(this, "FileData");
402
+ }
403
+ static _capnp = {
404
+ displayName: "FileData",
405
+ id: "fa6725c8a360f9a2",
406
+ size: new $.ObjectSize(0, 2)
407
+ };
408
+ /**
409
+ * The contents of the file.
410
+ *
411
+ */
412
+ get path() {
413
+ return $.utils.getText(0, this);
414
+ }
415
+ set path(value) {
416
+ $.utils.setText(0, value, this);
417
+ }
418
+ get content() {
419
+ return $.utils.getText(1, this);
420
+ }
421
+ set content(value) {
422
+ $.utils.setText(1, value, this);
423
+ }
424
+ toString() {
425
+ return "FileData_" + super.toString();
426
+ }
427
+ };
428
+ var FileSystemData = class _FileSystemData extends $.Struct {
429
+ static {
430
+ __name(this, "FileSystemData");
431
+ }
432
+ static _capnp = {
433
+ displayName: "FileSystemData",
434
+ id: "aaa72a672ac0732f",
435
+ size: new $.ObjectSize(0, 3)
436
+ };
437
+ static _Ids;
438
+ static _Metadata;
439
+ static _Files;
440
+ _adoptIds(value) {
441
+ $.utils.adopt(value, $.utils.getPointer(0, this));
442
+ }
443
+ _disownIds() {
444
+ return $.utils.disown(this.ids);
445
+ }
446
+ get ids() {
447
+ return $.utils.getList(0, _FileSystemData._Ids, this);
448
+ }
449
+ _hasIds() {
450
+ return !$.utils.isNull($.utils.getPointer(0, this));
451
+ }
452
+ _initIds(length) {
453
+ return $.utils.initList(0, _FileSystemData._Ids, length, this);
454
+ }
455
+ set ids(value) {
456
+ $.utils.copyFrom(value, $.utils.getPointer(0, this));
457
+ }
458
+ _adoptMetadata(value) {
459
+ $.utils.adopt(value, $.utils.getPointer(1, this));
460
+ }
461
+ _disownMetadata() {
462
+ return $.utils.disown(this.metadata);
463
+ }
464
+ get metadata() {
465
+ return $.utils.getList(1, _FileSystemData._Metadata, this);
466
+ }
467
+ _hasMetadata() {
468
+ return !$.utils.isNull($.utils.getPointer(1, this));
469
+ }
470
+ _initMetadata(length) {
471
+ return $.utils.initList(1, _FileSystemData._Metadata, length, this);
472
+ }
473
+ set metadata(value) {
474
+ $.utils.copyFrom(value, $.utils.getPointer(1, this));
475
+ }
476
+ _adoptFiles(value) {
477
+ $.utils.adopt(value, $.utils.getPointer(2, this));
478
+ }
479
+ _disownFiles() {
480
+ return $.utils.disown(this.files);
481
+ }
482
+ get files() {
483
+ return $.utils.getList(2, _FileSystemData._Files, this);
484
+ }
485
+ _hasFiles() {
486
+ return !$.utils.isNull($.utils.getPointer(2, this));
487
+ }
488
+ _initFiles(length) {
489
+ return $.utils.initList(2, _FileSystemData._Files, length, this);
490
+ }
491
+ set files(value) {
492
+ $.utils.copyFrom(value, $.utils.getPointer(2, this));
493
+ }
494
+ toString() {
495
+ return "FileSystemData_" + super.toString();
496
+ }
497
+ };
498
+ FileMetadata._Properties = $.CompositeList(FileMetadata_KeyValuePair);
499
+ FileSystemData._Ids = $.CompositeList(FileIdentifier);
500
+ FileSystemData._Metadata = $.CompositeList(FileMetadata);
501
+ FileSystemData._Files = $.CompositeList(FileData);
502
+
503
+ // ../powerlines/src/types/vfs.ts
504
+ var __VFS_PATCH__ = Symbol("__VFS_PATCH__");
505
+ var __VFS_REVERT__ = Symbol("__VFS_REVERT__");
269
506
  var createLog = /* @__PURE__ */ __name((name, options = {}) => {
270
507
  const logLevel = options.logLevel === null ? LogLevelLabel.SILENT : options.logLevel || LogLevelLabel.INFO;
271
508
  if (logLevel === LogLevelLabel.SILENT) {
@@ -304,96 +541,8 @@ var BADGE_COLORS = [
304
541
  var extendLog = /* @__PURE__ */ __name((logFn, name) => {
305
542
  return (type, ...args) => logFn(type, ` ${chalk5.inverse.hex(BADGE_COLORS[name.split("").map((char) => char.charCodeAt(0)).reduce((ret, charCode) => ret + charCode, 0) % BADGE_COLORS.length] || BADGE_COLORS[0])(` ${titleCase(name)} `)} ${args.join(" ")} `);
306
543
  }, "extendLog");
307
-
308
- // ../powerlines/src/types/commands.ts
309
- var SUPPORTED_COMMANDS = [
310
- "new",
311
- "clean",
312
- "prepare",
313
- "lint",
314
- "test",
315
- "build",
316
- "docs",
317
- "release",
318
- "finalize"
319
- ];
320
-
321
- // ../powerlines/src/plugin-utils/helpers.ts
322
- function isPlugin(value) {
323
- return isSetObject(value) && "name" in value && isSetString(value.name) && (isUndefined(value.applyToEnvironment) || "applyToEnvironment" in value && isFunction(value.applyToEnvironment)) && (isUndefined(value.dedupe) || "dedupe" in value && isFunction(value.dedupe)) && (isUndefined(value.dependsOn) || "dependsOn" in value && Array.isArray(value.dependsOn) && value.dependsOn.every(isPluginConfig)) && SUPPORTED_COMMANDS.every((command) => isUndefined(value[command]) || command in value && (isFunction(value[command]) || isSetObject(value[command]) && "handler" in value[command] && isFunction(value[command].handler)));
324
- }
325
- __name(isPlugin, "isPlugin");
326
- function isPluginConfigObject(value) {
327
- return isSetObject(value) && "plugin" in value && ((isSetString(value.plugin) || isFunction(value.plugin)) && "options" in value && isSetObject(value.options) || isPlugin(value.plugin));
328
- }
329
- __name(isPluginConfigObject, "isPluginConfigObject");
330
- function isPluginConfigTuple(value) {
331
- return Array.isArray(value) && (value.length === 1 || value.length === 2) && ((isSetString(value[0]) || isFunction(value[0])) && value.length > 1 && isSetObject(value[1]) || isPlugin(value[0]));
332
- }
333
- __name(isPluginConfigTuple, "isPluginConfigTuple");
334
- function isPluginConfig(value) {
335
- return isSetString(value) || isFunction(value) || isPlugin(value) || isPluginConfigObject(value) || isPluginConfigTuple(value);
336
- }
337
- __name(isPluginConfig, "isPluginConfig");
338
- function isPluginHookFunction(value) {
339
- return isFunction(value) || isSetObject(value) && "handler" in value && isFunction(value.handler);
340
- }
341
- __name(isPluginHookFunction, "isPluginHookFunction");
342
- function isPluginHookObject(value) {
343
- return isSetObject(value) && "handler" in value && isFunction(value.handler);
344
- }
345
- __name(isPluginHookObject, "isPluginHookObject");
346
- function isPluginHook(value) {
347
- return isPluginHookFunction(value) || isPluginHookObject(value);
348
- }
349
- __name(isPluginHook, "isPluginHook");
350
- function getHookHandler(pluginHook) {
351
- return isFunction(pluginHook) ? pluginHook : pluginHook.handler;
352
- }
353
- __name(getHookHandler, "getHookHandler");
354
- function isHookExternal(hook) {
355
- return hook.startsWith("vite:") || hook.startsWith("esbuild:") || hook.startsWith("rolldown:") || hook.startsWith("rollup:") || hook.startsWith("webpack:") || hook.startsWith("rspack:") || hook.startsWith("farm:");
356
- }
357
- __name(isHookExternal, "isHookExternal");
358
- function checkDedupe(plugin, plugins2) {
359
- return plugin.dedupe === false || plugins2.some((p) => p.dedupe !== false && (isFunction(p.dedupe) && p.dedupe(plugin) || p.name === plugin.name));
360
- }
361
- __name(checkDedupe, "checkDedupe");
362
- function addPluginHook(context, plugin, pluginHook, hooksList) {
363
- if (!checkDedupe(plugin, hooksList.map((hook) => hook.plugin))) {
364
- hooksList.push(isFunction(pluginHook) ? {
365
- plugin,
366
- handler: getHookHandler(pluginHook).bind(context)
367
- } : {
368
- plugin,
369
- ...pluginHook,
370
- handler: getHookHandler(pluginHook).bind(context)
371
- });
372
- }
373
- }
374
- __name(addPluginHook, "addPluginHook");
375
- function resolveOptions(options) {
376
- return defu3(options, {
377
- interopDefault: true,
378
- fsCache: options.mode !== "development" ? joinPaths(options.cacheDir, "jiti") : false,
379
- moduleCache: options.mode !== "development"
380
- });
381
- }
382
- __name(resolveOptions, "resolveOptions");
383
- function createPluginResolver(options) {
384
- return createJiti(joinPaths(options.workspaceRoot, options.projectRoot), resolveOptions({
385
- ...options
386
- }));
387
- }
388
- __name(createPluginResolver, "createPluginResolver");
389
- function createResolver(options) {
390
- const baseResolver = createJiti(joinPaths(options.workspaceRoot, options.projectRoot), resolveOptions(options));
391
- baseResolver.plugin = createPluginResolver(options);
392
- return baseResolver;
393
- }
394
- __name(createResolver, "createResolver");
395
- function isBufferEncoding(options) {
396
- return isSetString(options) || options === null;
544
+ function isBufferEncoding(options) {
545
+ return isSetString(options) || options === null;
397
546
  }
398
547
  __name(isBufferEncoding, "isBufferEncoding");
399
548
  function isPowerlinesWriteFileOptions(options) {
@@ -540,160 +689,71 @@ function patchFS(originalFS, vfs) {
540
689
  };
541
690
  }
542
691
  __name(patchFS, "patchFS");
543
- var VirtualFileSystem = class {
692
+ var UnifiedFS = class _UnifiedFS extends Union {
544
693
  static {
545
- __name(this, "VirtualFileSystem");
694
+ __name(this, "UnifiedFS");
546
695
  }
547
696
  /**
548
697
  * The internal map of virtual files.
549
698
  */
550
- #meta = {};
551
- /**
552
- * A map of unique identifiers to their virtual file paths.
553
- */
554
- #ids = {};
555
- /**
556
- * A map of virtual file paths to their underlying file content.
557
- */
558
- #cachedFS = /* @__PURE__ */ new Map();
559
- /**
560
- * A map of virtual file paths to their underlying file content.
561
- */
562
- #cachedResolver = /* @__PURE__ */ new Map();
563
- /**
564
- * The internal map of virtual files.
565
- */
566
699
  #virtualFS = new Volume();
567
700
  /**
568
701
  * The physical file system.
569
702
  */
570
- #fs = cloneFS(fs);
571
- /**
572
- * The unified volume that combines the virtual file system with the real file system.
573
- *
574
- * @remarks
575
- * This volume allows for seamless access to both virtual and real files.
576
- */
577
- #unifiedFS = new Union();
578
- /**
579
- * Indicator specifying if the file system module is patched
580
- */
581
- #isPatched = false;
582
- /**
583
- * Function to revert require patch
584
- */
585
- #revert;
703
+ #physicalFS = cloneFS(fs);
586
704
  /**
587
- * The context of the virtual file system.
705
+ * The context of the unified file system.
588
706
  */
589
707
  #context;
590
- /**
591
- * The file system's logging function.
592
- */
593
- #log;
594
- /**
595
- * Checks if a path exists in the virtual file system (VFS).
596
- *
597
- * @param path - The path to check.
598
- * @returns `true` if the path exists, otherwise `false`.
599
- */
600
- #existsSync(path) {
601
- const formattedPath = this.formatPath(path);
602
- return this.#virtualFS.existsSync(formattedPath) || this.#fs.existsSync(formattedPath) || this.resolveFS(path).existsSync(formattedPath);
603
- }
604
- /**
605
- * Exposes the internal VFS map for advanced usage.
606
- */
607
- get [__VFS_CACHE__]() {
608
- return this.#cachedFS;
609
- }
610
- /**
611
- * Exposes the internal VFS resolver cache for advanced usage.
612
- */
613
- get [__VFS_RESOLVER__]() {
614
- return this.#cachedResolver;
708
+ static create(context, data) {
709
+ let result = new _UnifiedFS(context, data);
710
+ result = result.use(result.#physicalFS);
711
+ if (result.#context.config.output.mode !== "fs") {
712
+ result = result.use(result.#virtualFS);
713
+ }
714
+ return result;
615
715
  }
616
716
  /**
617
- * Exposes the internal VFS map for advanced usage.
717
+ * Gets the virtual file system (VFS).
618
718
  */
619
- get [__VFS_VIRTUAL__]() {
719
+ get virtual() {
620
720
  return this.#virtualFS;
621
721
  }
622
722
  /**
623
- * Exposes the internal UFS map for advanced usage.
624
- */
625
- get [__VFS_UNIFIED__]() {
626
- return this.#unifiedFS;
627
- }
628
- /**
629
- * A proxy to access the underlying file metadata.
630
- */
631
- get meta() {
632
- return new Proxy(this.#meta, {
633
- get: /* @__PURE__ */ __name((target, prop) => {
634
- if (target[prop]) {
635
- return {
636
- id: prop,
637
- mode: this.#virtualFS.existsSync(prop) ? "virtual" : this.#fs.existsSync(prop) ? "fs" : this.#context.config.output.mode,
638
- details: {},
639
- variant: "normal",
640
- ...target[prop]
641
- };
642
- }
643
- return void 0;
644
- }, "get"),
645
- set: /* @__PURE__ */ __name((target, prop, value) => {
646
- target[prop] = value;
647
- this.#ids[value.id || prop] = prop;
648
- return true;
649
- }, "set"),
650
- deleteProperty: /* @__PURE__ */ __name((target, prop) => {
651
- delete this.#ids[target[prop]?.id || prop];
652
- delete target[prop];
653
- return true;
654
- }, "deleteProperty")
655
- });
656
- }
657
- /**
658
- * A map of module ids to their file paths.
723
+ * Gets the physical file system (FS).
659
724
  */
660
- get ids() {
661
- return this.#ids;
725
+ get physical() {
726
+ return this.#physicalFS;
662
727
  }
663
728
  /**
664
729
  * Creates a new instance of the VirtualFileSystem.
665
730
  *
666
731
  * @param context - The context of the virtual file system, typically containing options and logging functions.
667
- * @param serialized - A map of files/file contents to populate in cache
732
+ * @param data - A buffer containing the serialized virtual file system data.
668
733
  */
669
- constructor(context, serialized = {}) {
734
+ constructor(context, data) {
735
+ super();
670
736
  this.#context = context;
671
- this.#cachedFS = /* @__PURE__ */ new Map();
672
- this.#meta = Object.fromEntries(Object.entries(serialized.virtualFilesMeta ?? {}));
673
- this.#ids = Object.fromEntries(Object.entries(this.#meta).map(([path, data]) => [
674
- data.id || path,
675
- path
676
- ]));
677
- if (!this.#fs.existsSync(this.#context.dataPath)) {
678
- this.#fs.mkdirSync(this.#context.dataPath, {
737
+ if (!this.#physicalFS.existsSync(this.#context.dataPath)) {
738
+ this.#physicalFS.mkdirSync(this.#context.dataPath, {
679
739
  recursive: true
680
740
  });
681
741
  }
682
- if (!this.#fs.existsSync(this.#context.cachePath)) {
683
- this.#fs.mkdirSync(this.#context.cachePath, {
742
+ if (!this.#physicalFS.existsSync(this.#context.cachePath)) {
743
+ this.#physicalFS.mkdirSync(this.#context.cachePath, {
684
744
  recursive: true
685
745
  });
686
746
  }
687
- if (!this.#fs.existsSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath))) {
688
- this.#fs.mkdirSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath), {
747
+ if (!this.#physicalFS.existsSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath))) {
748
+ this.#physicalFS.mkdirSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath), {
689
749
  recursive: true
690
750
  });
691
751
  }
692
- this.#unifiedFS = this.#unifiedFS.use(this.#fs);
693
752
  if (this.#context.config.output.mode !== "fs") {
694
- if (serialized?.virtualFiles && Object.keys(serialized.virtualFiles).length > 0) {
695
- this.#virtualFS = Volume.fromJSON(serialized.virtualFiles);
696
- }
753
+ this.#virtualFS = Volume.fromJSON(data._hasFiles() && data.files.length > 0 ? data.files.values().reduce((ret, file) => {
754
+ ret[file.path] = file.content;
755
+ return ret;
756
+ }, {}) : {});
697
757
  if (!this.#virtualFS.existsSync(this.#context.artifactsPath)) {
698
758
  this.#virtualFS.mkdirSync(this.#context.artifactsPath, {
699
759
  recursive: true
@@ -714,926 +774,1168 @@ var VirtualFileSystem = class {
714
774
  recursive: true
715
775
  });
716
776
  }
717
- this.#unifiedFS = this.#unifiedFS.use(this.#virtualFS);
718
777
  } else if (this.#context.config.projectType === "application") {
719
- if (!this.#fs.existsSync(this.#context.artifactsPath)) {
720
- this.#fs.mkdirSync(this.#context.artifactsPath, {
778
+ if (!this.#physicalFS.existsSync(this.#context.artifactsPath)) {
779
+ this.#physicalFS.mkdirSync(this.#context.artifactsPath, {
721
780
  recursive: true
722
781
  });
723
782
  }
724
- if (!this.#fs.existsSync(this.#context.builtinsPath)) {
725
- this.#fs.mkdirSync(this.#context.builtinsPath, {
783
+ if (!this.#physicalFS.existsSync(this.#context.builtinsPath)) {
784
+ this.#physicalFS.mkdirSync(this.#context.builtinsPath, {
726
785
  recursive: true
727
786
  });
728
787
  }
729
- if (!this.#fs.existsSync(this.#context.entryPath)) {
730
- this.#fs.mkdirSync(this.#context.entryPath, {
788
+ if (!this.#physicalFS.existsSync(this.#context.entryPath)) {
789
+ this.#physicalFS.mkdirSync(this.#context.entryPath, {
731
790
  recursive: true
732
791
  });
733
792
  }
734
- if (!this.#fs.existsSync(this.#context.dtsPath)) {
735
- this.#fs.mkdirSync(this.#context.dtsPath, {
793
+ if (!this.#physicalFS.existsSync(this.#context.dtsPath)) {
794
+ this.#physicalFS.mkdirSync(this.#context.dtsPath, {
736
795
  recursive: true
737
796
  });
738
797
  }
739
798
  }
740
- this.#log = extendLog(this.#context.log, "virtual-file-system");
741
- }
742
- [__VFS_INIT__]() {
743
- if (!this.#isPatched && this.#context.config.output.mode !== "fs") {
744
- this.#revert = patchFS(fs, this);
745
- this.#isPatched = true;
746
- }
747
- }
748
- [__VFS_REVERT__]() {
749
- if (this.#isPatched && this.#context.config.output.mode !== "fs") {
750
- if (!this.#revert) {
751
- throw new Error("Attempting to revert File System patch prior to calling `__init__` function");
752
- }
753
- this.#revert?.();
754
- this.#isPatched = false;
755
- }
756
799
  }
757
800
  /**
758
- * Check if a path or id corresponds to a virtual file **(does not actually exists on disk)**.
801
+ * Select the file system module to use for the operation based on the path or URL.
759
802
  *
760
- * @param pathOrId - The path or id to check.
761
- * @param options - Optional parameters for resolving the path.
762
- * @returns Whether the path or id corresponds to a virtual file **(does not actually exists on disk)**.
803
+ * @param pathOrUrl - The path to perform the file system operation on.
804
+ * @param options - Options for the operation, such as output mode.
805
+ * @returns The file system module used for the operation.
763
806
  */
764
- isVirtual(pathOrId, options = {}) {
765
- if (!pathOrId) {
766
- return false;
767
- }
768
- const resolvedPath = this.resolve(pathOrId, {
769
- ...options,
770
- type: "file"
771
- });
772
- if (!resolvedPath) {
773
- return false;
807
+ resolveFS(pathOrUrl, options = {}) {
808
+ const mode = this.resolveMode(pathOrUrl, options);
809
+ if (mode === "virtual") {
810
+ return {
811
+ ...this.#virtualFS,
812
+ mode: "virtual"
813
+ };
814
+ } else if (mode === "fs") {
815
+ return {
816
+ ...this.#physicalFS,
817
+ mode: "fs"
818
+ };
774
819
  }
775
- return this.meta[resolvedPath]?.mode === "virtual";
820
+ return {
821
+ ...this,
822
+ mode: this.#context.config.output.mode
823
+ };
776
824
  }
777
825
  /**
778
- * Check if a path or id corresponds to a file written to the file system **(actually exists on disk)**.
826
+ * Select the file system module to use for the operation based on the path or URL.
779
827
  *
780
- * @param pathOrId - The path or id to check.
781
- * @param options - Optional parameters for resolving the path.
782
- * @returns Whether the path or id corresponds to a file written to the file system **(actually exists on disk)**.
828
+ * @param pathOrUrl - The path to perform the file system operation on.
829
+ * @param options - Options for the operation, such as output mode.
830
+ * @returns The file system module used for the operation.
783
831
  */
784
- isFs(pathOrId, options = {}) {
785
- if (!pathOrId) {
786
- return false;
787
- }
788
- const resolvedPath = this.resolve(pathOrId, {
789
- ...options,
790
- type: "file"
791
- });
792
- if (!resolvedPath) {
793
- return false;
832
+ resolveMode(pathOrUrl, options = {}) {
833
+ if (options.mode === "virtual" && this.#context.config.output.mode !== "fs" && isParentPath(toFilePath(pathOrUrl), this.#context.artifactsPath)) {
834
+ return "virtual";
835
+ } else if (options.mode === "fs" || this.#context.config.output.mode === "fs" || isParentPath(toFilePath(pathOrUrl), this.#context.dataPath) || isParentPath(toFilePath(pathOrUrl), this.#context.cachePath) || isParentPath(toFilePath(pathOrUrl), joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath))) {
836
+ return "fs";
794
837
  }
795
- return this.meta[resolvedPath]?.mode === "fs";
838
+ return void 0;
796
839
  }
797
840
  /**
798
- * Check if a path exists within one of the directories specified in the tsconfig.json's `path` field.
841
+ * Serializes the virtual file system (VFS) to a JSON object.
799
842
  *
800
- * @see https://www.typescriptlang.org/tsconfig#paths
801
- *
802
- * @param pathOrId - The path or ID to check.
803
- * @returns Whether the path or ID corresponds to a virtual file.
843
+ * @returns A JSON representation of the virtual file system.
804
844
  */
805
- isTsconfigPath(pathOrId) {
806
- return !!this.#context.tsconfig.options.paths && Object.keys(this.#context.tsconfig.options.paths).some((path) => pathOrId.startsWith(path.replaceAll("*", "")));
845
+ toJSON() {
846
+ return this.#virtualFS.toJSON();
847
+ }
848
+ };
849
+
850
+ // ../powerlines/src/lib/fs/vfs.ts
851
+ var VirtualFileSystem = class _VirtualFileSystem {
852
+ static {
853
+ __name(this, "VirtualFileSystem");
807
854
  }
808
855
  /**
809
- * Lists files in a given path.
810
- *
811
- * @param path - The path to list files from.
812
- * @param options - Options for listing files, such as encoding and recursion.
813
- * @returns An array of file names in the specified path.
856
+ * A map of virtual file IDs to their associated metadata.
814
857
  */
815
- readdirSync(path, options = "utf8") {
816
- return this.resolveFS(path).readdirSync(toFilePath(path), options);
817
- }
858
+ #metadata;
818
859
  /**
819
- * Removes a file in the virtual file system (VFS).
820
- *
821
- * @param path - The path to create the directory at.
860
+ * A map of virtual file IDs to their underlying file paths.
822
861
  */
823
- unlinkSync(path, options) {
824
- const formattedPath = toFilePath(path);
825
- if (!this.isFile(formattedPath)) {
826
- return;
827
- }
828
- this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${formattedPath}`);
829
- this.resolveFS(path, options).unlinkSync(formattedPath);
830
- this.#cachedFS.delete(formattedPath);
831
- this.clearResolverCache(formattedPath);
832
- }
862
+ #ids;
833
863
  /**
834
- * Removes a file in the virtual file system (VFS).
835
- *
836
- * @param path - The path to create the directory at.
864
+ * A map of underlying file paths to their virtual file IDs.
837
865
  */
838
- async unlink(path, options) {
839
- const formattedPath = toFilePath(path);
840
- if (!this.isFile(formattedPath)) {
841
- return;
842
- }
843
- this.#log(LogLevelLabel.TRACE, `Removing file: ${formattedPath}`);
844
- if (isFunction(this.resolveFS(path, options).promises.unlink)) {
845
- await this.resolveFS(path, options).promises.unlink(formattedPath);
846
- this.#cachedFS.delete(formattedPath);
847
- this.clearResolverCache(formattedPath);
848
- } else {
849
- this.unlinkSync(formattedPath, options);
850
- }
851
- }
866
+ #paths;
852
867
  /**
853
- * Removes a directory in the virtual file system (VFS).
854
- *
855
- * @param path - The path to create the directory at.
856
- * @param options - Options for creating the directory.
868
+ * A map of virtual file paths to their underlying file content.
857
869
  */
858
- rmdirSync(path, options = {}) {
859
- const formattedPath = toFilePath(path);
860
- if (!this.isDirectory(formattedPath)) {
861
- return;
862
- }
863
- this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${formattedPath}`);
864
- this.resolveFS(path, options).rmdirSync(formattedPath, defu3(options, {
865
- recursive: true
866
- }));
867
- this.#cachedFS.delete(formattedPath);
868
- this.clearResolverCache(formattedPath);
869
- }
870
+ #cachedResolver = /* @__PURE__ */ new Map();
870
871
  /**
871
- * Removes a directory in the virtual file system (VFS).
872
+ * The unified volume that combines the virtual file system with the real file system.
872
873
  *
873
- * @param path - The path to create the directory at.
874
- * @param options - Options for creating the directory.
875
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
874
+ * @remarks
875
+ * This volume allows for seamless access to both virtual and real files.
876
876
  */
877
- async rmdir(path, options = {}) {
878
- const formattedPath = toFilePath(path);
879
- if (!this.isDirectory(formattedPath)) {
880
- return;
881
- }
882
- this.#log(LogLevelLabel.TRACE, `Removing directory: ${formattedPath}`);
883
- if (isFunction(this.resolveFS(path, options).promises.rm)) {
884
- await this.resolveFS(path, options).promises.rm(formattedPath, defu3(options, {
885
- force: true,
886
- recursive: true
887
- }));
888
- this.#cachedFS.delete(formattedPath);
889
- this.clearResolverCache(formattedPath);
890
- } else {
891
- this.rmdirSync(formattedPath, defu3(options ?? {}, {
892
- force: true,
893
- recursive: true
894
- }));
895
- }
896
- }
877
+ #unifiedFS;
897
878
  /**
898
- * Removes a file in the virtual file system (VFS).
879
+ * Indicator specifying if the file system module is patched
880
+ */
881
+ #isPatched = false;
882
+ /**
883
+ * Indicator specifying if the virtual file system (VFS) is disposed
884
+ */
885
+ #isDisposed = false;
886
+ /**
887
+ * Function to revert require patch
888
+ */
889
+ #revert;
890
+ /**
891
+ * The context of the virtual file system.
892
+ */
893
+ #context;
894
+ /**
895
+ * The file system's logging function.
896
+ */
897
+ #log;
898
+ /**
899
+ * Checks if a path exists in the virtual file system (VFS).
899
900
  *
900
- * @param path - The path to the file to remove.
901
- * @param options - Options for removing the file.
902
- * @returns A promise that resolves when the file is removed.
901
+ * @param path - The path to check.
902
+ * @returns `true` if the path exists, otherwise `false`.
903
903
  */
904
- async rm(path, options = {}) {
905
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
906
- if (this.isDirectory(path)) {
907
- return this.rmdir(path, options);
908
- }
909
- return this.unlink(path, options);
904
+ #existsSync(path) {
905
+ const formattedPath = this.formatPath(path);
906
+ return this.#unifiedFS.virtual.existsSync(formattedPath) || this.#unifiedFS.physical.existsSync(formattedPath) || this.#unifiedFS.resolveFS(path).existsSync(formattedPath);
910
907
  }
911
908
  /**
912
- * Synchronously removes a file or directory in the virtual file system (VFS).
909
+ * Builds a regular expression from a string pattern for path matching.
913
910
  *
914
- * @param path - The path to the file or directory to remove.
915
- * @param options - Options for removing the file or directory.
911
+ * @param strPattern - The string pattern to convert.
912
+ * @returns A regular expression for matching paths.
916
913
  */
917
- rmSync(path, options = {}) {
918
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
919
- if (this.isDirectory(path)) {
920
- return this.rmdirSync(path, options);
921
- }
922
- return this.unlinkSync(path, options);
914
+ #buildRegex(strPattern) {
915
+ const token = "::GLOBSTAR::";
916
+ return new RegExp(`^${this.formatPath(strPattern).replace(/\*\*/g, token).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(token, "g"), ".*")}$`);
923
917
  }
924
918
  /**
925
- * Creates a directory in the virtual file system (VFS).
919
+ * Formats a file id by removing the file extension and prepending the runtime prefix.
926
920
  *
927
- * @param path - The path to create the directory at.
928
- * @param options - Options for creating the directory.
929
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
921
+ * @param id - The file ID to format.
922
+ * @returns The formatted file ID.
930
923
  */
931
- mkdirSync(path, options = {}) {
932
- const filePath = toFilePath(path);
933
- this.clearResolverCache(filePath);
934
- return this.resolveFS(filePath, options).mkdirSync(filePath, defu3(options ?? {}, {
935
- recursive: true
936
- }));
924
+ #formatId(id) {
925
+ const formattedId = toFilePath(id);
926
+ return `${this.#context.config.output.builtinPrefix}:${formattedId.replace(new RegExp(`^${this.#context.config.output.builtinPrefix}:`), "").replace(/^\\0/, "").replace(findFileDotExtensionSafe(formattedId), "")}`;
937
927
  }
938
928
  /**
939
- * Creates a directory in the virtual file system (VFS).
929
+ * Resolves an id parameter to a corresponding virtual file path in the virtual file system (VFS).
940
930
  *
941
- * @param path - The path to create the directory at.
942
- * @param options - Options for creating the directory.
943
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
931
+ * @param id - The id to resolve.
932
+ * @returns The resolved file id if it exists, otherwise undefined.
944
933
  */
945
- async mkdir(path, options = {}) {
946
- let result;
947
- const filePath = toFilePath(path);
948
- if (isFunction(this.resolveFS(filePath, options).promises.mkdir)) {
949
- result = await this.resolveFS(filePath, options).promises.mkdir(filePath, defu3(options ?? {}, {
950
- recursive: true
951
- }));
952
- } else {
953
- result = this.resolveFS(filePath, options).mkdirSync(filePath, defu3(options ?? {}, {
954
- recursive: true
955
- }));
934
+ #resolveId(id) {
935
+ if (this.#ids[this.#formatId(id)]) {
936
+ return this.#ids[this.#formatId(id)] || false;
956
937
  }
957
- this.clearResolverCache(filePath);
958
- return result;
938
+ return false;
959
939
  }
960
940
  /**
961
- * Glob files in the virtual file system (VFS) based on the provided pattern(s).
941
+ * Resolves a path parameter to a corresponding virtual file path in the virtual file system (VFS).
962
942
  *
963
- * @param patterns - A pattern (or multiple patterns) to use to determine the file paths to return
964
- * @returns An array of file paths matching the provided pattern(s)
943
+ * @param path - The path to resolve.
944
+ * @param options - Optional parameters for resolving the path.
945
+ * @returns The resolved file path if it exists, otherwise undefined.
965
946
  */
966
- async glob(patterns) {
967
- const results = [];
968
- for (const pattern of toArray(patterns)) {
969
- const normalized = this.formatPath(pattern);
970
- if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
971
- const resolved = this.resolve(normalized, {
972
- type: "file"
973
- });
974
- if (resolved && !results.includes(resolved)) {
975
- results.push(resolved);
976
- }
977
- continue;
947
+ #resolvePath(path, options = {}) {
948
+ if (isAbsolutePath(path)) {
949
+ if (this.#existsSync(path)) {
950
+ return path;
978
951
  }
979
- const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths(this.#context.workspaceConfig.workspaceRoot, normalized));
980
- const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
981
- const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
982
- const stack = [
983
- baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
984
- ];
985
- while (stack.length) {
986
- const dir = stack.pop();
987
- let entries = [];
988
- try {
989
- entries = await this.readdir(dir);
990
- } catch {
991
- continue;
992
- }
993
- for (const entry of entries) {
994
- const full = this.formatPath(joinPaths(dir, entry));
995
- let stats;
996
- try {
997
- stats = this.#unifiedFS.lstatSync(full);
998
- } catch {
999
- stats = void 0;
1000
- }
1001
- if (!stats) continue;
1002
- if (stats.isDirectory()) {
1003
- stack.push(full);
1004
- } else if (stats.isFile()) {
1005
- if (this.buildRegex(absPattern).test(full)) {
1006
- const resolved = this.resolve(full, {
1007
- type: "file"
1008
- });
1009
- if (resolved && !results.includes(resolved)) {
1010
- results.push(resolved);
1011
- }
1012
- }
1013
- }
1014
- }
952
+ const result = this.#checkVariants(path);
953
+ if (result) {
954
+ return result;
1015
955
  }
1016
956
  }
1017
- return results;
1018
- }
1019
- /**
1020
- * Synchronously glob files in the virtual file system (VFS) based on the provided pattern(s).
1021
- *
1022
- * @param patterns - A pattern (or multiple patterns) to use to determine the file paths to return
1023
- * @returns An array of file paths matching the provided pattern(s)
1024
- */
1025
- globSync(patterns) {
1026
- const results = [];
1027
- for (const pattern of toArray(patterns)) {
1028
- const normalized = this.formatPath(pattern);
1029
- if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
1030
- const resolved = this.resolve(normalized, {
1031
- type: "file"
1032
- });
1033
- if (resolved && !results.includes(resolved)) {
1034
- results.push(resolved);
1035
- }
1036
- continue;
957
+ for (const parentPath of this.#resolveParentPaths(path, options.paths)) {
958
+ const request = joinPaths$1(parentPath, path);
959
+ if (this.#existsSync(request)) {
960
+ return request;
1037
961
  }
1038
- const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths(this.#context.workspaceConfig.workspaceRoot, normalized));
1039
- const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
1040
- const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
1041
- const stack = [
1042
- baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
1043
- ];
1044
- while (stack.length) {
1045
- const dir = stack.pop();
1046
- let entries = [];
1047
- try {
1048
- entries = this.readdirSync(dir);
1049
- } catch {
1050
- continue;
1051
- }
1052
- for (const entry of entries) {
1053
- const full = this.formatPath(joinPaths(dir, entry));
1054
- let stats;
1055
- try {
1056
- stats = this.#unifiedFS.lstatSync(full);
1057
- } catch {
1058
- stats = void 0;
1059
- }
1060
- if (!stats) continue;
1061
- if (stats.isDirectory()) {
1062
- stack.push(full);
1063
- } else if (stats.isFile()) {
1064
- if (this.buildRegex(absPattern).test(full)) {
1065
- const resolved = this.resolve(full, {
1066
- type: "file"
1067
- });
1068
- if (resolved && !results.includes(resolved)) {
1069
- results.push(resolved);
1070
- }
1071
- }
1072
- }
1073
- }
962
+ const result = this.#checkVariants(request);
963
+ if (result) {
964
+ return result;
1074
965
  }
1075
966
  }
1076
- return results;
967
+ return false;
1077
968
  }
1078
969
  /**
1079
- * Moves a file from one path to another in the virtual file system (VFS).
970
+ * Resolves parent paths for a given request.
1080
971
  *
1081
- * @param srcPath - The source path to move
1082
- * @param destPath - The destination path to move to
972
+ * @param request - The request path to resolve parent paths for.
973
+ * @param parents - An optional array of parent paths to consider.
974
+ * @returns An array of resolved parent paths.
1083
975
  */
1084
- async move(srcPath, destPath) {
1085
- const content = await this.readFile(srcPath);
1086
- await this.writeFile(destPath, content);
1087
- await this.rm(srcPath);
976
+ #resolveParentPaths(request, parents = []) {
977
+ let paths = [
978
+ this.#context.workspaceConfig.workspaceRoot,
979
+ joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot)
980
+ ];
981
+ if (this.#context.tsconfig.options.paths) {
982
+ paths = this.#context.tsconfig.options.paths ? Object.keys(this.#context.tsconfig.options.paths).filter((tsconfigPath) => request.startsWith(tsconfigPath.replaceAll("*", ""))).map((tsconfigPath) => this.#context.tsconfig.options.paths?.[tsconfigPath]).flat().reduce((ret, path) => {
983
+ if (path && !ret.includes(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path))) {
984
+ ret.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path));
985
+ }
986
+ return ret;
987
+ }, paths) : paths;
988
+ }
989
+ return paths.reduce((ret, path) => {
990
+ if (!ret.includes(path)) {
991
+ ret.push(path);
992
+ }
993
+ return ret;
994
+ }, parents.filter(Boolean).map((p) => this.formatPath(p)));
1088
995
  }
1089
996
  /**
1090
- * Synchronously moves a file from one path to another in the virtual file system (VFS).
997
+ * Clears the resolver cache for a given path.
1091
998
  *
1092
- * @param srcPath - The source path to move
1093
- * @param destPath - The destination path to move to
999
+ * @param path - The path to clear the resolver cache for.
1094
1000
  */
1095
- moveSync(srcPath, destPath) {
1096
- const content = this.readFileSync(srcPath);
1097
- this.writeFileSync(destPath, content);
1098
- this.rmSync(srcPath);
1001
+ #clearResolverCache(path) {
1002
+ this.#cachedResolver.keys().filter((key) => key.startsWith(toFilePath(path))).forEach((key) => this.#cachedResolver.delete(key));
1099
1003
  }
1100
1004
  /**
1101
- * Copies a file from one path to another in the virtual file system (VFS).
1005
+ * Check if the file exists with different variants (index, extensions).
1102
1006
  *
1103
- * @param srcPath - The source path to copy
1104
- * @param destPath - The destination path to copy to
1007
+ * @param request - The request path to check.
1008
+ * @param parentPath - An optional parent path to prepend to the request.
1009
+ * @returns The file path if it exists, otherwise false.
1105
1010
  */
1106
- async copy(srcPath, destPath) {
1107
- const content = await this.readFile(srcPath);
1108
- await this.writeFile(destPath, content);
1011
+ #checkVariants(request, parentPath) {
1012
+ const path = parentPath ? joinPaths$1(parentPath, request) : request;
1013
+ let file = this.#checkExtensions(path);
1014
+ if (file) {
1015
+ return file;
1016
+ }
1017
+ file = this.#checkIndex(path);
1018
+ if (file) {
1019
+ return file;
1020
+ }
1021
+ return false;
1109
1022
  }
1110
1023
  /**
1111
- * Synchronously copies a file from one path to another in the virtual file system (VFS).
1024
+ * Check if the index file exists in the given request path.
1112
1025
  *
1113
- * @param srcPath - The source path to copy
1114
- * @param destPath - The destination path to copy to
1115
- */
1116
- copySync(srcPath, destPath) {
1117
- const content = this.readFileSync(srcPath);
1118
- this.writeFileSync(destPath, content);
1119
- }
1120
- /**
1121
- * Lists files in a given path.
1122
- *
1123
- * @param pathOrId - The path to list files from.
1124
- * @param options - Options for listing files, such as encoding and recursion.
1125
- * @returns An array of file names in the specified path.
1126
- */
1127
- async readdir(pathOrId, options = "utf8") {
1128
- return this.resolveFS(pathOrId).promises.readdir(toFilePath(pathOrId), options);
1129
- }
1130
- /**
1131
- * Asynchronously reads a file from the virtual file system (VFS).
1132
- *
1133
- * @param pathOrId - The path or ID of the file to read.
1134
- * @returns A promise that resolves to the contents of the file as a string, or undefined if the file does not exist.
1026
+ * @param request - The request path to check.
1027
+ * @returns The index file path if it exists, otherwise false.
1135
1028
  */
1136
- async readFile(pathOrId, options = "utf8") {
1137
- if (!pathOrId) {
1138
- return void 0;
1029
+ #checkIndex(request) {
1030
+ let file = joinPaths$1(request, "index");
1031
+ if (this.#existsSync(file)) {
1032
+ return file;
1139
1033
  }
1140
- const filePath = this.resolve(toFilePath(pathOrId), {
1141
- type: "file"
1142
- });
1143
- if (filePath) {
1144
- if (this.#cachedFS.has(filePath)) {
1145
- return this.#cachedFS.get(filePath);
1146
- }
1147
- let result;
1148
- if (isFunction(this.resolveFS(filePath).promises.readFile)) {
1149
- result = (await this.resolveFS(filePath).promises.readFile(filePath, options))?.toString("utf8");
1150
- } else {
1151
- result = this.resolveFS(filePath).readFileSync(filePath, options);
1152
- }
1153
- const content = isBuffer(result) ? bufferToString(result) : result;
1154
- this.#cachedFS.set(filePath, content);
1155
- return content;
1034
+ file = this.#checkExtensions(file);
1035
+ if (file) {
1036
+ return file;
1156
1037
  }
1157
- return void 0;
1038
+ return false;
1158
1039
  }
1159
1040
  /**
1160
- * Synchronously reads a file from the virtual file system (VFS).
1041
+ * Check if the file exists with different extensions.
1161
1042
  *
1162
- * @param pathOrId - The path or ID of the file to read.
1163
- * @returns The contents of the file as a string, or undefined if the file does not exist.
1043
+ * @param request - The request path to check.
1044
+ * @returns The file path if it exists with any of the checked extensions, otherwise false.
1164
1045
  */
1165
- readFileSync(pathOrId, options = "utf8") {
1166
- if (!pathOrId) {
1167
- return void 0;
1046
+ #checkExtensions(request) {
1047
+ let file = `${request}.ts`;
1048
+ if (this.#existsSync(file)) {
1049
+ return file;
1168
1050
  }
1169
- const filePath = this.resolve(toFilePath(pathOrId), {
1170
- type: "file"
1171
- });
1172
- if (filePath) {
1173
- if (this.#cachedFS.has(filePath)) {
1174
- return this.#cachedFS.get(filePath);
1175
- }
1176
- const result = this.resolveFS(filePath).readFileSync(filePath, options);
1177
- const content = isBuffer(result) ? bufferToString(result) : result;
1178
- this.#cachedFS.set(filePath, content);
1179
- return content;
1051
+ file = `${request}.mts`;
1052
+ if (this.#existsSync(file)) {
1053
+ return file;
1180
1054
  }
1181
- return void 0;
1182
- }
1183
- /**
1184
- * Writes a file to the virtual file system (VFS).
1185
- *
1186
- * @param path - The path to the file.
1187
- * @param data - The contents of the file.
1188
- * @param options - Optional parameters for writing the file.
1189
- * @returns A promise that resolves when the file is written.
1190
- */
1191
- async writeFile(path, data = "", options = "utf8") {
1192
- const formattedPath = this.formatPath(path);
1193
- if (!this.isDirectory(findFilePath(formattedPath))) {
1194
- await this.mkdir(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
1055
+ file = `${request}.cts`;
1056
+ if (this.#existsSync(file)) {
1057
+ return file;
1195
1058
  }
1196
- let code = isPowerLinesWriteFileData(data) ? data.code : data;
1197
- if ((!isPowerlinesWriteFileOptions(options) || !options.skipFormat) && isSetString(code)) {
1198
- const resolvedConfig = await resolveConfig(formattedPath);
1199
- if (resolvedConfig) {
1200
- code = await format(code, {
1201
- absolutePath: formattedPath,
1202
- ...resolvedConfig
1203
- });
1204
- }
1059
+ file = `${request}.tsx`;
1060
+ if (this.#existsSync(file)) {
1061
+ return file;
1205
1062
  }
1206
- const outputMode = this.resolveOutputMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1207
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1208
- this.meta[formattedPath] = {
1209
- path: formattedPath,
1210
- code,
1211
- mode: outputMode,
1212
- variant: "normal",
1213
- ...isPowerLinesWriteFileData(data) ? data : {}
1214
- };
1215
- this.clearResolverCache(formattedPath);
1216
- const ifs = this.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1217
- if (isFunction(ifs.promises.writeFile)) {
1218
- return ifs.promises.writeFile(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1063
+ file = `${request}.js`;
1064
+ if (this.#existsSync(file)) {
1065
+ return file;
1219
1066
  }
1220
- return ifs.writeFileSync(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1067
+ file = `${request}.mjs`;
1068
+ if (this.#existsSync(file)) {
1069
+ return file;
1070
+ }
1071
+ file = `${request}.cjs`;
1072
+ if (this.#existsSync(file)) {
1073
+ return file;
1074
+ }
1075
+ file = `${request}.jsx`;
1076
+ if (this.#existsSync(file)) {
1077
+ return file;
1078
+ }
1079
+ file = `${request}.json`;
1080
+ if (this.#existsSync(file)) {
1081
+ return file;
1082
+ }
1083
+ file = `${request}.d.ts`;
1084
+ if (this.#existsSync(file)) {
1085
+ return file;
1086
+ }
1087
+ return false;
1221
1088
  }
1222
1089
  /**
1223
- * Synchronously writes a file to the virtual file system (VFS).
1090
+ * Creates a virtual file system (VFS) that is backed up to a Cap'n Proto message buffer.
1224
1091
  *
1225
- * @param path - The file to write.
1226
- * @param data - The contents of the file.
1227
- * @param options - Optional parameters for writing the file.
1092
+ * @param context - The context of the virtual file system, typically containing options and logging functions.
1093
+ * @returns A promise that resolves to a new virtual file system instance.
1228
1094
  */
1229
- writeFileSync(path, data = "", options = "utf8") {
1230
- const formattedPath = this.formatPath(path);
1231
- if (!this.isDirectory(findFilePath(formattedPath))) {
1232
- this.mkdirSync(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
1233
- }
1234
- const code = isPowerLinesWriteFileData(data) ? data.code : data;
1235
- const outputMode = this.resolveOutputMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1236
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1237
- this.meta[formattedPath] = {
1238
- path: formattedPath,
1239
- code,
1240
- mode: outputMode,
1241
- variant: "normal",
1242
- ...isPowerLinesWriteFileData(data) ? data : {}
1243
- };
1244
- this.clearResolverCache(formattedPath);
1245
- const writeStream = this.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0).createWriteStream(formattedPath);
1246
- try {
1247
- writeStream.write(code);
1248
- } finally {
1249
- writeStream.close();
1095
+ static async create(context) {
1096
+ if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1097
+ const buffer = await readFileBuffer(joinPaths$1(context.cachePath, "fs.bin"));
1098
+ const message2 = new $.Message(buffer, false);
1099
+ return new _VirtualFileSystem(context, message2.getRoot(FileSystemData));
1250
1100
  }
1101
+ const message = new $.Message();
1102
+ return new _VirtualFileSystem(context, message.initRoot(FileSystemData));
1251
1103
  }
1252
1104
  /**
1253
- * Synchronously checks if a file exists in the virtual file system (VFS).
1105
+ * Synchronously creates a virtual file system (VFS) that is backed up to a Cap'n Proto message buffer.
1254
1106
  *
1255
- * @param pathOrId - The path or ID of the file to check.
1256
- * @returns `true` if the file exists, otherwise `false`.
1107
+ * @param context - The context of the virtual file system, typically containing options and logging functions.
1108
+ * @returns A new virtual file system instance.
1257
1109
  */
1258
- existsSync(pathOrId) {
1259
- return this.resolve(pathOrId) !== false;
1110
+ static createSync(context) {
1111
+ if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1112
+ const buffer = readFileBufferSync(joinPaths$1(context.cachePath, "fs.bin"));
1113
+ const message2 = new $.Message(buffer, false);
1114
+ return new _VirtualFileSystem(context, message2.getRoot(FileSystemData));
1115
+ }
1116
+ const message = new $.Message();
1117
+ return new _VirtualFileSystem(context, message.initRoot(FileSystemData));
1260
1118
  }
1261
1119
  /**
1262
- * Retrieves the metadata of a file in the virtual file system (VFS).
1263
- *
1264
- * @param pathOrId - The path or ID of the file to retrieve metadata for.
1265
- * @returns The metadata of the file, or undefined if the file does not exist.
1120
+ * A map of file ids to their metadata.
1266
1121
  */
1267
- getMetadata(pathOrId) {
1268
- const resolved = this.resolve(pathOrId);
1269
- if (resolved && this.meta[resolved]) {
1270
- return this.meta[resolved];
1271
- }
1272
- return void 0;
1122
+ get metadata() {
1123
+ return this.#metadata;
1273
1124
  }
1274
1125
  /**
1275
- * Checks if a file exists in the virtual file system (VFS).
1276
- *
1277
- * @remarks
1278
- * This is a base method used by {@link existsSync} - it does not try to resolve the path prior to checking if it exists or not.
1279
- *
1280
- * @param pathOrId - The path of the file to check.
1281
- * @returns `true` if the file exists, otherwise `false`.
1126
+ * A map of module ids to their file paths.
1282
1127
  */
1283
- isFile(pathOrId) {
1284
- const resolved = this.resolve(pathOrId);
1285
- return !!(resolved && (this.#virtualFS.existsSync(resolved) && this.#virtualFS.lstatSync(resolved).isFile() || this.#fs.existsSync(resolved) && this.#fs.lstatSync(resolved).isFile() || this.resolveFS(resolved).existsSync(resolved) && this.resolveFS(resolved).lstatSync(resolved).isFile()));
1128
+ get ids() {
1129
+ return this.#ids;
1286
1130
  }
1287
1131
  /**
1288
- * Checks if a directory exists in the virtual file system (VFS).
1289
- *
1290
- * @param pathOrId - The path of the directory to check.
1291
- * @returns `true` if the directory exists, otherwise `false`.
1132
+ * A map of virtual file paths to their IDs.
1292
1133
  */
1293
- isDirectory(pathOrId) {
1294
- const resolved = this.resolve(pathOrId);
1295
- return !!(resolved && (this.#virtualFS.existsSync(resolved) && this.#virtualFS.lstatSync(resolved).isDirectory() || this.#fs.existsSync(resolved) && this.#fs.lstatSync(resolved).isDirectory() || this.resolveFS(resolved).existsSync(resolved) && this.resolveFS(resolved).lstatSync(resolved).isDirectory()));
1134
+ get paths() {
1135
+ return this.#paths;
1296
1136
  }
1297
1137
  /**
1298
- * Retrieves the status of a file in the virtual file system (VFS).
1138
+ * Creates a new instance of the {@link VirtualFileSystem}.
1299
1139
  *
1300
- * @param pathOrId - The path or ID of the file to retrieve status for.
1301
- * @returns A promise that resolves to the file's status information, or false if the file does not exist.
1140
+ * @param context - The context of the virtual file system, typically containing options and logging functions.
1141
+ * @param data - A buffer containing the serialized virtual file system data.
1302
1142
  */
1303
- async stat(pathOrId, options) {
1304
- return this.resolveFS(pathOrId).promises.stat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1143
+ constructor(context, data) {
1144
+ this.#context = context;
1145
+ this.#unifiedFS = UnifiedFS.create(context, data);
1146
+ this.#metadata = {};
1147
+ if (data._hasMetadata()) {
1148
+ this.#metadata = data.metadata.values().reduce((ret, data2) => {
1149
+ ret[data2.id] = {
1150
+ id: data2.id,
1151
+ variant: data2.variant,
1152
+ mode: data2.mode,
1153
+ properties: data2._hasProperties() ? data2.properties.values().reduce((ret2, item) => {
1154
+ ret2[item.key] = item.value;
1155
+ return ret2;
1156
+ }, {}) : {}
1157
+ };
1158
+ return ret;
1159
+ }, {});
1160
+ }
1161
+ this.#ids = {};
1162
+ this.#paths = {};
1163
+ if (data._hasIds()) {
1164
+ this.#ids = data.ids.values().reduce((ret, data2) => {
1165
+ ret[data2.id] ??= data2.path;
1166
+ ret[data2.path] ??= data2.path;
1167
+ return ret;
1168
+ }, {});
1169
+ this.#paths = data.ids.values().reduce((ret, data2) => {
1170
+ ret[data2.path] ??= data2.id;
1171
+ return ret;
1172
+ }, {});
1173
+ }
1174
+ this.#log = extendLog(this.#context.log, "file-system");
1305
1175
  }
1306
1176
  /**
1307
- * Synchronously retrieves the status of a file in the virtual file system (VFS).
1177
+ * Check if a path or id corresponds to a virtual file **(does not actually exists on disk)**.
1308
1178
  *
1309
- * @param pathOrId - The path or ID of the file to retrieve status for.
1310
- * @returns The file's status information, or false if the file does not exist.
1179
+ * @param pathOrId - The path or id to check.
1180
+ * @param options - Optional parameters for resolving the path.
1181
+ * @returns Whether the path or id corresponds to a virtual file **(does not actually exists on disk)**.
1311
1182
  */
1312
- statSync(pathOrId) {
1313
- return this.resolveFS(pathOrId).statSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId));
1183
+ isVirtual(pathOrId, options = {}) {
1184
+ if (!pathOrId) {
1185
+ return false;
1186
+ }
1187
+ const resolvedPath = this.resolve(pathOrId, {
1188
+ ...options,
1189
+ type: "file"
1190
+ });
1191
+ if (!resolvedPath) {
1192
+ return false;
1193
+ }
1194
+ return this.metadata[resolvedPath]?.mode === "virtual";
1314
1195
  }
1315
1196
  /**
1316
- * Retrieves the status of a symbolic link in the virtual file system (VFS).
1197
+ * Check if a path or id corresponds to a file written to the file system **(actually exists on disk)**.
1317
1198
  *
1318
- * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
1319
- * @returns A promise that resolves to the symbolic link's status information, or false if the link does not exist.
1199
+ * @param pathOrId - The path or id to check.
1200
+ * @param options - Optional parameters for resolving the path.
1201
+ * @returns Whether the path or id corresponds to a file written to the file system **(actually exists on disk)**.
1320
1202
  */
1321
- async lstat(pathOrId, options) {
1322
- return this.resolveFS(pathOrId).promises.lstat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1203
+ isPhysical(pathOrId, options = {}) {
1204
+ if (!pathOrId) {
1205
+ return false;
1206
+ }
1207
+ const resolvedPath = this.resolve(pathOrId, {
1208
+ ...options,
1209
+ type: "file"
1210
+ });
1211
+ if (!resolvedPath) {
1212
+ return false;
1213
+ }
1214
+ return this.metadata[resolvedPath]?.mode === "fs";
1323
1215
  }
1324
1216
  /**
1325
- * Synchronously retrieves the status of a symbolic link in the virtual file system (VFS).
1217
+ * Lists files in a given path.
1326
1218
  *
1327
- * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
1328
- * @returns The symbolic link's status information, or false if the link does not exist.
1219
+ * @param path - The path to list files from.
1220
+ * @param options - Options for listing files, such as encoding and recursion.
1221
+ * @returns An array of file names in the specified path.
1329
1222
  */
1330
- lstatSync(pathOrId, options) {
1331
- return this.resolveFS(pathOrId).lstatSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1223
+ readdirSync(path, options = "utf8") {
1224
+ return this.#unifiedFS.resolveFS(path).readdirSync(toFilePath(path), options);
1332
1225
  }
1333
1226
  /**
1334
- * Resolves a path based on TypeScript's `tsconfig.json` paths.
1335
- *
1336
- * @see https://www.typescriptlang.org/tsconfig#paths
1227
+ * Removes a file in the virtual file system (VFS).
1337
1228
  *
1338
- * @param path - The path to check.
1339
- * @returns The resolved file path if it exists, otherwise undefined.
1229
+ * @param path - The path to create the directory at.
1340
1230
  */
1341
- resolveTsconfigPath(path) {
1342
- if (this.#context.tsconfig.options.paths) {
1343
- for (const tsconfigPathKey of Object.keys(this.#context.tsconfig.options.paths).filter((tsconfigPath) => path.startsWith(tsconfigPath.replaceAll("*", "")))) {
1344
- const resolvedPath = this.#context.tsconfig.options.paths[tsconfigPathKey]?.find((tsconfigPath) => this.resolvePath(joinPaths(this.#context.workspaceConfig.workspaceRoot, tsconfigPath.replaceAll("*", ""), path.replace(tsconfigPathKey.replaceAll("*", ""), ""))) || this.formatPath(tsconfigPath) === this.formatPath(path));
1345
- if (resolvedPath) {
1346
- return this.formatPath(resolvedPath) === this.formatPath(path) ? this.formatPath(resolvedPath) : this.resolvePath(joinPaths(this.#context.workspaceConfig.workspaceRoot, resolvedPath.replaceAll("*", ""), path.replace(tsconfigPathKey.replaceAll("*", ""), "")));
1347
- }
1348
- }
1231
+ unlinkSync(path, options) {
1232
+ const formattedPath = toFilePath(path);
1233
+ if (!this.isFile(formattedPath)) {
1234
+ return;
1349
1235
  }
1350
- return false;
1236
+ this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${formattedPath}`);
1237
+ this.#unifiedFS.resolveFS(path, options).unlinkSync(formattedPath);
1238
+ if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1239
+ delete this.metadata[this.paths[formattedPath]];
1240
+ }
1241
+ this.#clearResolverCache(formattedPath);
1351
1242
  }
1352
1243
  /**
1353
- * Resolves a path based on TypeScript's `tsconfig.json` paths.
1354
- *
1355
- * @see https://www.typescriptlang.org/tsconfig#paths
1244
+ * Removes a file in the virtual file system (VFS).
1356
1245
  *
1357
- * @param path - The path to check.
1358
- * @returns The resolved file path if it exists, otherwise undefined.
1246
+ * @param path - The path to create the directory at.
1359
1247
  */
1360
- resolveTsconfigPathPackage(path) {
1361
- if (this.#context.tsconfig.options.paths) {
1362
- const tsconfigPathKeys = Object.keys(this.#context.tsconfig.options.paths).filter((tsconfigPath) => path.startsWith(tsconfigPath.replaceAll("*", "")));
1363
- if (tsconfigPathKeys.length > 0 && tsconfigPathKeys[0]) {
1364
- return tsconfigPathKeys[0].replace(/\/\*$/, "");
1248
+ async unlink(path, options) {
1249
+ const formattedPath = toFilePath(path);
1250
+ if (!this.isFile(formattedPath)) {
1251
+ return;
1252
+ }
1253
+ this.#log(LogLevelLabel.TRACE, `Removing file: ${formattedPath}`);
1254
+ if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.unlink)) {
1255
+ await this.#unifiedFS.resolveFS(path, options).promises.unlink(formattedPath);
1256
+ if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1257
+ delete this.metadata[this.paths[formattedPath]];
1365
1258
  }
1259
+ this.#clearResolverCache(formattedPath);
1260
+ } else {
1261
+ this.unlinkSync(formattedPath, options);
1366
1262
  }
1367
- return false;
1368
1263
  }
1369
1264
  /**
1370
- * Resolves a path or ID to its real path in the virtual file system (VFS).
1265
+ * Removes a directory in the virtual file system (VFS).
1371
1266
  *
1372
- * @param pathOrId - The path or ID to resolve.
1373
- * @returns The resolved real path if it exists, otherwise undefined.
1267
+ * @param path - The path to create the directory at.
1268
+ * @param options - Options for creating the directory.
1374
1269
  */
1375
- realpathSync(pathOrId) {
1376
- const filePath = this.resolve(toFilePath(pathOrId));
1377
- if (!filePath) {
1378
- throw new Error(`File not found: ${toFilePath(pathOrId)}`);
1270
+ rmdirSync(path, options = {}) {
1271
+ const formattedPath = toFilePath(path);
1272
+ if (!this.isDirectory(formattedPath)) {
1273
+ return;
1379
1274
  }
1380
- return filePath;
1275
+ this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${formattedPath}`);
1276
+ this.#unifiedFS.resolveFS(path, options).rmdirSync(formattedPath, defu2(options, {
1277
+ recursive: true
1278
+ }));
1279
+ this.#clearResolverCache(formattedPath);
1381
1280
  }
1382
1281
  /**
1383
- * Resolves a path or ID parameter to a corresponding virtual file path in the virtual file system (VFS).
1282
+ * Removes a directory in the virtual file system (VFS).
1384
1283
  *
1385
- * @param pathOrId - The path or ID to resolve.
1386
- * @param options - Optional parameters for resolving the path, such as whether to include the file extension.
1387
- * @returns The resolved file path if it exists, otherwise undefined.
1284
+ * @param path - The path to create the directory at.
1285
+ * @param options - Options for creating the directory.
1286
+ * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1388
1287
  */
1389
- resolve(pathOrId, options = {}) {
1390
- const formattedPathOrId = toFilePath(pathOrId);
1391
- const resolverKey = `${formattedPathOrId}${options.withExtension ? "-ext" : ""}${options.paths ? `-${murmurhash(options.paths)}` : ""}${options.type ? `-${options.type}` : ""}`;
1392
- if (this.#cachedResolver.has(resolverKey)) {
1393
- return this.#cachedResolver.get(resolverKey);
1394
- }
1395
- let result = this.resolveId(formattedPathOrId);
1396
- if (!result) {
1397
- result = this.resolvePath(formattedPathOrId, options);
1398
- }
1399
- if (!result) {
1400
- result = false;
1288
+ async rmdir(path, options = {}) {
1289
+ const formattedPath = toFilePath(path);
1290
+ if (!this.isDirectory(formattedPath)) {
1291
+ return;
1401
1292
  }
1402
- if (result && options.withExtension === false) {
1403
- return result.replace(/\.[m|c]?[t|j]sx?$/, "");
1293
+ this.#log(LogLevelLabel.TRACE, `Removing directory: ${formattedPath}`);
1294
+ if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.rm)) {
1295
+ await this.#unifiedFS.resolveFS(path, options).promises.rm(formattedPath, defu2(options, {
1296
+ force: true,
1297
+ recursive: true
1298
+ }));
1299
+ this.#clearResolverCache(formattedPath);
1300
+ } else {
1301
+ this.rmdirSync(formattedPath, defu2(options ?? {}, {
1302
+ force: true,
1303
+ recursive: true
1304
+ }));
1404
1305
  }
1405
- this.#cachedResolver.set(resolverKey, result);
1406
- return result;
1407
1306
  }
1408
1307
  /**
1409
- * Retrieves the partial metadata for all files in the virtual file system (VFS).
1308
+ * Removes a file in the virtual file system (VFS).
1410
1309
  *
1411
- * @returns A record containing the partial metadata for all files.
1310
+ * @param path - The path to the file to remove.
1311
+ * @param options - Options for removing the file.
1312
+ * @returns A promise that resolves when the file is removed.
1412
1313
  */
1413
- getPartialMeta() {
1414
- return Object.fromEntries(Object.entries(this.#meta).filter(([_, data]) => isSetObject(data)));
1415
- }
1416
- buildRegex(strPattern) {
1417
- const token = "::GLOBSTAR::";
1418
- return new RegExp(`^${this.formatPath(strPattern).replace(/\*\*/g, token).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(token, "g"), ".*")}$`);
1314
+ async rm(path, options = {}) {
1315
+ this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
1316
+ if (this.isDirectory(path)) {
1317
+ return this.rmdir(path, options);
1318
+ }
1319
+ return this.unlink(path, options);
1419
1320
  }
1420
1321
  /**
1421
- * Converts a relative path to an absolute path based on the workspace and project root.
1322
+ * Synchronously removes a file or directory in the virtual file system (VFS).
1422
1323
  *
1423
- * @param path - The relative path to convert.
1424
- * @returns The absolute path.
1324
+ * @param path - The path to the file or directory to remove.
1325
+ * @param options - Options for removing the file or directory.
1425
1326
  */
1426
- formatPath(path) {
1427
- const formattedPath = toFilePath(path);
1428
- if (isAbsolutePath(formattedPath) || formattedPath.startsWith(this.#context.workspaceConfig.workspaceRoot)) {
1429
- return formattedPath;
1430
- } else if (formattedPath.startsWith(this.#context.config.projectRoot)) {
1431
- return joinPaths(this.#context.workspaceConfig.workspaceRoot, formattedPath);
1327
+ rmSync(path, options = {}) {
1328
+ this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
1329
+ if (this.isDirectory(path)) {
1330
+ return this.rmdirSync(path, options);
1432
1331
  }
1433
- return formattedPath;
1332
+ return this.unlinkSync(path, options);
1434
1333
  }
1435
1334
  /**
1436
- * Formats a file id by removing the file extension and prepending the runtime prefix.
1335
+ * Creates a directory in the virtual file system (VFS).
1437
1336
  *
1438
- * @param id - The file ID to format.
1439
- * @returns The formatted file ID.
1337
+ * @param path - The path to create the directory at.
1338
+ * @param options - Options for creating the directory.
1339
+ * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1440
1340
  */
1441
- formatId(id) {
1442
- const formattedId = toFilePath(id);
1443
- return `${this.#context.config.output.builtinPrefix}:${formattedId.replace(new RegExp(`^${this.#context.config.output.builtinPrefix}:`), "").replace(/^\\0/, "").replace(findFileDotExtensionSafe(formattedId), "")}`;
1341
+ mkdirSync(path, options = {}) {
1342
+ const filePath = toFilePath(path);
1343
+ this.#clearResolverCache(filePath);
1344
+ return this.#unifiedFS.resolveFS(filePath, options).mkdirSync(filePath, defu2(options ?? {}, {
1345
+ recursive: true
1346
+ }));
1444
1347
  }
1445
1348
  /**
1446
- * Resolves an id parameter to a corresponding virtual file path in the virtual file system (VFS).
1349
+ * Creates a directory in the virtual file system (VFS).
1447
1350
  *
1448
- * @param id - The id to resolve.
1449
- * @returns The resolved file id if it exists, otherwise undefined.
1351
+ * @param path - The path to create the directory at.
1352
+ * @param options - Options for creating the directory.
1353
+ * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1450
1354
  */
1451
- resolveId(id) {
1452
- if (this.#ids[this.formatId(id)]) {
1453
- return this.#ids[this.formatId(id)] || false;
1355
+ async mkdir(path, options = {}) {
1356
+ let result;
1357
+ const filePath = toFilePath(path);
1358
+ if (isFunction(this.#unifiedFS.resolveFS(filePath, options).promises.mkdir)) {
1359
+ result = await this.#unifiedFS.resolveFS(filePath, options).promises.mkdir(filePath, defu2(options ?? {}, {
1360
+ recursive: true
1361
+ }));
1362
+ } else {
1363
+ result = this.#unifiedFS.resolveFS(filePath, options).mkdirSync(filePath, defu2(options ?? {}, {
1364
+ recursive: true
1365
+ }));
1454
1366
  }
1455
- return false;
1367
+ this.#clearResolverCache(filePath);
1368
+ return result;
1456
1369
  }
1457
1370
  /**
1458
- * Resolves a path parameter to a corresponding virtual file path in the virtual file system (VFS).
1371
+ * Glob files in the virtual file system (VFS) based on the provided pattern(s).
1459
1372
  *
1460
- * @param path - The path to resolve.
1461
- * @param options - Optional parameters for resolving the path.
1462
- * @returns The resolved file path if it exists, otherwise undefined.
1373
+ * @param patterns - A pattern (or multiple patterns) to use to determine the file paths to return
1374
+ * @returns An array of file paths matching the provided pattern(s)
1463
1375
  */
1464
- resolvePath(path, options = {}) {
1465
- if (isAbsolutePath(path)) {
1466
- if (this.#existsSync(path)) {
1467
- return path;
1468
- }
1469
- const result = this.checkVariants(path);
1470
- if (result) {
1471
- return result;
1472
- }
1473
- }
1474
- for (const parentPath of this.resolveParentPaths(path, options.paths)) {
1475
- const request = joinPaths(parentPath, path);
1476
- if (this.#existsSync(request)) {
1477
- return request;
1376
+ async glob(patterns) {
1377
+ const results = [];
1378
+ for (const pattern of toArray(patterns)) {
1379
+ const normalized = this.formatPath(pattern);
1380
+ if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
1381
+ const resolved = this.resolve(normalized, {
1382
+ type: "file"
1383
+ });
1384
+ if (resolved && !results.includes(resolved)) {
1385
+ results.push(resolved);
1386
+ }
1387
+ continue;
1478
1388
  }
1479
- const result = this.checkVariants(request);
1480
- if (result) {
1481
- return result;
1389
+ const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1390
+ const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
1391
+ const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
1392
+ const stack = [
1393
+ baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
1394
+ ];
1395
+ while (stack.length) {
1396
+ const dir = stack.pop();
1397
+ let entries = [];
1398
+ try {
1399
+ entries = await this.readdir(dir);
1400
+ } catch {
1401
+ continue;
1402
+ }
1403
+ for (const entry of entries) {
1404
+ const full = this.formatPath(joinPaths$1(dir, entry));
1405
+ let stats;
1406
+ try {
1407
+ stats = this.#unifiedFS.lstatSync(full);
1408
+ } catch {
1409
+ stats = void 0;
1410
+ }
1411
+ if (!stats) continue;
1412
+ if (stats.isDirectory()) {
1413
+ stack.push(full);
1414
+ } else if (stats.isFile()) {
1415
+ if (this.#buildRegex(absPattern).test(full)) {
1416
+ const resolved = this.resolve(full, {
1417
+ type: "file"
1418
+ });
1419
+ if (resolved && !results.includes(resolved)) {
1420
+ results.push(resolved);
1421
+ }
1422
+ }
1423
+ }
1424
+ }
1482
1425
  }
1483
1426
  }
1484
- return false;
1427
+ return results;
1485
1428
  }
1486
- resolveParentPaths(request, parents = []) {
1487
- let paths = [
1488
- this.#context.workspaceConfig.workspaceRoot,
1489
- joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot)
1490
- ];
1491
- if (this.#context.tsconfig.options.paths) {
1492
- paths = this.#context.tsconfig.options.paths ? Object.keys(this.#context.tsconfig.options.paths).filter((tsconfigPath) => request.startsWith(tsconfigPath.replaceAll("*", ""))).map((tsconfigPath) => this.#context.tsconfig.options.paths?.[tsconfigPath]).flat().reduce((ret, path) => {
1493
- if (path && !ret.includes(joinPaths(this.#context.workspaceConfig.workspaceRoot, path))) {
1494
- ret.push(joinPaths(this.#context.workspaceConfig.workspaceRoot, path));
1429
+ /**
1430
+ * Synchronously glob files in the virtual file system (VFS) based on the provided pattern(s).
1431
+ *
1432
+ * @param patterns - A pattern (or multiple patterns) to use to determine the file paths to return
1433
+ * @returns An array of file paths matching the provided pattern(s)
1434
+ */
1435
+ globSync(patterns) {
1436
+ const results = [];
1437
+ for (const pattern of toArray(patterns)) {
1438
+ const normalized = this.formatPath(pattern);
1439
+ if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
1440
+ const resolved = this.resolve(normalized, {
1441
+ type: "file"
1442
+ });
1443
+ if (resolved && !results.includes(resolved)) {
1444
+ results.push(resolved);
1495
1445
  }
1496
- return ret;
1497
- }, paths) : paths;
1498
- }
1499
- return paths.reduce((ret, path) => {
1500
- if (!ret.includes(path)) {
1501
- ret.push(path);
1446
+ continue;
1502
1447
  }
1503
- return ret;
1504
- }, parents.filter(Boolean).map((p) => this.formatPath(p)));
1448
+ const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1449
+ const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
1450
+ const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
1451
+ const stack = [
1452
+ baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
1453
+ ];
1454
+ while (stack.length) {
1455
+ const dir = stack.pop();
1456
+ let entries = [];
1457
+ try {
1458
+ entries = this.readdirSync(dir);
1459
+ } catch {
1460
+ continue;
1461
+ }
1462
+ for (const entry of entries) {
1463
+ const full = this.formatPath(joinPaths$1(dir, entry));
1464
+ let stats;
1465
+ try {
1466
+ stats = this.#unifiedFS.lstatSync(full);
1467
+ } catch {
1468
+ stats = void 0;
1469
+ }
1470
+ if (!stats) continue;
1471
+ if (stats.isDirectory()) {
1472
+ stack.push(full);
1473
+ } else if (stats.isFile()) {
1474
+ if (this.#buildRegex(absPattern).test(full)) {
1475
+ const resolved = this.resolve(full, {
1476
+ type: "file"
1477
+ });
1478
+ if (resolved && !results.includes(resolved)) {
1479
+ results.push(resolved);
1480
+ }
1481
+ }
1482
+ }
1483
+ }
1484
+ }
1485
+ }
1486
+ return results;
1505
1487
  }
1506
1488
  /**
1507
- * Select the file system module to use for the operation based on the path or URL.
1489
+ * Moves a file from one path to another in the virtual file system (VFS).
1508
1490
  *
1509
- * @param pathOrUrl - The path to perform the file system operation on.
1510
- * @param options - Options for the operation, such as output mode.
1511
- * @returns The file system module used for the operation.
1491
+ * @param srcPath - The source path to move
1492
+ * @param destPath - The destination path to move to
1512
1493
  */
1513
- resolveFS(pathOrUrl, options = {}) {
1514
- const mode = this.resolveOutputMode(pathOrUrl, options);
1515
- if (mode === "virtual") {
1516
- return this.#virtualFS;
1517
- } else if (mode === "fs") {
1518
- return this.#fs;
1519
- }
1520
- return this.#unifiedFS;
1494
+ async move(srcPath, destPath) {
1495
+ const content = await this.readFile(srcPath);
1496
+ await this.writeFile(destPath, content);
1497
+ await this.rm(srcPath);
1521
1498
  }
1522
1499
  /**
1523
- * Select the file system module to use for the operation based on the path or URL.
1500
+ * Synchronously moves a file from one path to another in the virtual file system (VFS).
1524
1501
  *
1525
- * @param pathOrUrl - The path to perform the file system operation on.
1526
- * @param options - Options for the operation, such as output mode.
1527
- * @returns The file system module used for the operation.
1502
+ * @param srcPath - The source path to move
1503
+ * @param destPath - The destination path to move to
1528
1504
  */
1529
- resolveOutputMode(pathOrUrl, options = {}) {
1530
- if (options.mode === "virtual" && this.#context.config.output.mode !== "fs" && isParentPath(toFilePath(pathOrUrl), this.#context.artifactsPath)) {
1531
- return "virtual";
1532
- } else if (options.mode === "fs" || this.#context.config.output.mode === "fs" || isParentPath(toFilePath(pathOrUrl), this.#context.dataPath) || isParentPath(toFilePath(pathOrUrl), this.#context.cachePath) || isParentPath(toFilePath(pathOrUrl), joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.outputPath))) {
1533
- return "fs";
1505
+ moveSync(srcPath, destPath) {
1506
+ const content = this.readFileSync(srcPath);
1507
+ this.writeFileSync(destPath, content);
1508
+ this.rmSync(srcPath);
1509
+ }
1510
+ /**
1511
+ * Copies a file from one path to another in the virtual file system (VFS).
1512
+ *
1513
+ * @param srcPath - The source path to copy
1514
+ * @param destPath - The destination path to copy to
1515
+ */
1516
+ async copy(srcPath, destPath) {
1517
+ const content = await this.readFile(srcPath);
1518
+ await this.writeFile(destPath, content);
1519
+ }
1520
+ /**
1521
+ * Synchronously copies a file from one path to another in the virtual file system (VFS).
1522
+ *
1523
+ * @param srcPath - The source path to copy
1524
+ * @param destPath - The destination path to copy to
1525
+ */
1526
+ copySync(srcPath, destPath) {
1527
+ const content = this.readFileSync(srcPath);
1528
+ this.writeFileSync(destPath, content);
1529
+ }
1530
+ /**
1531
+ * Lists files in a given path.
1532
+ *
1533
+ * @param pathOrId - The path to list files from.
1534
+ * @param options - Options for listing files, such as encoding and recursion.
1535
+ * @returns An array of file names in the specified path.
1536
+ */
1537
+ async readdir(pathOrId, options = "utf8") {
1538
+ return this.#unifiedFS.resolveFS(pathOrId).promises.readdir(toFilePath(pathOrId), options);
1539
+ }
1540
+ /**
1541
+ * Asynchronously reads a file from the virtual file system (VFS).
1542
+ *
1543
+ * @param pathOrId - The path or ID of the file to read.
1544
+ * @returns A promise that resolves to the contents of the file as a string, or undefined if the file does not exist.
1545
+ */
1546
+ async readFile(pathOrId, options = "utf8") {
1547
+ if (!pathOrId) {
1548
+ return void 0;
1549
+ }
1550
+ const filePath = this.resolve(toFilePath(pathOrId), {
1551
+ type: "file"
1552
+ });
1553
+ if (filePath) {
1554
+ let result;
1555
+ if (isFunction(this.#unifiedFS.resolveFS(filePath).promises.readFile)) {
1556
+ result = (await this.#unifiedFS.resolveFS(filePath).promises.readFile(filePath, options))?.toString("utf8");
1557
+ } else {
1558
+ result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
1559
+ }
1560
+ const content = isBuffer(result) ? bufferToString(result) : result;
1561
+ return content;
1534
1562
  }
1535
1563
  return void 0;
1536
1564
  }
1537
1565
  /**
1538
- * Clears the resolver cache for a given path.
1566
+ * Synchronously reads a file from the virtual file system (VFS).
1539
1567
  *
1540
- * @param path - The path to clear the resolver cache for.
1568
+ * @param pathOrId - The path or ID of the file to read.
1569
+ * @returns The contents of the file as a string, or undefined if the file does not exist.
1541
1570
  */
1542
- clearResolverCache(path) {
1543
- this.#cachedResolver.keys().filter((key) => key.startsWith(toFilePath(path))).forEach((key) => this.#cachedResolver.delete(key));
1571
+ readFileSync(pathOrId, options = "utf8") {
1572
+ if (!pathOrId) {
1573
+ return void 0;
1574
+ }
1575
+ const filePath = this.resolve(toFilePath(pathOrId), {
1576
+ type: "file"
1577
+ });
1578
+ if (filePath) {
1579
+ const result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
1580
+ const content = isBuffer(result) ? bufferToString(result) : result;
1581
+ return content;
1582
+ }
1583
+ return void 0;
1544
1584
  }
1545
1585
  /**
1546
- * Check if the file exists with different variants (index, extensions).
1586
+ * Writes a file to the virtual file system (VFS).
1547
1587
  *
1548
- * @param request - The request path to check.
1549
- * @param parentPath - An optional parent path to prepend to the request.
1550
- * @returns The file path if it exists, otherwise false.
1588
+ * @param path - The path to the file.
1589
+ * @param data - The contents of the file.
1590
+ * @param options - Optional parameters for writing the file.
1591
+ * @returns A promise that resolves when the file is written.
1551
1592
  */
1552
- checkVariants(request, parentPath) {
1553
- const path = parentPath ? joinPaths(parentPath, request) : request;
1554
- let file = this.checkExtensions(path);
1555
- if (file) {
1556
- return file;
1593
+ async writeFile(path, data = "", options = "utf8") {
1594
+ const formattedPath = this.formatPath(path);
1595
+ if (!this.isDirectory(findFilePath(formattedPath))) {
1596
+ await this.mkdir(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
1557
1597
  }
1558
- file = this.checkIndex(path);
1559
- if (file) {
1560
- return file;
1598
+ let code = isPowerLinesWriteFileData(data) ? data.code : data;
1599
+ if ((!isPowerlinesWriteFileOptions(options) || !options.skipFormat) && isSetString(code)) {
1600
+ const resolvedConfig = await resolveConfig(formattedPath);
1601
+ if (resolvedConfig) {
1602
+ code = await format(code, {
1603
+ absolutePath: formattedPath,
1604
+ ...resolvedConfig
1605
+ });
1606
+ }
1561
1607
  }
1562
- return false;
1608
+ const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1609
+ this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1610
+ this.metadata[formattedPath] = {
1611
+ mode: outputMode,
1612
+ variant: "normal",
1613
+ ...isPowerLinesWriteFileData(data) ? data : {}
1614
+ };
1615
+ this.#clearResolverCache(formattedPath);
1616
+ const ifs = this.#unifiedFS.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1617
+ if (isFunction(ifs.promises.writeFile)) {
1618
+ return ifs.promises.writeFile(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1619
+ }
1620
+ return ifs.writeFileSync(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1563
1621
  }
1564
1622
  /**
1565
- * Check if the index file exists in the given request path.
1623
+ * Synchronously writes a file to the virtual file system (VFS).
1566
1624
  *
1567
- * @param request - The request path to check.
1568
- * @returns The index file path if it exists, otherwise false.
1625
+ * @param path - The file to write.
1626
+ * @param data - The contents of the file.
1627
+ * @param options - Optional parameters for writing the file.
1569
1628
  */
1570
- checkIndex(request) {
1571
- let file = joinPaths(request, "index");
1572
- if (this.#existsSync(file)) {
1573
- return file;
1629
+ writeFileSync(path, data = "", options = "utf8") {
1630
+ const formattedPath = this.formatPath(path);
1631
+ if (!this.isDirectory(findFilePath(formattedPath))) {
1632
+ this.mkdirSync(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
1574
1633
  }
1575
- file = this.checkExtensions(file);
1576
- if (file) {
1577
- return file;
1634
+ const code = isPowerLinesWriteFileData(data) ? data.code : data;
1635
+ const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1636
+ this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1637
+ this.metadata[formattedPath] = {
1638
+ mode: outputMode,
1639
+ variant: "normal",
1640
+ ...isPowerLinesWriteFileData(data) ? data : {}
1641
+ };
1642
+ this.#clearResolverCache(formattedPath);
1643
+ const writeStream = this.#unifiedFS.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0).createWriteStream(formattedPath);
1644
+ try {
1645
+ writeStream.write(code);
1646
+ } finally {
1647
+ writeStream.close();
1578
1648
  }
1579
- return false;
1580
1649
  }
1581
1650
  /**
1582
- * Check if the file exists with different extensions.
1651
+ * Synchronously checks if a file exists in the virtual file system (VFS).
1583
1652
  *
1584
- * @param request - The request path to check.
1585
- * @param vfs - The file system module to use for checking file existence.
1586
- * @returns The file path if it exists with any of the checked extensions, otherwise false.
1653
+ * @param pathOrId - The path or ID of the file to check.
1654
+ * @returns `true` if the file exists, otherwise `false`.
1587
1655
  */
1588
- checkExtensions(request) {
1589
- let file = `${request}.ts`;
1590
- if (this.#existsSync(file)) {
1591
- return file;
1656
+ existsSync(pathOrId) {
1657
+ return this.resolve(pathOrId) !== false;
1658
+ }
1659
+ /**
1660
+ * Retrieves the metadata of a file in the virtual file system (VFS).
1661
+ *
1662
+ * @param pathOrId - The path or ID of the file to retrieve metadata for.
1663
+ * @returns The metadata of the file, or undefined if the file does not exist.
1664
+ */
1665
+ getMetadata(pathOrId) {
1666
+ const resolved = this.resolve(pathOrId);
1667
+ if (resolved && this.metadata[resolved]) {
1668
+ return this.metadata[resolved];
1592
1669
  }
1593
- file = `${request}.mts`;
1594
- if (this.#existsSync(file)) {
1595
- return file;
1670
+ return void 0;
1671
+ }
1672
+ /**
1673
+ * Checks if a file exists in the virtual file system (VFS).
1674
+ *
1675
+ * @remarks
1676
+ * This is a base method used by {@link existsSync} - it does not try to resolve the path prior to checking if it exists or not.
1677
+ *
1678
+ * @param pathOrId - The path of the file to check.
1679
+ * @returns `true` if the file exists, otherwise `false`.
1680
+ */
1681
+ isFile(pathOrId) {
1682
+ const resolved = this.resolve(pathOrId);
1683
+ return !!(resolved && (this.#unifiedFS.virtual.existsSync(resolved) && this.#unifiedFS.virtual.lstatSync(resolved).isFile() || this.#unifiedFS.physical.existsSync(resolved) && this.#unifiedFS.physical.lstatSync(resolved).isFile() || this.#unifiedFS.resolveFS(resolved).existsSync(resolved) && this.#unifiedFS.resolveFS(resolved).lstatSync(resolved).isFile()));
1684
+ }
1685
+ /**
1686
+ * Checks if a directory exists in the virtual file system (VFS).
1687
+ *
1688
+ * @param pathOrId - The path of the directory to check.
1689
+ * @returns `true` if the directory exists, otherwise `false`.
1690
+ */
1691
+ isDirectory(pathOrId) {
1692
+ const resolved = this.resolve(pathOrId);
1693
+ return !!(resolved && (this.#unifiedFS.virtual.existsSync(resolved) && this.#unifiedFS.virtual.lstatSync(resolved).isDirectory() || this.#unifiedFS.physical.existsSync(resolved) && this.#unifiedFS.physical.lstatSync(resolved).isDirectory() || this.#unifiedFS.resolveFS(resolved).existsSync(resolved) && this.#unifiedFS.resolveFS(resolved).lstatSync(resolved).isDirectory()));
1694
+ }
1695
+ /**
1696
+ * Retrieves the status of a file in the virtual file system (VFS).
1697
+ *
1698
+ * @param pathOrId - The path or ID of the file to retrieve status for.
1699
+ * @returns A promise that resolves to the file's status information, or false if the file does not exist.
1700
+ */
1701
+ async stat(pathOrId, options) {
1702
+ return this.#unifiedFS.resolveFS(pathOrId).promises.stat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1703
+ }
1704
+ /**
1705
+ * Synchronously retrieves the status of a file in the virtual file system (VFS).
1706
+ *
1707
+ * @param pathOrId - The path or ID of the file to retrieve status for.
1708
+ * @returns The file's status information, or false if the file does not exist.
1709
+ */
1710
+ statSync(pathOrId) {
1711
+ return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId));
1712
+ }
1713
+ /**
1714
+ * Retrieves the status of a symbolic link in the virtual file system (VFS).
1715
+ *
1716
+ * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
1717
+ * @returns A promise that resolves to the symbolic link's status information, or false if the link does not exist.
1718
+ */
1719
+ async lstat(pathOrId, options) {
1720
+ return this.#unifiedFS.resolveFS(pathOrId).promises.lstat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1721
+ }
1722
+ /**
1723
+ * Synchronously retrieves the status of a symbolic link in the virtual file system (VFS).
1724
+ *
1725
+ * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
1726
+ * @returns The symbolic link's status information, or false if the link does not exist.
1727
+ */
1728
+ lstatSync(pathOrId, options) {
1729
+ return this.#unifiedFS.resolveFS(pathOrId).lstatSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
1730
+ }
1731
+ /**
1732
+ * Resolves a path or ID to its real path in the virtual file system (VFS).
1733
+ *
1734
+ * @param pathOrId - The path or ID to resolve.
1735
+ * @returns The resolved real path if it exists, otherwise undefined.
1736
+ */
1737
+ realpathSync(pathOrId) {
1738
+ const filePath = this.resolve(toFilePath(pathOrId));
1739
+ if (!filePath) {
1740
+ throw new Error(`File not found: ${toFilePath(pathOrId)}`);
1596
1741
  }
1597
- file = `${request}.cts`;
1598
- if (this.#existsSync(file)) {
1599
- return file;
1742
+ return filePath;
1743
+ }
1744
+ /**
1745
+ * Resolves a path or ID parameter to a corresponding virtual file path in the virtual file system (VFS).
1746
+ *
1747
+ * @param pathOrId - The path or ID to resolve.
1748
+ * @param options - Optional parameters for resolving the path, such as whether to include the file extension.
1749
+ * @returns The resolved file path if it exists, otherwise undefined.
1750
+ */
1751
+ resolve(pathOrId, options = {}) {
1752
+ const formattedPathOrId = toFilePath(pathOrId);
1753
+ const resolverKey = `${formattedPathOrId}${options.withExtension ? "-ext" : ""}${options.paths ? `-${murmurhash(options.paths)}` : ""}${options.type ? `-${options.type}` : ""}`;
1754
+ if (this.#cachedResolver.has(resolverKey)) {
1755
+ return this.#cachedResolver.get(resolverKey);
1600
1756
  }
1601
- file = `${request}.tsx`;
1602
- if (this.#existsSync(file)) {
1603
- return file;
1757
+ let result = this.#resolveId(formattedPathOrId);
1758
+ if (!result) {
1759
+ result = this.#resolvePath(formattedPathOrId, options);
1604
1760
  }
1605
- file = `${request}.js`;
1606
- if (this.#existsSync(file)) {
1607
- return file;
1761
+ if (!result) {
1762
+ result = false;
1608
1763
  }
1609
- file = `${request}.mjs`;
1610
- if (this.#existsSync(file)) {
1611
- return file;
1764
+ if (result && options.withExtension === false) {
1765
+ return result.replace(/\.[m|c]?[t|j]sx?$/, "");
1612
1766
  }
1613
- file = `${request}.cjs`;
1614
- if (this.#existsSync(file)) {
1615
- return file;
1767
+ this.#cachedResolver.set(resolverKey, result);
1768
+ return result;
1769
+ }
1770
+ /**
1771
+ * Converts a relative path to an absolute path based on the workspace and project root.
1772
+ *
1773
+ * @param path - The relative path to convert.
1774
+ * @returns The absolute path.
1775
+ */
1776
+ formatPath(path) {
1777
+ const formattedPath = toFilePath(path);
1778
+ if (isAbsolutePath(formattedPath) || formattedPath.startsWith(this.#context.workspaceConfig.workspaceRoot)) {
1779
+ return formattedPath;
1780
+ } else if (formattedPath.startsWith(this.#context.config.projectRoot)) {
1781
+ return joinPaths$1(this.#context.workspaceConfig.workspaceRoot, formattedPath);
1616
1782
  }
1617
- file = `${request}.jsx`;
1618
- if (this.#existsSync(file)) {
1619
- return file;
1783
+ return formattedPath;
1784
+ }
1785
+ /**
1786
+ * Disposes of the virtual file system (VFS) by saving its state to disk.
1787
+ */
1788
+ async dispose() {
1789
+ if (!this.#isDisposed) {
1790
+ this.#isDisposed = true;
1791
+ this.#log(LogLevelLabel.DEBUG, "Disposing virtual file system...");
1792
+ await this.unlink(joinPaths$1(this.#context.cachePath, "fs.bin"));
1793
+ const message = new $.Message();
1794
+ const data = message.initRoot(FileSystemData);
1795
+ const virtualFS = this.#unifiedFS.toJSON();
1796
+ const files = data._initFiles(Object.keys(virtualFS).length);
1797
+ Object.entries(virtualFS).filter(([_, content]) => content).forEach(([path, content], index) => {
1798
+ const fileData = files.get(index);
1799
+ fileData.path = path;
1800
+ fileData.content = content;
1801
+ });
1802
+ const ids = data._initIds(Object.keys(this.ids).length);
1803
+ Object.entries(this.ids).forEach(([id, path], index) => {
1804
+ const fileId = ids.get(index);
1805
+ fileId.id = id;
1806
+ fileId.path = path;
1807
+ });
1808
+ const metadata = data._initMetadata(Object.keys(this.metadata).length);
1809
+ Object.entries(this.metadata).forEach(([id, value], index) => {
1810
+ const fileMetadata = metadata.get(index);
1811
+ fileMetadata.id = id;
1812
+ fileMetadata.mode = value.mode;
1813
+ fileMetadata.variant = value.variant;
1814
+ if (value.properties) {
1815
+ const props = fileMetadata._initProperties(Object.keys(value.properties).length);
1816
+ Object.entries(value.properties).forEach(([key, val], propIndex) => {
1817
+ const propData = props.get(propIndex);
1818
+ propData.key = key;
1819
+ propData.value = val;
1820
+ });
1821
+ }
1822
+ });
1823
+ await writeFileBuffer(joinPaths$1(this.#context.cachePath, "fs.bin"), message.toArrayBuffer());
1620
1824
  }
1621
- file = `${request}.json`;
1622
- if (this.#existsSync(file)) {
1623
- return file;
1825
+ }
1826
+ /**
1827
+ * Initializes the virtual file system (VFS) by patching the file system module if necessary.
1828
+ */
1829
+ [__VFS_PATCH__]() {
1830
+ if (!this.#isPatched && this.#context.config.output.mode !== "fs") {
1831
+ this.#revert = patchFS(fs, this);
1832
+ this.#isPatched = true;
1624
1833
  }
1625
- file = `${request}.d.ts`;
1626
- if (this.#existsSync(file)) {
1627
- return file;
1834
+ }
1835
+ /**
1836
+ * Reverts the file system module to its original state if it was previously patched.
1837
+ */
1838
+ [__VFS_REVERT__]() {
1839
+ if (this.#isPatched && this.#context.config.output.mode !== "fs") {
1840
+ if (!this.#revert) {
1841
+ throw new Error("Attempting to revert File System patch prior to calling `__init__` function");
1842
+ }
1843
+ this.#revert?.();
1844
+ this.#isPatched = false;
1628
1845
  }
1629
- return false;
1846
+ }
1847
+ async [Symbol.asyncDispose]() {
1848
+ return this.dispose();
1630
1849
  }
1631
1850
  };
1632
- function createVfs(context) {
1633
- const vfs = new VirtualFileSystem(context);
1634
- return vfs;
1851
+
1852
+ // ../powerlines/src/types/commands.ts
1853
+ var SUPPORTED_COMMANDS = [
1854
+ "new",
1855
+ "clean",
1856
+ "prepare",
1857
+ "lint",
1858
+ "test",
1859
+ "build",
1860
+ "docs",
1861
+ "deploy",
1862
+ "finalize"
1863
+ ];
1864
+
1865
+ // ../powerlines/src/plugin-utils/helpers.ts
1866
+ function isPlugin(value) {
1867
+ return isSetObject(value) && "name" in value && isSetString(value.name) && (isUndefined(value.applyToEnvironment) || "applyToEnvironment" in value && isFunction(value.applyToEnvironment)) && (isUndefined(value.dedupe) || "dedupe" in value && isFunction(value.dedupe)) && (isUndefined(value.dependsOn) || "dependsOn" in value && Array.isArray(value.dependsOn) && value.dependsOn.every(isPluginConfig)) && SUPPORTED_COMMANDS.every((command) => isUndefined(value[command]) || command in value && (isFunction(value[command]) || isSetObject(value[command]) && "handler" in value[command] && isFunction(value[command].handler)));
1868
+ }
1869
+ __name(isPlugin, "isPlugin");
1870
+ function isPluginConfigObject(value) {
1871
+ return isSetObject(value) && "plugin" in value && ((isSetString(value.plugin) || isFunction(value.plugin)) && "options" in value && isSetObject(value.options) || isPlugin(value.plugin));
1872
+ }
1873
+ __name(isPluginConfigObject, "isPluginConfigObject");
1874
+ function isPluginConfigTuple(value) {
1875
+ return Array.isArray(value) && (value.length === 1 || value.length === 2) && ((isSetString(value[0]) || isFunction(value[0])) && value.length > 1 && isSetObject(value[1]) || isPlugin(value[0]));
1876
+ }
1877
+ __name(isPluginConfigTuple, "isPluginConfigTuple");
1878
+ function isPluginConfig(value) {
1879
+ return isSetString(value) || isFunction(value) || isPlugin(value) || isPluginConfigObject(value) || isPluginConfigTuple(value);
1880
+ }
1881
+ __name(isPluginConfig, "isPluginConfig");
1882
+ function isPluginHookFunction(value) {
1883
+ return isFunction(value) || isSetObject(value) && "handler" in value && isFunction(value.handler);
1884
+ }
1885
+ __name(isPluginHookFunction, "isPluginHookFunction");
1886
+ function isPluginHookObject(value) {
1887
+ return isSetObject(value) && "handler" in value && isFunction(value.handler);
1888
+ }
1889
+ __name(isPluginHookObject, "isPluginHookObject");
1890
+ function isPluginHook(value) {
1891
+ return isPluginHookFunction(value) || isPluginHookObject(value);
1892
+ }
1893
+ __name(isPluginHook, "isPluginHook");
1894
+ function getHookHandler(pluginHook) {
1895
+ return isFunction(pluginHook) ? pluginHook : pluginHook.handler;
1896
+ }
1897
+ __name(getHookHandler, "getHookHandler");
1898
+ function isHookExternal(hook) {
1899
+ return hook.startsWith("vite:") || hook.startsWith("esbuild:") || hook.startsWith("rolldown:") || hook.startsWith("rollup:") || hook.startsWith("webpack:") || hook.startsWith("rspack:") || hook.startsWith("farm:");
1900
+ }
1901
+ __name(isHookExternal, "isHookExternal");
1902
+ function checkDedupe(plugin, plugins2) {
1903
+ return plugin.dedupe === false || plugins2.some((p) => p.dedupe !== false && (isFunction(p.dedupe) && p.dedupe(plugin) || p.name === plugin.name));
1904
+ }
1905
+ __name(checkDedupe, "checkDedupe");
1906
+ function addPluginHook(context, plugin, pluginHook, hooksList) {
1907
+ if (!checkDedupe(plugin, hooksList.map((hook) => hook.plugin))) {
1908
+ hooksList.push(isFunction(pluginHook) ? {
1909
+ plugin,
1910
+ handler: getHookHandler(pluginHook).bind(context)
1911
+ } : {
1912
+ plugin,
1913
+ ...pluginHook,
1914
+ handler: getHookHandler(pluginHook).bind(context)
1915
+ });
1916
+ }
1917
+ }
1918
+ __name(addPluginHook, "addPluginHook");
1919
+ function resolveOptions(options) {
1920
+ return defu2(options, {
1921
+ interopDefault: true,
1922
+ fsCache: options.mode !== "development" ? joinPaths$1(options.cacheDir, "jiti") : false,
1923
+ moduleCache: options.mode !== "development"
1924
+ });
1925
+ }
1926
+ __name(resolveOptions, "resolveOptions");
1927
+ function createPluginResolver(options) {
1928
+ return createJiti(joinPaths$1(options.workspaceRoot, options.projectRoot), resolveOptions({
1929
+ ...options
1930
+ }));
1931
+ }
1932
+ __name(createPluginResolver, "createPluginResolver");
1933
+ function createResolver(options) {
1934
+ const baseResolver = createJiti(joinPaths$1(options.workspaceRoot, options.projectRoot), resolveOptions(options));
1935
+ baseResolver.plugin = createPluginResolver(options);
1936
+ return baseResolver;
1635
1937
  }
1636
- __name(createVfs, "createVfs");
1938
+ __name(createResolver, "createResolver");
1637
1939
 
1638
1940
  // ../powerlines/src/internal/contexts/context.ts
1639
1941
  var configCache = /* @__PURE__ */ new WeakMap();
@@ -1673,7 +1975,6 @@ var PowerlinesContext = class _PowerlinesContext {
1673
1975
  lint: config.lint,
1674
1976
  transform: config.transform,
1675
1977
  build: config.build,
1676
- override: config.override,
1677
1978
  framework: config.framework
1678
1979
  };
1679
1980
  }
@@ -1749,7 +2050,7 @@ var PowerlinesContext = class _PowerlinesContext {
1749
2050
  */
1750
2051
  get fs() {
1751
2052
  if (!this.#fs) {
1752
- this.#fs = createVfs(this);
2053
+ this.#fs = VirtualFileSystem.createSync(this);
1753
2054
  }
1754
2055
  return this.#fs;
1755
2056
  }
@@ -1776,9 +2077,7 @@ var PowerlinesContext = class _PowerlinesContext {
1776
2077
  }),
1777
2078
  configHash: murmurhash(this.config, {
1778
2079
  maxLength: CACHE_HASH_LENGTH
1779
- }),
1780
- builtinIdMap: {},
1781
- virtualFiles: {}
2080
+ })
1782
2081
  };
1783
2082
  }
1784
2083
  /**
@@ -1819,31 +2118,31 @@ var PowerlinesContext = class _PowerlinesContext {
1819
2118
  * Get the path to the artifacts directory for the project
1820
2119
  */
1821
2120
  get artifactsPath() {
1822
- return joinPaths$1(this.workspaceConfig.workspaceRoot, this.config.projectRoot, this.config.output.artifactsFolder);
2121
+ return joinPaths(this.workspaceConfig.workspaceRoot, this.config.projectRoot, this.config.output.artifactsFolder);
1823
2122
  }
1824
2123
  /**
1825
2124
  * Get the path to the builtin modules used by the project
1826
2125
  */
1827
2126
  get builtinsPath() {
1828
- return joinPaths$1(this.artifactsPath, "builtins");
2127
+ return joinPaths(this.artifactsPath, "builtins");
1829
2128
  }
1830
2129
  /**
1831
2130
  * Get the path to the entry directory for the project
1832
2131
  */
1833
2132
  get entryPath() {
1834
- return joinPaths$1(this.artifactsPath, "entry");
2133
+ return joinPaths(this.artifactsPath, "entry");
1835
2134
  }
1836
2135
  /**
1837
2136
  * Get the path to the data directory for the project
1838
2137
  */
1839
2138
  get dataPath() {
1840
- return joinPaths$1(this.envPaths.data, "projects", getPrefixedProjectRootHash(this.config.name, this.meta.projectRootHash));
2139
+ return joinPaths(this.envPaths.data, "projects", getPrefixedProjectRootHash(this.config.name, this.meta.projectRootHash));
1841
2140
  }
1842
2141
  /**
1843
2142
  * Get the path to the cache directory for the project
1844
2143
  */
1845
2144
  get cachePath() {
1846
- return joinPaths$1(this.envPaths.cache, "projects", murmurhash({
2145
+ return joinPaths(this.envPaths.cache, "projects", murmurhash({
1847
2146
  checksum: this.#checksum,
1848
2147
  config: this.meta.configHash
1849
2148
  }, {
@@ -1854,7 +2153,7 @@ var PowerlinesContext = class _PowerlinesContext {
1854
2153
  * Get the path to the generated declaration file for the project
1855
2154
  */
1856
2155
  get dtsPath() {
1857
- return this.config.output.dts ? appendPath(this.config.output.dts, this.workspaceConfig.workspaceRoot) : joinPaths$1(this.workspaceConfig.workspaceRoot, this.config.projectRoot, "storm.d.ts");
2156
+ return this.config.output.dts ? appendPath(this.config.output.dts, this.workspaceConfig.workspaceRoot) : joinPaths(this.workspaceConfig.workspaceRoot, this.config.projectRoot, "storm.d.ts");
1858
2157
  }
1859
2158
  /**
1860
2159
  * Get the project root relative to the workspace root
@@ -1866,13 +2165,13 @@ var PowerlinesContext = class _PowerlinesContext {
1866
2165
  * The builtin module id that exist in the Powerlines virtual file system
1867
2166
  */
1868
2167
  get builtins() {
1869
- return Object.values(this.fs.meta).filter((meta) => meta && meta.variant === "builtin").map((meta) => meta?.id).filter(Boolean);
2168
+ return Object.values(this.fs.metadata).filter((meta) => meta && meta.variant === "builtin").map((meta) => meta?.id).filter(Boolean);
1870
2169
  }
1871
2170
  /**
1872
- * Get the project root relative to the workspace root
2171
+ * Get the builtin virtual files that exist in the Powerlines virtual file system
1873
2172
  */
1874
2173
  async getBuiltins() {
1875
- return Promise.all(Object.entries(this.fs.meta).filter(([, meta]) => meta && meta.variant === "builtin").map(async ([path, meta]) => {
2174
+ return Promise.all(Object.entries(this.fs.metadata).filter(([, meta]) => meta && meta.variant === "builtin").map(async ([path, meta]) => {
1876
2175
  const code = await this.fs.readFile(path);
1877
2176
  return {
1878
2177
  ...meta,
@@ -1892,7 +2191,7 @@ var PowerlinesContext = class _PowerlinesContext {
1892
2191
  return this.fs.writeFile(isAbsolute(path) ? path : appendPath(path, this.entryPath), {
1893
2192
  code,
1894
2193
  variant: "entry"
1895
- }, defu3(options, {
2194
+ }, defu2(options, {
1896
2195
  mode: this.config.output.mode
1897
2196
  }));
1898
2197
  }
@@ -1905,11 +2204,11 @@ var PowerlinesContext = class _PowerlinesContext {
1905
2204
  * @param options - Optional write file options
1906
2205
  */
1907
2206
  async writeBuiltin(code, id, path, options = {}) {
1908
- return this.fs.writeFile(path ? isAbsolute(path) ? path : joinPaths$1(this.builtinsPath, path) : appendPath(id, this.builtinsPath), {
2207
+ return this.fs.writeFile(path ? isAbsolute(path) ? path : joinPaths(this.builtinsPath, path) : appendPath(id, this.builtinsPath), {
1909
2208
  id,
1910
2209
  code,
1911
2210
  variant: "builtin"
1912
- }, defu3(options, {
2211
+ }, defu2(options, {
1913
2212
  mode: this.config.output.mode
1914
2213
  }));
1915
2214
  }
@@ -1931,7 +2230,7 @@ var PowerlinesContext = class _PowerlinesContext {
1931
2230
  options
1932
2231
  });
1933
2232
  }
1934
- const result = await parseAsync(id, code, defu3(options ?? {}, {
2233
+ const result = await parseAsync(id, code, defu2(options ?? {}, {
1935
2234
  lang: hasFileExtension(id) ? void 0 : "ts",
1936
2235
  astType: hasFileExtension(id) ? void 0 : "ts",
1937
2236
  sourceType: "module",
@@ -1969,7 +2268,7 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
1969
2268
  }) {
1970
2269
  this.config.inlineConfig = inlineConfig;
1971
2270
  if (inlineConfig.command === "new") {
1972
- const workspacePackageJsonPath = joinPaths$1(this.workspaceConfig.workspaceRoot, "package.json");
2271
+ const workspacePackageJsonPath = joinPaths(this.workspaceConfig.workspaceRoot, "package.json");
1973
2272
  if (!existsSync(workspacePackageJsonPath)) {
1974
2273
  throw new Error(`The workspace package.json file could not be found at ${workspacePackageJsonPath}`);
1975
2274
  }
@@ -2092,11 +2391,11 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2092
2391
  this.resolver = result.resolver;
2093
2392
  this.mergeUserConfig(result.userConfig.config, this.config.userConfig);
2094
2393
  } else {
2095
- const projectJsonPath = joinPaths$1(cacheKey.projectRoot, "project.json");
2394
+ const projectJsonPath = joinPaths(cacheKey.projectRoot, "project.json");
2096
2395
  if (existsSync(projectJsonPath)) {
2097
2396
  this.projectJson = await readJsonFile(projectJsonPath);
2098
2397
  }
2099
- const packageJsonPath = joinPaths$1(cacheKey.projectRoot, "package.json");
2398
+ const packageJsonPath = joinPaths(cacheKey.projectRoot, "package.json");
2100
2399
  if (existsSync(packageJsonPath)) {
2101
2400
  this.packageJson = await readJsonFile(packageJsonPath);
2102
2401
  }
@@ -2119,7 +2418,7 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2119
2418
  });
2120
2419
  }
2121
2420
  if (isSetObject(config)) {
2122
- this.resolvedConfig = defu3({
2421
+ this.resolvedConfig = defu2({
2123
2422
  inlineConfig: this.config.inlineConfig,
2124
2423
  userConfig: this.config.userConfig
2125
2424
  }, options.isHighPriority ? this.#getConfigProps(config) : {}, {
@@ -2136,11 +2435,11 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2136
2435
  tsconfig: appendPath("tsconfig.json", cacheKey.projectRoot),
2137
2436
  sourceRoot: this.projectJson?.sourceRoot || appendPath("src", cacheKey.projectRoot),
2138
2437
  output: {
2139
- outputPath: joinPaths$1("dist", cacheKey.projectRoot),
2438
+ outputPath: joinPaths("dist", cacheKey.projectRoot),
2140
2439
  mode: "virtual",
2141
- dts: joinPaths$1(cacheKey.projectRoot, `${config.framework ?? "powerlines"}.d.ts`),
2440
+ dts: joinPaths(cacheKey.projectRoot, `${config.framework ?? "powerlines"}.d.ts`),
2142
2441
  builtinPrefix: config.framework ?? "powerlines",
2143
- artifactsFolder: joinPaths$1(cacheKey.projectRoot, `.${config.framework ?? "powerlines"}`),
2442
+ artifactsFolder: joinPaths(cacheKey.projectRoot, `.${config.framework ?? "powerlines"}`),
2144
2443
  assets: [
2145
2444
  {
2146
2445
  glob: "LICENSE"
@@ -2175,9 +2474,9 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2175
2474
  eslint: {}
2176
2475
  },
2177
2476
  build: {
2178
- target: "esnext"
2179
- },
2180
- override: {}
2477
+ target: "esnext",
2478
+ override: {}
2479
+ }
2181
2480
  });
2182
2481
  }
2183
2482
  this.config.entry = getUniqueEntries(this.config.entry);
@@ -2197,12 +2496,12 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2197
2496
  ] : [
2198
2497
  "esm"
2199
2498
  ])));
2200
- this.config.output.outputPath ??= joinPaths$1("dist", this.config.projectRoot || ".");
2499
+ this.config.output.outputPath ??= joinPaths("dist", this.config.projectRoot || ".");
2201
2500
  this.config.output.assets = getUnique(this.config.output.assets.map((asset) => {
2202
2501
  return {
2203
2502
  glob: isSetObject(asset) ? asset.glob : asset,
2204
2503
  input: isString(asset) || !asset.input || asset.input === "." || asset.input === "/" || asset.input === "./" ? this.workspaceConfig.workspaceRoot : appendPath(asset.input, this.workspaceConfig.workspaceRoot),
2205
- output: appendPath(isSetObject(asset) && asset.output ? joinPaths$1(this.config.output.outputPath, replacePath(asset.output, this.config.output.outputPath)) : this.config.output.outputPath, this.workspaceConfig.workspaceRoot),
2504
+ output: appendPath(isSetObject(asset) && asset.output ? joinPaths(this.config.output.outputPath, replacePath(asset.output, this.config.output.outputPath)) : this.config.output.outputPath, this.workspaceConfig.workspaceRoot),
2206
2505
  ignore: isSetObject(asset) && asset.ignore ? toArray(asset.ignore) : void 0
2207
2506
  };
2208
2507
  }));
@@ -2213,9 +2512,10 @@ ${result.errors.map((error) => ` [${error.severity}] ${error.message}${error.co
2213
2512
  ret.push(plugin);
2214
2513
  return ret;
2215
2514
  }, []);
2515
+ this.#fs ??= await VirtualFileSystem.create(this);
2216
2516
  }
2217
2517
  mergeUserConfig(from = {}, into = this.config.userConfig ?? {}) {
2218
- this.config.userConfig = defu3({
2518
+ this.config.userConfig = defu2({
2219
2519
  entry: Array.isArray(from.entry) && from.entry.length > 0 ? from.entry : Array.isArray(into?.entry) && into.entry.length > 0 ? into.entry : []
2220
2520
  }, omit(from ?? {}, [
2221
2521
  "entry"
@@ -2580,7 +2880,7 @@ async function emitTypes(context, tsconfig, files) {
2580
2880
  const emitResult = program.emit(void 0, (fileName, text, _, __, sourceFiles, _data) => {
2581
2881
  const sourceFile = sourceFiles?.[0];
2582
2882
  if (sourceFile?.fileName && !fileName.endsWith(".map")) {
2583
- if (context.builtins.some((file) => file === sourceFile.fileName || context.fs.meta[file]?.id && context.fs.meta[file]?.id === sourceFile.fileName)) {
2883
+ if (context.builtins.some((file) => file === sourceFile.fileName || context.fs.metadata[file]?.id && context.fs.metadata[file]?.id === sourceFile.fileName)) {
2584
2884
  builtinModules += `
2585
2885
  declare module "${context.fs.resolve(sourceFile.fileName)}" {
2586
2886
  ${text.trim().replace(/^\s*export\s*declare\s*/gm, "export ").replace(/^\s*declare\s*/gm, "")}
@@ -2669,7 +2969,7 @@ function getTsconfigFilePath(workspaceRoot, projectRoot, tsconfig = "tsconfig.js
2669
2969
  if (!existsSync(tsconfigFilePath)) {
2670
2970
  tsconfigFilePath = appendPath(tsconfig, workspaceRoot);
2671
2971
  if (!existsSync(tsconfigFilePath)) {
2672
- tsconfigFilePath = appendPath(tsconfig, joinPaths(workspaceRoot, projectRoot));
2972
+ tsconfigFilePath = appendPath(tsconfig, joinPaths$1(workspaceRoot, projectRoot));
2673
2973
  if (!existsSync(tsconfigFilePath)) {
2674
2974
  throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${tsconfig}, ${appendPath(tsconfig, projectRoot)}, ${appendPath(tsconfig, workspaceRoot)}, or ${tsconfigFilePath}`);
2675
2975
  }
@@ -2727,9 +3027,9 @@ function getParsedTypeScriptConfig(workspaceRoot, projectRoot, tsconfig, tsconfi
2727
3027
  const tsconfigFilePath = getTsconfigFilePath(workspaceRoot, projectRoot, tsconfig);
2728
3028
  const tsconfigJson = readJsonFileSync(tsconfigFilePath);
2729
3029
  if (!tsconfigJson) {
2730
- throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${joinPaths(projectRoot, tsconfig ?? "tsconfig.json")}`);
3030
+ throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${joinPaths$1(projectRoot, tsconfig ?? "tsconfig.json")}`);
2731
3031
  }
2732
- const parsedCommandLine = ts2.parseJsonConfigFileContent(defu3(tsconfigRaw ?? {}, tsconfigJson), host, appendPath(projectRoot, workspaceRoot));
3032
+ const parsedCommandLine = ts2.parseJsonConfigFileContent(defu2(tsconfigRaw ?? {}, tsconfigJson), host, appendPath(projectRoot, workspaceRoot));
2733
3033
  if (parsedCommandLine.errors.length > 0) {
2734
3034
  const errorMessage = `Cannot parse the TypeScript compiler options. Please investigate the following issues:
2735
3035
  ${parsedCommandLine.errors.map((error) => `- ${(error.category !== void 0 && error.code ? `[${error.category}-${error.code}]: ` : "") + error.messageText.toString()}`).join("\n")}
@@ -2781,8 +3081,8 @@ async function resolveTsconfigChanges(context) {
2781
3081
  tsconfigJson.compilerOptions.emitDecoratorMetadata = true;
2782
3082
  }
2783
3083
  if (context.config.output.dts) {
2784
- const dtsFilePath = context.config.output.dts ? context.config.output.dts.startsWith(context.workspaceConfig.workspaceRoot) ? context.config.output.dts : joinPaths(context.workspaceConfig.workspaceRoot, context.config.output.dts) : joinPaths(context.workspaceConfig.workspaceRoot, context.config.projectRoot, "storm.d.ts");
2785
- const dtsRelativePath = joinPaths(relativePath(joinPaths(context.workspaceConfig.workspaceRoot, context.config.projectRoot), findFilePath(dtsFilePath)), findFileName(dtsFilePath));
3084
+ const dtsFilePath = context.config.output.dts ? context.config.output.dts.startsWith(context.workspaceConfig.workspaceRoot) ? context.config.output.dts : joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.output.dts) : joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot, "storm.d.ts");
3085
+ const dtsRelativePath = joinPaths$1(relativePath(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot), findFilePath(dtsFilePath)), findFileName(dtsFilePath));
2786
3086
  if (!tsconfigJson.include?.some((filePattern) => isIncludeMatchFound(filePattern, [
2787
3087
  dtsFilePath,
2788
3088
  dtsRelativePath,
@@ -3021,10 +3321,13 @@ ${context.entry.map((entry) => `- ${entry.input.file || entry.file}${entry.outpu
3021
3321
  await resolveTsconfig(context);
3022
3322
  await installDependencies(context);
3023
3323
  await this.callPostHook(context, "configResolved");
3324
+ if (context.config.build.polyfill) {
3325
+ context.config.build.polyfill = context.config.build.polyfill.map((polyfill) => replacePathTokens(context, polyfill));
3326
+ }
3024
3327
  context.log(LogLevelLabel.TRACE, `Powerlines configuration has been resolved:
3025
3328
 
3026
3329
  ${formatLogMessage(context.config)}`);
3027
- context.fs[__VFS_INIT__]();
3330
+ context.fs[__VFS_PATCH__]();
3028
3331
  await writeMetaFile(context);
3029
3332
  context.persistedMeta = context.meta;
3030
3333
  if (!existsSync(context.cachePath)) {
@@ -3081,10 +3384,10 @@ ${formatLogMessage(context.config)}`);
3081
3384
  }
3082
3385
  return ret;
3083
3386
  }, [
3084
- joinPaths(typescriptPath, "lib", "lib.esnext.full.d.ts")
3387
+ joinPaths$1(typescriptPath, "lib", "lib.esnext.full.d.ts")
3085
3388
  ]);
3086
3389
  context.log(LogLevelLabel.TRACE, "Parsing TypeScript configuration for the Powerlines project.");
3087
- const resolvedTsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.tsconfig.tsconfigFilePath, defu3({
3390
+ const resolvedTsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.tsconfig.tsconfigFilePath, defu2({
3088
3391
  compilerOptions: {
3089
3392
  strict: false,
3090
3393
  noEmit: false,
@@ -3099,7 +3402,7 @@ ${formatLogMessage(context.config)}`);
3099
3402
  ],
3100
3403
  include: files
3101
3404
  }, context.config.tsconfigRaw ?? {}));
3102
- resolvedTsconfig.options.configFilePath = joinPaths(context.workspaceConfig.workspaceRoot, context.tsconfig.tsconfigFilePath);
3405
+ resolvedTsconfig.options.configFilePath = joinPaths$1(context.workspaceConfig.workspaceRoot, context.tsconfig.tsconfigFilePath);
3103
3406
  resolvedTsconfig.options.pathsBasePath = context.workspaceConfig.workspaceRoot;
3104
3407
  resolvedTsconfig.options.suppressOutputPathCheck = true;
3105
3408
  let generatedTypes = await emitTypes(context, resolvedTsconfig, files);
@@ -3175,26 +3478,26 @@ ${formatTypes(generatedTypes)}
3175
3478
  await this.#executeEnvironments(async (context) => {
3176
3479
  context.log(LogLevelLabel.TRACE, `Initializing the processing options for the Powerlines project.`);
3177
3480
  await this.callPreHook(context, "new");
3178
- const files = await listFiles(joinPaths(context.powerlinesPath, "files/common/**/*.hbs"));
3481
+ const files = await listFiles(joinPaths$1(context.powerlinesPath, "files/common/**/*.hbs"));
3179
3482
  for (const file of files) {
3180
3483
  context.log(LogLevelLabel.TRACE, `Adding template file: ${file}`);
3181
3484
  const template = Handlebars.compile(file);
3182
- await writeFile(context.log, joinPaths(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3485
+ await writeFile(context.log, joinPaths$1(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3183
3486
  }
3184
3487
  await this.callNormalHook(context, "new");
3185
3488
  if (context.config.projectType === "application") {
3186
- const files2 = await listFiles(joinPaths(context.powerlinesPath, "files/application/**/*.hbs"));
3489
+ const files2 = await listFiles(joinPaths$1(context.powerlinesPath, "files/application/**/*.hbs"));
3187
3490
  for (const file of files2) {
3188
3491
  context.log(LogLevelLabel.TRACE, `Adding application template file: ${file}`);
3189
3492
  const template = Handlebars.compile(file);
3190
- await writeFile(context.log, joinPaths(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3493
+ await writeFile(context.log, joinPaths$1(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3191
3494
  }
3192
3495
  } else {
3193
- const files2 = await listFiles(joinPaths(context.powerlinesPath, "files/library/**/*.hbs"));
3496
+ const files2 = await listFiles(joinPaths$1(context.powerlinesPath, "files/library/**/*.hbs"));
3194
3497
  for (const file of files2) {
3195
3498
  context.log(LogLevelLabel.TRACE, `Adding library template file: ${file}`);
3196
3499
  const template = Handlebars.compile(file);
3197
- await writeFile(context.log, joinPaths(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3500
+ await writeFile(context.log, joinPaths$1(context.config.projectRoot, file.replace(".hbs", "")), template(context));
3198
3501
  }
3199
3502
  }
3200
3503
  await this.callPostHook(context, "new");
@@ -3258,7 +3561,7 @@ ${formatTypes(generatedTypes)}
3258
3561
  await this.callPreHook(context, "build");
3259
3562
  await this.callNormalHook(context, "build");
3260
3563
  await Promise.all(context.config.output.assets.map(async (asset) => {
3261
- context.log(LogLevelLabel.DEBUG, `Copying asset(s): ${chalk5.redBright(context.workspaceConfig.workspaceRoot === asset.input ? asset.glob : joinPaths(replacePath(asset.input, context.workspaceConfig.workspaceRoot), asset.glob))} -> ${chalk5.greenBright(joinPaths(replacePath(asset.output, context.workspaceConfig.workspaceRoot), asset.glob))} ${Array.isArray(asset.ignore) && asset.ignore.length > 0 ? ` (ignoring: ${asset.ignore.map((i) => chalk5.yellowBright(i)).join(", ")})` : ""}`);
3564
+ context.log(LogLevelLabel.DEBUG, `Copying asset(s): ${chalk5.redBright(context.workspaceConfig.workspaceRoot === asset.input ? asset.glob : joinPaths$1(replacePath(asset.input, context.workspaceConfig.workspaceRoot), asset.glob))} -> ${chalk5.greenBright(joinPaths$1(replacePath(asset.output, context.workspaceConfig.workspaceRoot), asset.glob))} ${Array.isArray(asset.ignore) && asset.ignore.length > 0 ? ` (ignoring: ${asset.ignore.map((i) => chalk5.yellowBright(i)).join(", ")})` : ""}`);
3262
3565
  await copyFiles(asset, asset.output);
3263
3566
  }));
3264
3567
  await this.callPostHook(context, "build");
@@ -3286,22 +3589,22 @@ ${formatTypes(generatedTypes)}
3286
3589
  this.#context.log(LogLevelLabel.TRACE, "Powerlines documentation generation completed");
3287
3590
  }
3288
3591
  /**
3289
- * Release the project
3592
+ * Deploy the project source code
3290
3593
  *
3291
3594
  * @remarks
3292
- * This method will prepare and build the Powerlines project, generating the necessary artifacts for release.
3595
+ * This method will prepare and build the Powerlines project, generating the necessary artifacts for the deployment.
3293
3596
  *
3294
- * @param inlineConfig - The inline configuration for the release command
3597
+ * @param inlineConfig - The inline configuration for the deploy command
3295
3598
  */
3296
- async release(inlineConfig = {
3297
- command: "release"
3599
+ async deploy(inlineConfig = {
3600
+ command: "deploy"
3298
3601
  }) {
3299
- this.context.log(LogLevelLabel.INFO, "\u{1F4E6} Releasing the Powerlines project");
3602
+ this.context.log(LogLevelLabel.INFO, "\u{1F4E6} Deploying the Powerlines project");
3300
3603
  await this.prepare(inlineConfig);
3301
3604
  await this.#executeEnvironments(async (context) => {
3302
- await this.callHook(context, "release");
3605
+ await this.callHook(context, "deploy");
3303
3606
  });
3304
- this.context.log(LogLevelLabel.TRACE, "Powerlines release completed");
3607
+ this.context.log(LogLevelLabel.TRACE, "Powerlines deploy completed");
3305
3608
  }
3306
3609
  /**
3307
3610
  * Finalization process
@@ -3316,6 +3619,7 @@ ${formatTypes(generatedTypes)}
3316
3619
  await this.#executeEnvironments(async (context) => {
3317
3620
  await this.callHook(context, "finalize");
3318
3621
  context.fs[__VFS_REVERT__]();
3622
+ await context.fs.dispose();
3319
3623
  });
3320
3624
  this.context.log(LogLevelLabel.TRACE, "Powerlines finalize execution completed");
3321
3625
  }
@@ -3546,7 +3850,7 @@ ${formatTypes(generatedTypes)}
3546
3850
  }
3547
3851
  }
3548
3852
  try {
3549
- const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(joinPaths(pluginPath, "plugin")));
3853
+ const module = await this.context.resolver.plugin.import(this.context.resolver.plugin.esmResolve(joinPaths$1(pluginPath, "plugin")));
3550
3854
  const result = module.plugin ?? module.default;
3551
3855
  if (!result) {
3552
3856
  throw new Error(`The plugin package "${pluginPath}" does not export a valid module.`);
@@ -3587,22 +3891,88 @@ var DEFAULT_ESBUILD_CONFIG = {
3587
3891
  logLevel: "silent"
3588
3892
  };
3589
3893
  function extractESBuildConfig(context) {
3590
- return defu3({
3894
+ const inject = context.config.build.override.inject ?? context.config.build.inject;
3895
+ if (inject && Object.keys(inject).length > 0) {
3896
+ context.fs.writeFileSync(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.artifactsPath, "inject-shim.js"), Object.entries(inject).map(([key, value]) => {
3897
+ if (value) {
3898
+ if (Array.isArray(value)) {
3899
+ if (camelCase(key) !== key) {
3900
+ if (value.length === 1) {
3901
+ return `
3902
+ import ${camelCase(key)} from "${value[0]}";
3903
+ export { ${camelCase(key)} as "${key}" }`;
3904
+ } else if (value.length > 1) {
3905
+ return `
3906
+ import ${value[1] === "*" ? `* as ${camelCase(key)}` : `{ ${value[1]} as ${camelCase(key)} }`} from "${value[0]}";
3907
+ export { ${camelCase(key)} as "${key}" }`;
3908
+ }
3909
+ } else if (value.length === 1) {
3910
+ return `
3911
+ import ${key} from "${value[0]}";
3912
+ export { ${key} };`;
3913
+ } else if (value.length > 1) {
3914
+ return `
3915
+ import ${value[1] === "*" ? `* as ${key}` : `{ ${value[1]} as ${key} }`} from "${value[0]}";
3916
+ export { ${key} };`;
3917
+ }
3918
+ } else if (camelCase(key) !== key) {
3919
+ return `
3920
+ import ${camelCase(key)} from "${value[0]}";
3921
+ export { ${camelCase(key)} as "${key}" }`;
3922
+ } else {
3923
+ return `
3924
+ import ${key} from "${value}";
3925
+ export { ${key} };`;
3926
+ }
3927
+ }
3928
+ return "";
3929
+ }).join("\n"));
3930
+ }
3931
+ return defu2({
3591
3932
  alias: context.builtins.reduce((ret, id) => {
3592
- const path = context.fs.ids[id];
3593
- if (path) {
3594
- ret[id] = path;
3933
+ if (!ret[id]) {
3934
+ const path = context.fs.ids[id];
3935
+ if (path) {
3936
+ ret[id] = path;
3937
+ }
3595
3938
  }
3596
3939
  return ret;
3597
- }, {})
3598
- }, context.config.build.variant === "esbuild" ? context.config.override : {}, {
3940
+ }, context.config.build.alias ? Array.isArray(context.config.build.alias) ? context.config.build.alias.reduce((ret, alias) => {
3941
+ if (!ret[alias.find.toString()]) {
3942
+ ret[alias.find.toString()] = alias.replacement;
3943
+ }
3944
+ return ret;
3945
+ }, {}) : context.config.build.alias : {}),
3946
+ inject: inject && Object.keys(inject).length > 0 ? [
3947
+ joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.artifactsPath, "inject-shim.js")
3948
+ ] : void 0
3949
+ }, context.config.build.variant === "esbuild" ? omit(context.config.build.override, [
3950
+ "alias",
3951
+ "inject",
3952
+ "external",
3953
+ "noExternal",
3954
+ "skipNodeModulesBundle",
3955
+ "extensions"
3956
+ ]) : {}, {
3957
+ mainFields: context.config.build.mainFields,
3958
+ conditions: context.config.build.conditions,
3959
+ define: context.config.build.define,
3960
+ resolveExtensions: context.config.build.extensions,
3961
+ packages: context.config.build.skipNodeModulesBundle ? "external" : context.config.build.variant === "esbuild" ? context.config.build.packages : void 0,
3599
3962
  format: Array.isArray(context.config.output.format) ? context.config.output.format[0] : context.config.output.format,
3600
3963
  platform: context.config.build.platform,
3601
3964
  treeShaking: Boolean(context.config.build?.treeshake) || context.config.build?.treeShaking,
3602
3965
  outdir: context.config.output.outputPath,
3603
3966
  tsconfig: context.tsconfig.tsconfigFilePath,
3604
3967
  tsconfigRaw: context.tsconfig.tsconfigJson
3605
- }, context.config.build.variant === "esbuild" ? context.config.build : {}, {
3968
+ }, context.config.build.variant === "esbuild" ? omit(context.config.build, [
3969
+ "alias",
3970
+ "inject",
3971
+ "external",
3972
+ "noExternal",
3973
+ "skipNodeModulesBundle",
3974
+ "extensions"
3975
+ ]) : {}, {
3606
3976
  minify: context.config.mode !== "development",
3607
3977
  metafile: context.config.mode === "development",
3608
3978
  sourcemap: context.config.mode === "development"
@@ -3630,25 +4000,39 @@ var DEFAULT_VITE_CONFIG = {
3630
4000
  clearScreen: true
3631
4001
  };
3632
4002
  function extractViteConfig(context) {
3633
- return defu3({
4003
+ return defu2({
3634
4004
  resolve: {
3635
4005
  alias: context.builtins.reduce((ret, id) => {
3636
- const path = context.fs.ids[id];
3637
- if (path) {
3638
- ret[id] = path;
4006
+ if (!ret.find((e) => e.find === id)) {
4007
+ const path = context.fs.ids[id];
4008
+ if (path) {
4009
+ ret.push({
4010
+ find: id,
4011
+ replacement: path
4012
+ });
4013
+ }
3639
4014
  }
3640
4015
  return ret;
3641
- }, {})
3642
- }
3643
- }, context.config.build.variant === "vite" ? context.config.override : {}, {
3644
- external: context.config.build.external,
3645
- noExternal: context.config.build.noExternal,
3646
- skipNodeModulesBundle: context.config.build.skipNodeModulesBundle
3647
- }, {
4016
+ }, context.config.build.alias ? Array.isArray(context.config.build.alias) ? context.config.build.alias : Object.entries(context.config.build.alias).reduce((ret, [id, path]) => {
4017
+ if (!ret.find((e) => e.find === id)) {
4018
+ ret.push({
4019
+ find: id,
4020
+ replacement: path
4021
+ });
4022
+ }
4023
+ return ret;
4024
+ }, []) : []),
4025
+ dedupe: context.config.build.dedupe,
4026
+ mainFields: context.config.build.mainFields,
4027
+ conditions: context.config.build.conditions,
4028
+ extensions: context.config.build.extensions
4029
+ }
4030
+ }, context.config.build.variant === "vite" ? context.config.build.override : {}, {
4031
+ define: context.config.build.define,
3648
4032
  rootDir: context.config.sourceRoot,
3649
4033
  platform: context.config.build.platform,
3650
4034
  mode: context.config.mode === "development" ? "development" : "production",
3651
- cacheDir: joinPaths(context.cachePath, "vite"),
4035
+ cacheDir: joinPaths$1(context.cachePath, "vite"),
3652
4036
  build: {
3653
4037
  outDir: context.config.output.outputPath,
3654
4038
  tsconfig: context.tsconfig.tsconfigFilePath,
@@ -3656,8 +4040,7 @@ function extractViteConfig(context) {
3656
4040
  },
3657
4041
  esbuild: extractESBuildConfig(context),
3658
4042
  logLevel: context.config.logLevel ?? void 0,
3659
- envDir: context.config.projectRoot,
3660
- noExternal: context.builtins
4043
+ envDir: context.config.projectRoot
3661
4044
  }, context.config.build.variant === "vite" ? context.config.build : {}, {
3662
4045
  build: {
3663
4046
  minify: context.config.mode !== "development",
@@ -3700,9 +4083,23 @@ async function handleResolveId(context, args, options = {}) {
3700
4083
  };
3701
4084
  }
3702
4085
  }
3703
- if (context.fs.isTsconfigPath(args.id)) {
3704
- const tsconfigPath = context.fs.resolveTsconfigPath(args.id);
3705
- const tsconfigPathPackage = context.fs.resolveTsconfigPathPackage(args.id);
4086
+ if (!!context.tsconfig.options.paths && Object.keys(context.tsconfig.options.paths).some((path) => args.id.startsWith(path.replaceAll("*", "")))) {
4087
+ let tsconfigPath = false;
4088
+ if (context.tsconfig.options.paths) {
4089
+ for (const tsconfigPathKey of Object.keys(context.tsconfig.options.paths).filter((tsconfigPath2) => args.id.startsWith(tsconfigPath2.replaceAll("*", "")))) {
4090
+ const resolvedPath = context.tsconfig.options.paths[tsconfigPathKey]?.find((tsconfigPath2) => context.fs.resolve(joinPaths(context.workspaceConfig.workspaceRoot, tsconfigPath2.replaceAll("*", ""), args.id.replace(tsconfigPathKey.replaceAll("*", ""), ""))) || context.fs.formatPath(tsconfigPath2) === context.fs.formatPath(args.id));
4091
+ if (resolvedPath) {
4092
+ tsconfigPath = context.fs.formatPath(resolvedPath) === context.fs.formatPath(args.id) ? context.fs.formatPath(resolvedPath) : context.fs.resolve(joinPaths(context.workspaceConfig.workspaceRoot, resolvedPath.replaceAll("*", ""), args.id.replace(tsconfigPathKey.replaceAll("*", ""), "")));
4093
+ }
4094
+ }
4095
+ }
4096
+ let tsconfigPathPackage = false;
4097
+ if (context.tsconfig.options.paths) {
4098
+ const tsconfigPathKeys = Object.keys(context.tsconfig.options.paths).filter((tsconfigPath2) => args.id.startsWith(tsconfigPath2.replaceAll("*", "")));
4099
+ if (tsconfigPathKeys.length > 0 && tsconfigPathKeys[0]) {
4100
+ tsconfigPathPackage = tsconfigPathKeys[0].replace(/\/\*$/, "");
4101
+ }
4102
+ }
3706
4103
  if (tsconfigPath && tsconfigPathPackage) {
3707
4104
  return {
3708
4105
  id: tsconfigPath,
@@ -3735,7 +4132,7 @@ async function handleResolveId(context, args, options = {}) {
3735
4132
  args.importer
3736
4133
  ] : []
3737
4134
  });
3738
- if (match(args.id, options.noExternal) || resolvedPath && context.fs.meta[resolvedPath]?.variant === "builtin") {
4135
+ if (match(args.id, options.noExternal) || resolvedPath && context.fs.metadata[resolvedPath]?.variant === "builtin") {
3739
4136
  return void 0;
3740
4137
  }
3741
4138
  if (match(args.id, options.external) || args.id.startsWith("node:")) {
@@ -3884,7 +4281,12 @@ var vite = createVitePlugin(createUnpluginFactory("vite", (api, plugin) => {
3884
4281
  api.context.config.mode = isDevelopmentMode(env.mode) ? "development" : isTestMode(env.mode) ? "test" : "production";
3885
4282
  const environment = await api.context.getEnvironment();
3886
4283
  const result = await api.callHook(environment, "config");
3887
- return defu3(extractViteConfig(api.context), result?.build ?? {}, config);
4284
+ return defu2(
4285
+ extractViteConfig(api.context),
4286
+ // Need to use `any` here to avoid excessive type complexity
4287
+ result?.build ?? {},
4288
+ config
4289
+ );
3888
4290
  },
3889
4291
  async configResolved(_config) {
3890
4292
  const environment = await api.context.getEnvironment();
@@ -3947,228 +4349,6 @@ createRolldownPlugin(createUnpluginFactory("rolldown"));
3947
4349
  createRollupPlugin(createUnpluginFactory("rollup"));
3948
4350
  createRspackPlugin(createUnpluginFactory("rspack"));
3949
4351
  createUnloaderPlugin(createUnpluginFactory("unloader"));
3950
- BigInt("0xa56c61324b9d6e49");
3951
- var FileMetadata_KeyValuePair = class extends $.Struct {
3952
- static {
3953
- __name(this, "FileMetadata_KeyValuePair");
3954
- }
3955
- static _capnp = {
3956
- displayName: "KeyValuePair",
3957
- id: "eabb26cf58b2a14c",
3958
- size: new $.ObjectSize(0, 2)
3959
- };
3960
- get key() {
3961
- return $.utils.getText(0, this);
3962
- }
3963
- set key(value) {
3964
- $.utils.setText(0, value, this);
3965
- }
3966
- get value() {
3967
- return $.utils.getText(1, this);
3968
- }
3969
- set value(value) {
3970
- $.utils.setText(1, value, this);
3971
- }
3972
- toString() {
3973
- return "FileMetadata_KeyValuePair_" + super.toString();
3974
- }
3975
- };
3976
- var FileMetadata = class _FileMetadata extends $.Struct {
3977
- static {
3978
- __name(this, "FileMetadata");
3979
- }
3980
- static KeyValuePair = FileMetadata_KeyValuePair;
3981
- static _capnp = {
3982
- displayName: "FileMetadata",
3983
- id: "8e2cab5d7e28c7b3",
3984
- size: new $.ObjectSize(0, 4),
3985
- defaultVariant: "normal"
3986
- };
3987
- static _Properties;
3988
- /**
3989
- * The variant of the file.
3990
- *
3991
- */
3992
- get id() {
3993
- return $.utils.getText(0, this);
3994
- }
3995
- set id(value) {
3996
- $.utils.setText(0, value, this);
3997
- }
3998
- /**
3999
- * The output mode of the file.
4000
- *
4001
- */
4002
- get variant() {
4003
- return $.utils.getText(1, this, _FileMetadata._capnp.defaultVariant);
4004
- }
4005
- set variant(value) {
4006
- $.utils.setText(1, value, this);
4007
- }
4008
- /**
4009
- * Additional metadata associated with the file.
4010
- *
4011
- */
4012
- get mode() {
4013
- return $.utils.getText(2, this);
4014
- }
4015
- set mode(value) {
4016
- $.utils.setText(2, value, this);
4017
- }
4018
- _adoptProperties(value) {
4019
- $.utils.adopt(value, $.utils.getPointer(3, this));
4020
- }
4021
- _disownProperties() {
4022
- return $.utils.disown(this.properties);
4023
- }
4024
- get properties() {
4025
- return $.utils.getList(3, _FileMetadata._Properties, this);
4026
- }
4027
- _hasProperties() {
4028
- return !$.utils.isNull($.utils.getPointer(3, this));
4029
- }
4030
- _initProperties(length) {
4031
- return $.utils.initList(3, _FileMetadata._Properties, length, this);
4032
- }
4033
- set properties(value) {
4034
- $.utils.copyFrom(value, $.utils.getPointer(3, this));
4035
- }
4036
- toString() {
4037
- return "FileMetadata_" + super.toString();
4038
- }
4039
- };
4040
- var FileIdentifier = class extends $.Struct {
4041
- static {
4042
- __name(this, "FileIdentifier");
4043
- }
4044
- static _capnp = {
4045
- displayName: "FileIdentifier",
4046
- id: "e12b8732389d7406",
4047
- size: new $.ObjectSize(0, 2)
4048
- };
4049
- /**
4050
- * An additional identifier for the file.
4051
- *
4052
- */
4053
- get path() {
4054
- return $.utils.getText(0, this);
4055
- }
4056
- set path(value) {
4057
- $.utils.setText(0, value, this);
4058
- }
4059
- get id() {
4060
- return $.utils.getText(1, this);
4061
- }
4062
- set id(value) {
4063
- $.utils.setText(1, value, this);
4064
- }
4065
- toString() {
4066
- return "FileIdentifier_" + super.toString();
4067
- }
4068
- };
4069
- var FileData = class extends $.Struct {
4070
- static {
4071
- __name(this, "FileData");
4072
- }
4073
- static _capnp = {
4074
- displayName: "FileData",
4075
- id: "fa6725c8a360f9a2",
4076
- size: new $.ObjectSize(0, 2)
4077
- };
4078
- /**
4079
- * The contents of the file.
4080
- *
4081
- */
4082
- get path() {
4083
- return $.utils.getText(0, this);
4084
- }
4085
- set path(value) {
4086
- $.utils.setText(0, value, this);
4087
- }
4088
- get content() {
4089
- return $.utils.getText(1, this);
4090
- }
4091
- set content(value) {
4092
- $.utils.setText(1, value, this);
4093
- }
4094
- toString() {
4095
- return "FileData_" + super.toString();
4096
- }
4097
- };
4098
- var FileSystemData = class _FileSystemData extends $.Struct {
4099
- static {
4100
- __name(this, "FileSystemData");
4101
- }
4102
- static _capnp = {
4103
- displayName: "FileSystemData",
4104
- id: "aaa72a672ac0732f",
4105
- size: new $.ObjectSize(0, 3)
4106
- };
4107
- static _Ids;
4108
- static _Metadata;
4109
- static _Files;
4110
- _adoptIds(value) {
4111
- $.utils.adopt(value, $.utils.getPointer(0, this));
4112
- }
4113
- _disownIds() {
4114
- return $.utils.disown(this.ids);
4115
- }
4116
- get ids() {
4117
- return $.utils.getList(0, _FileSystemData._Ids, this);
4118
- }
4119
- _hasIds() {
4120
- return !$.utils.isNull($.utils.getPointer(0, this));
4121
- }
4122
- _initIds(length) {
4123
- return $.utils.initList(0, _FileSystemData._Ids, length, this);
4124
- }
4125
- set ids(value) {
4126
- $.utils.copyFrom(value, $.utils.getPointer(0, this));
4127
- }
4128
- _adoptMetadata(value) {
4129
- $.utils.adopt(value, $.utils.getPointer(1, this));
4130
- }
4131
- _disownMetadata() {
4132
- return $.utils.disown(this.metadata);
4133
- }
4134
- get metadata() {
4135
- return $.utils.getList(1, _FileSystemData._Metadata, this);
4136
- }
4137
- _hasMetadata() {
4138
- return !$.utils.isNull($.utils.getPointer(1, this));
4139
- }
4140
- _initMetadata(length) {
4141
- return $.utils.initList(1, _FileSystemData._Metadata, length, this);
4142
- }
4143
- set metadata(value) {
4144
- $.utils.copyFrom(value, $.utils.getPointer(1, this));
4145
- }
4146
- _adoptFiles(value) {
4147
- $.utils.adopt(value, $.utils.getPointer(2, this));
4148
- }
4149
- _disownFiles() {
4150
- return $.utils.disown(this.files);
4151
- }
4152
- get files() {
4153
- return $.utils.getList(2, _FileSystemData._Files, this);
4154
- }
4155
- _hasFiles() {
4156
- return !$.utils.isNull($.utils.getPointer(2, this));
4157
- }
4158
- _initFiles(length) {
4159
- return $.utils.initList(2, _FileSystemData._Files, length, this);
4160
- }
4161
- set files(value) {
4162
- $.utils.copyFrom(value, $.utils.getPointer(2, this));
4163
- }
4164
- toString() {
4165
- return "FileSystemData_" + super.toString();
4166
- }
4167
- };
4168
- FileMetadata._Properties = $.CompositeList(FileMetadata_KeyValuePair);
4169
- FileSystemData._Ids = $.CompositeList(FileIdentifier);
4170
- FileSystemData._Metadata = $.CompositeList(FileMetadata);
4171
- FileSystemData._Files = $.CompositeList(FileData);
4172
4352
 
4173
4353
  // ../powerlines/src/index.ts
4174
4354
  var src_default = PowerlinesAPI;
@@ -4183,7 +4363,7 @@ function withExecutor(command, executorFn) {
4183
4363
  throw new Error("The executor requires `projectsConfigurations` on the context object.");
4184
4364
  }
4185
4365
  const projectConfig = context.projectsConfigurations.projects[context.projectName];
4186
- const api = await src_default.from(workspaceConfig.workspaceRoot, defu3({
4366
+ const api = await src_default.from(workspaceConfig.workspaceRoot, defu2({
4187
4367
  root: projectConfig.root,
4188
4368
  type: projectConfig.projectType,
4189
4369
  sourceRoot: projectConfig.sourceRoot,
@@ -4196,7 +4376,7 @@ function withExecutor(command, executorFn) {
4196
4376
  }
4197
4377
  }, options));
4198
4378
  try {
4199
- return await Promise.resolve(executorFn(defu3({
4379
+ return await Promise.resolve(executorFn(defu2({
4200
4380
  projectName: context.projectName,
4201
4381
  options,
4202
4382
  workspaceConfig,