@powerlines/nx 0.10.37 → 0.10.38

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 (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{chunk-KTB7KDCP.mjs → chunk-2SK7GXYX.mjs} +1 -1
  3. package/dist/{chunk-R6CZOQMS.mjs → chunk-37R7Z4YA.mjs} +1 -1
  4. package/dist/{chunk-5HP24RWY.js → chunk-55HWRJFI.js} +2 -2
  5. package/dist/{chunk-53FEJYJL.js → chunk-5IM5S57N.js} +2 -2
  6. package/dist/{chunk-YMEHBI54.mjs → chunk-7Z54WTD3.mjs} +1 -1
  7. package/dist/{chunk-EKHF27MZ.mjs → chunk-BM5C4GAH.mjs} +1 -1
  8. package/dist/{chunk-UZF6PHPR.js → chunk-CJE2WIZT.js} +2 -2
  9. package/dist/{chunk-ZH5WF5UY.js → chunk-DDZYTWHI.js} +2 -2
  10. package/dist/{chunk-RWFBSRGJ.js → chunk-DNMCZOZX.js} +2 -2
  11. package/dist/{chunk-2PYUYDPD.js → chunk-DQI2I5KK.js} +1 -3
  12. package/dist/{chunk-C3K6TKXH.js → chunk-F7EY5OCV.js} +903 -919
  13. package/dist/{chunk-Q3ODFYEY.mjs → chunk-HJZ2I6NE.mjs} +1 -1
  14. package/dist/{chunk-D4UEK625.js → chunk-JXYA5T7X.js} +2 -2
  15. package/dist/{chunk-XZORJRHX.js → chunk-KBRCV5NY.js} +3 -3
  16. package/dist/{chunk-LLXWCS4O.mjs → chunk-OIL7SLIA.mjs} +1 -1
  17. package/dist/{chunk-HI5N4XXZ.mjs → chunk-OS2GSBDL.mjs} +899 -914
  18. package/dist/{chunk-WGIN2BGP.mjs → chunk-OVX2CEXQ.mjs} +1 -3
  19. package/dist/{chunk-32H4LR4S.mjs → chunk-PWZ3J3N6.mjs} +1 -1
  20. package/dist/executors.js +15 -15
  21. package/dist/executors.mjs +7 -7
  22. package/dist/index.js +18 -18
  23. package/dist/index.mjs +9 -9
  24. package/dist/src/base/base-executor.js +3 -3
  25. package/dist/src/base/base-executor.mjs +2 -2
  26. package/dist/src/executors/build/executor.js +5 -5
  27. package/dist/src/executors/build/executor.mjs +3 -3
  28. package/dist/src/executors/clean/executor.js +5 -5
  29. package/dist/src/executors/clean/executor.mjs +3 -3
  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/lint/executor.js +5 -5
  33. package/dist/src/executors/lint/executor.mjs +3 -3
  34. package/dist/src/executors/prepare/executor.js +5 -5
  35. package/dist/src/executors/prepare/executor.mjs +3 -3
  36. package/dist/src/helpers/plugin-utilities.js +5 -5
  37. package/dist/src/helpers/plugin-utilities.mjs +2 -2
  38. package/dist/src/plugin/index.js +4 -4
  39. package/dist/src/plugin/index.mjs +3 -3
  40. package/package.json +8 -8
@@ -1,18 +1,19 @@
1
- import { loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, loadUserConfigFile, writeMetaFile } from './chunk-WGIN2BGP.mjs';
1
+ import { loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, loadUserConfigFile, writeMetaFile } from './chunk-OVX2CEXQ.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 defu5, { defu } from 'defu';
6
+ import defu6, { 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';
10
10
  import { toArray } from '@stryke/convert/to-array';
11
11
  import { copyFiles } from '@stryke/fs/copy-file';
12
+ import { createDirectory } from '@stryke/fs/helpers';
12
13
  import { install } from '@stryke/fs/install';
13
- import { listFiles, listFilesSync } from '@stryke/fs/list-files';
14
+ import { listFilesSync, listFiles } from '@stryke/fs/list-files';
14
15
  import { isPackageExists, isPackageListed, doesPackageMatch, getPackageListing } from '@stryke/fs/package-fns';
15
- import { getResolutionCombinations, resolve, resolveSync, resolvePackage } from '@stryke/fs/resolve';
16
+ import { getResolutionCombinations, resolve as resolve$1, resolveSync, resolvePackage } from '@stryke/fs/resolve';
16
17
  import { appendPath } from '@stryke/path/append';
17
18
  import { joinPaths as joinPaths$1 } from '@stryke/path/join-paths';
18
19
  import { replacePath, replaceExtension } from '@stryke/path/replace';
@@ -27,14 +28,16 @@ import Handlebars from 'handlebars';
27
28
  import { declare } from '@babel/helper-plugin-utils';
28
29
  import * as t from '@babel/types';
29
30
  import ts, { flattenDiagnosticMessageText } from 'typescript';
31
+ import { joinPaths } from '@stryke/path/join';
32
+ import { InMemoryFileSystemHost, Project } from 'ts-morph';
30
33
  import { getPackageName, hasPackageVersion, getPackageVersion } from '@stryke/string-format/package';
31
34
  import { getObjectDiff } from '@donedeal0/superdiff';
32
35
  import { readJsonFile, readJsonFileSync } from '@stryke/fs/json';
33
36
  import { StormJSON } from '@stryke/json/storm-json';
34
- import { findFilePath, findFileExtension, relativePath, findFileName, findFileDotExtensionSafe } from '@stryke/path/file-path-fns';
37
+ import { hasFileExtension, findFilePath, findFileName, relativePath, findFileDotExtensionSafe } from '@stryke/path/file-path-fns';
35
38
  import { titleCase } from '@stryke/string-format/title-case';
36
- import { existsSync } from '@stryke/fs/exists';
37
- import { writeFile as writeFile$1 } from '@stryke/fs/write-file';
39
+ import { existsSync, exists } from '@stryke/fs/exists';
40
+ import { writeFileSync, writeFile as writeFile$1 } from '@stryke/fs/write-file';
38
41
  import { resolveConfig, format } from 'prettier';
39
42
  import { getEnvPaths } from '@stryke/env/get-env-paths';
40
43
  import { relativeToWorkspaceRoot } from '@stryke/fs/get-workspace-root';
@@ -43,7 +46,6 @@ import { murmurhash } from '@stryke/hash/murmurhash';
43
46
  import { getUnique, getUniqueBy } from '@stryke/helpers/get-unique';
44
47
  import { omit } from '@stryke/helpers/omit';
45
48
  import { isAbsolutePath, isAbsolute } from '@stryke/path/is-type';
46
- import { joinPaths } from '@stryke/path/join';
47
49
  import { isNull } from '@stryke/type-checks/is-null';
48
50
  import { isString } from '@stryke/type-checks/is-string';
49
51
  import { uuid } from '@stryke/unique-id/uuid';
@@ -53,21 +55,19 @@ import { isUndefined } from '@stryke/type-checks/is-undefined';
53
55
  import { parseTypeDefinition } from '@stryke/convert/parse-type-definition';
54
56
  import { isFile } from '@stryke/fs/is-file';
55
57
  import * as $ from '@stryke/capnp';
56
- import { bufferToString } from '@stryke/convert/buffer-to-string';
57
58
  import { readFileBuffer, readFileBufferSync, writeFileBuffer } from '@stryke/fs/buffer';
58
- import { toAbsolutePath, correctPath } from '@stryke/path/correct-path';
59
+ import { correctPath, toAbsolutePath } from '@stryke/path/correct-path';
60
+ import { isParentPath } from '@stryke/path/is-parent-path';
59
61
  import { prettyBytes } from '@stryke/string-format/pretty-bytes';
60
- import { isBuffer } from '@stryke/type-checks/is-buffer';
61
62
  import { create } from 'flat-cache';
62
63
  import { Blob } from 'node:buffer';
63
- import _fs from 'node:fs';
64
64
  import { getColor } from '@storm-software/config-tools/utilities/colors';
65
65
  import { noop } from '@stryke/helpers/noop';
66
66
  import { slash } from '@stryke/path/slash';
67
- import { isParentPath } from '@stryke/path/is-parent-path';
68
- import { Volume } from 'memfs';
69
- import { Union } from 'unionfs';
70
- import { InMemoryFileSystemHost, Project } from 'ts-morph';
67
+ import { readFileSync, readFile } from '@stryke/fs/read-file';
68
+ import { unlinkSync } from 'node:fs';
69
+ import { unlink } from 'node:fs/promises';
70
+ import { resolve } from 'node:path';
71
71
  import { isObject } from '@stryke/type-checks/is-object';
72
72
 
73
73
  function resolveModulePath(nodePath, state) {
@@ -171,6 +171,108 @@ var moduleResolverBabelPlugin = /* @__PURE__ */ __name((context) => {
171
171
  };
172
172
  }, "builder"));
173
173
  }, "moduleResolverBabelPlugin");
174
+ var VirtualFileSystemHost = class extends InMemoryFileSystemHost {
175
+ static {
176
+ __name(this, "VirtualFileSystemHost");
177
+ }
178
+ #context;
179
+ constructor(context) {
180
+ super();
181
+ this.#context = context;
182
+ }
183
+ deleteSync(path) {
184
+ this.#context.fs.removeSync(path);
185
+ }
186
+ readDirSync(dirPath) {
187
+ return this.#context.fs.listSync(dirPath).reduce((ret, entry) => {
188
+ const fullPath = this.#context.fs.resolveSync(joinPaths(dirPath, entry));
189
+ if (fullPath) {
190
+ ret.push({
191
+ name: entry,
192
+ isDirectory: this.#context.fs.existsSync(fullPath),
193
+ isFile: this.#context.fs.existsSync(fullPath),
194
+ isSymlink: false
195
+ });
196
+ }
197
+ return ret;
198
+ }, []);
199
+ }
200
+ async readFile(filePath) {
201
+ if (!this.#context.fs.existsSync(filePath)) {
202
+ throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
203
+ }
204
+ return await this.#context.fs.read(filePath);
205
+ }
206
+ readFileSync(filePath) {
207
+ if (!this.#context.fs.existsSync(filePath)) {
208
+ throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
209
+ }
210
+ return this.#context.fs.readSync(filePath);
211
+ }
212
+ async writeFile(filePath, fileText) {
213
+ return this.#context.fs.write(filePath, fileText);
214
+ }
215
+ writeFileSync(filePath, fileText) {
216
+ this.#context.fs.writeSync(filePath, fileText);
217
+ }
218
+ async mkdir(_dirPath) {
219
+ }
220
+ mkdirSync(_dirPath) {
221
+ }
222
+ async move(srcPath, destPath) {
223
+ await this.#context.fs.move(srcPath, destPath);
224
+ }
225
+ moveSync(srcPath, destPath) {
226
+ this.#context.fs.moveSync(srcPath, destPath);
227
+ }
228
+ async copy(srcPath, destPath) {
229
+ await this.#context.fs.copy(srcPath, destPath);
230
+ }
231
+ copySync(srcPath, destPath) {
232
+ this.#context.fs.copySync(srcPath, destPath);
233
+ }
234
+ async fileExists(filePath) {
235
+ return this.#context.fs.exists(filePath);
236
+ }
237
+ fileExistsSync(filePath) {
238
+ return this.#context.fs.existsSync(filePath);
239
+ }
240
+ async directoryExists(dirPath) {
241
+ return this.#context.fs.exists(dirPath);
242
+ }
243
+ directoryExistsSync(dirPath) {
244
+ return this.#context.fs.existsSync(dirPath);
245
+ }
246
+ realpathSync(path) {
247
+ return this.#context.fs.resolveSync(path) || path;
248
+ }
249
+ getCurrentDirectory() {
250
+ return this.#context.workspaceConfig.workspaceRoot;
251
+ }
252
+ async glob(patterns) {
253
+ return this.#context.fs.glob(patterns);
254
+ }
255
+ globSync(patterns) {
256
+ return this.#context.fs.globSync(patterns);
257
+ }
258
+ };
259
+ function createProgram(context, override) {
260
+ context.log(LogLevelLabel.TRACE, `Creating ts-morph Project instance with configuration from: ${context.tsconfig.tsconfigFilePath}.`);
261
+ const project = new Project(defu6(override ?? {}, {
262
+ skipAddingFilesFromTsConfig: false,
263
+ tsConfigFilePath: context.tsconfig.tsconfigFilePath,
264
+ fileSystem: new VirtualFileSystemHost(context),
265
+ compilerOptions: defu6(context.tsconfig.options ?? {}, {
266
+ lib: [
267
+ "lib.esnext.full.d.ts"
268
+ ]
269
+ })
270
+ }));
271
+ return project;
272
+ }
273
+ __name(createProgram, "createProgram");
274
+
275
+ // ../powerlines/src/internal/helpers/generate-types.ts
174
276
  function formatTypes(code) {
175
277
  return code.replace(
176
278
  // eslint-disable-next-line regexp/no-super-linear-backtracking
@@ -181,8 +283,11 @@ function formatTypes(code) {
181
283
  __name(formatTypes, "formatTypes");
182
284
  async function emitTypes(context, files) {
183
285
  context.log(LogLevelLabel.TRACE, `Running the TypeScript compiler for ${files.length} generated runtime files.`);
184
- context.program.addSourceFilesAtPaths(files);
185
- const result = context.program.emitToMemory({
286
+ const program = createProgram(context, {
287
+ skipAddingFilesFromTsConfig: true
288
+ });
289
+ program.addSourceFilesAtPaths(files);
290
+ const result = program.emitToMemory({
186
291
  emitOnlyDtsFiles: true
187
292
  });
188
293
  let builtinModules = "";
@@ -385,7 +490,7 @@ function getParsedTypeScriptConfig(workspaceRoot, projectRoot, tsconfig, tsconfi
385
490
  if (!tsconfigJson) {
386
491
  throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${joinPaths$1(projectRoot, tsconfig ?? "tsconfig.json")}`);
387
492
  }
388
- const parsedCommandLine = ts.parseJsonConfigFileContent(defu5(tsconfigRaw ?? {}, tsconfigJson), host, appendPath(projectRoot, workspaceRoot));
493
+ const parsedCommandLine = ts.parseJsonConfigFileContent(defu6(tsconfigRaw ?? {}, tsconfigJson), host, appendPath(projectRoot, workspaceRoot));
389
494
  if (parsedCommandLine.errors.length > 0) {
390
495
  const errorMessage = `Cannot parse the TypeScript compiler options. Please investigate the following issues:
391
496
  ${parsedCommandLine.errors.map((error) => `- ${(error.category !== void 0 && error.code ? `[${error.category}-${error.code}]: ` : "") + error.messageText.toString()}`).join("\n")}
@@ -426,9 +531,6 @@ async function resolveTsconfigChanges(context) {
426
531
  const tsconfigJson = await readJsonFile(tsconfigFilePath);
427
532
  tsconfigJson.compilerOptions ??= {};
428
533
  if (context.config.output.dts !== false) {
429
- if (findFileExtension(context.dtsPath) !== "d.ts" && findFileExtension(context.dtsPath) !== "d.cts" && findFileExtension(context.dtsPath) !== "d.mts") {
430
- context.config.output.dts = joinPaths$1(context.dtsPath, "powerlines.d.ts");
431
- }
432
534
  const dtsRelativePath = joinPaths$1(relativePath(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot), findFilePath(context.dtsPath)), findFileName(context.dtsPath));
433
535
  if (!tsconfigJson.include?.some((filePattern) => isIncludeMatchFound(filePattern, [
434
536
  context.dtsPath,
@@ -471,9 +573,7 @@ async function initializeTsconfig(context) {
471
573
  context.tsconfig.originalTsconfigJson = await readJsonFile(tsconfigFilePath);
472
574
  context.tsconfig.tsconfigJson = await resolveTsconfigChanges(context);
473
575
  context.log(LogLevelLabel.TRACE, "Writing updated TypeScript configuration (tsconfig.json) file to disk.");
474
- await context.fs.writeFile(tsconfigFilePath, StormJSON.stringify(context.tsconfig.tsconfigJson), {
475
- mode: "fs"
476
- });
576
+ await writeFile(context.log, tsconfigFilePath, StormJSON.stringify(context.tsconfig.tsconfigJson));
477
577
  context.tsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.config.tsconfig, context.config.tsconfigRaw, context.tsconfig.originalTsconfigJson);
478
578
  }
479
579
  __name(initializeTsconfig, "initializeTsconfig");
@@ -533,7 +633,7 @@ async function resolveTsconfig(context) {
533
633
  __name(resolveTsconfig, "resolveTsconfig");
534
634
  var DEFAULT_ENVIRONMENT = "default";
535
635
  function createEnvironment(name, userConfig) {
536
- return defu5(userConfig.environments?.[name] ?? {}, {
636
+ return defu6(userConfig.environments?.[name] ?? {}, {
537
637
  name,
538
638
  title: userConfig.title || titleCase(userConfig.name),
539
639
  ssr: false,
@@ -577,8 +677,7 @@ function createDefaultEnvironment(userConfig) {
577
677
  }
578
678
  __name(createDefaultEnvironment, "createDefaultEnvironment");
579
679
  function resolveOptions(options) {
580
- return defu5(options, {
581
- debug: options.logLevel === "trace",
680
+ return defu6(options, {
582
681
  interopDefault: true,
583
682
  fsCache: options.mode !== "development" ? joinPaths$1(options.cacheDir, "jiti") : false,
584
683
  moduleCache: options.mode !== "development"
@@ -669,7 +768,7 @@ function replacePathTokens(context, path) {
669
768
  if (!path) {
670
769
  return path;
671
770
  }
672
- 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("{outputPath}", context.config.output.outputPath).replaceAll("{distPath}", context.config.output.distPath).replaceAll("{artifactsPath}", replacePath(context.artifactsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{builtinPath}", replacePath(context.builtinsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{entryPath}", replacePath(context.entryPath, context.workspaceConfig.workspaceRoot));
771
+ 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("{outputPath}", context.config.output.outputPath).replaceAll("{buildPath}", context.config.output.buildPath).replaceAll("{artifactsPath}", replacePath(context.artifactsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{builtinPath}", replacePath(context.builtinsPath, context.workspaceConfig.workspaceRoot)).replaceAll("{entryPath}", replacePath(context.entryPath, context.workspaceConfig.workspaceRoot));
673
772
  }
674
773
  __name(replacePathTokens, "replacePathTokens");
675
774
  function resolveEntryInputFile(context, typeDefinition) {
@@ -753,7 +852,7 @@ var FileMetadata = class _FileMetadata extends $.Struct {
753
852
  static _capnp = {
754
853
  displayName: "FileMetadata",
755
854
  id: "8e2cab5d7e28c7b3",
756
- size: new $.ObjectSize(8, 4),
855
+ size: new $.ObjectSize(8, 3),
757
856
  defaultType: "normal"
758
857
  };
759
858
  static _Properties;
@@ -768,7 +867,7 @@ var FileMetadata = class _FileMetadata extends $.Struct {
768
867
  $.utils.setText(0, value, this);
769
868
  }
770
869
  /**
771
- * The output mode of the file.
870
+ * The timestamp representing the file's creation date.
772
871
  *
773
872
  */
774
873
  get type() {
@@ -778,16 +877,6 @@ var FileMetadata = class _FileMetadata extends $.Struct {
778
877
  $.utils.setText(1, value, this);
779
878
  }
780
879
  /**
781
- * The timestamp representing the file's creation date.
782
- *
783
- */
784
- get mode() {
785
- return $.utils.getText(2, this);
786
- }
787
- set mode(value) {
788
- $.utils.setText(2, value, this);
789
- }
790
- /**
791
880
  * Additional metadata associated with the file.
792
881
  *
793
882
  */
@@ -798,22 +887,22 @@ var FileMetadata = class _FileMetadata extends $.Struct {
798
887
  $.utils.setUint32(0, value, this);
799
888
  }
800
889
  _adoptProperties(value) {
801
- $.utils.adopt(value, $.utils.getPointer(3, this));
890
+ $.utils.adopt(value, $.utils.getPointer(2, this));
802
891
  }
803
892
  _disownProperties() {
804
893
  return $.utils.disown(this.properties);
805
894
  }
806
895
  get properties() {
807
- return $.utils.getList(3, _FileMetadata._Properties, this);
896
+ return $.utils.getList(2, _FileMetadata._Properties, this);
808
897
  }
809
898
  _hasProperties() {
810
- return !$.utils.isNull($.utils.getPointer(3, this));
899
+ return !$.utils.isNull($.utils.getPointer(2, this));
811
900
  }
812
901
  _initProperties(length) {
813
- return $.utils.initList(3, _FileMetadata._Properties, length, this);
902
+ return $.utils.initList(2, _FileMetadata._Properties, length, this);
814
903
  }
815
904
  set properties(value) {
816
- $.utils.copyFrom(value, $.utils.getPointer(3, this));
905
+ $.utils.copyFrom(value, $.utils.getPointer(2, this));
817
906
  }
818
907
  toString() {
819
908
  return "FileMetadata_" + super.toString();
@@ -848,13 +937,13 @@ var FileId = class extends $.Struct {
848
937
  return "FileId_" + super.toString();
849
938
  }
850
939
  };
851
- var FileData = class extends $.Struct {
940
+ var FileStorage = class extends $.Struct {
852
941
  static {
853
- __name(this, "FileData");
942
+ __name(this, "FileStorage");
854
943
  }
855
944
  static _capnp = {
856
- displayName: "FileData",
857
- id: "fa6725c8a360f9a2",
945
+ displayName: "FileStorage",
946
+ id: "9dca66ac858c9ebe",
858
947
  size: new $.ObjectSize(0, 2)
859
948
  };
860
949
  /**
@@ -874,7 +963,7 @@ var FileData = class extends $.Struct {
874
963
  $.utils.setText(1, value, this);
875
964
  }
876
965
  toString() {
877
- return "FileData_" + super.toString();
966
+ return "FileStorage_" + super.toString();
878
967
  }
879
968
  };
880
969
  var FileSystem = class _FileSystem extends $.Struct {
@@ -887,7 +976,7 @@ var FileSystem = class _FileSystem extends $.Struct {
887
976
  size: new $.ObjectSize(0, 3)
888
977
  };
889
978
  static _Ids;
890
- static _Files;
979
+ static _Storage;
891
980
  static _Metadata;
892
981
  _adoptIds(value) {
893
982
  $.utils.adopt(value, $.utils.getPointer(0, this));
@@ -907,22 +996,22 @@ var FileSystem = class _FileSystem extends $.Struct {
907
996
  set ids(value) {
908
997
  $.utils.copyFrom(value, $.utils.getPointer(0, this));
909
998
  }
910
- _adoptFiles(value) {
999
+ _adoptStorage(value) {
911
1000
  $.utils.adopt(value, $.utils.getPointer(1, this));
912
1001
  }
913
- _disownFiles() {
914
- return $.utils.disown(this.files);
1002
+ _disownStorage() {
1003
+ return $.utils.disown(this.storage);
915
1004
  }
916
- get files() {
917
- return $.utils.getList(1, _FileSystem._Files, this);
1005
+ get storage() {
1006
+ return $.utils.getList(1, _FileSystem._Storage, this);
918
1007
  }
919
- _hasFiles() {
1008
+ _hasStorage() {
920
1009
  return !$.utils.isNull($.utils.getPointer(1, this));
921
1010
  }
922
- _initFiles(length) {
923
- return $.utils.initList(1, _FileSystem._Files, length, this);
1011
+ _initStorage(length) {
1012
+ return $.utils.initList(1, _FileSystem._Storage, length, this);
924
1013
  }
925
- set files(value) {
1014
+ set storage(value) {
926
1015
  $.utils.copyFrom(value, $.utils.getPointer(1, this));
927
1016
  }
928
1017
  _adoptMetadata(value) {
@@ -949,12 +1038,15 @@ var FileSystem = class _FileSystem extends $.Struct {
949
1038
  };
950
1039
  FileMetadata._Properties = $.CompositeList(FileMetadata_KeyValuePair);
951
1040
  FileSystem._Ids = $.CompositeList(FileId);
952
- FileSystem._Files = $.CompositeList(FileData);
1041
+ FileSystem._Storage = $.CompositeList(FileStorage);
953
1042
  FileSystem._Metadata = $.CompositeList(FileMetadata);
954
1043
 
955
1044
  // ../powerlines/src/types/fs.ts
956
- var __VFS_PATCH__ = "__VFS_PATCH__";
957
- var __VFS_REVERT__ = "__VFS_REVERT__";
1045
+ var StoragePreset = /* @__PURE__ */ (function(StoragePreset2) {
1046
+ StoragePreset2["VIRTUAL"] = "virtual";
1047
+ StoragePreset2["FS"] = "fs";
1048
+ return StoragePreset2;
1049
+ })({});
958
1050
  var createLog = /* @__PURE__ */ __name((name, options = {}) => {
959
1051
  const logLevel = options.logLevel === null ? LogLevelLabel.SILENT : options.logLevel || LogLevelLabel.INFO;
960
1052
  if (logLevel === LogLevelLabel.SILENT) {
@@ -993,142 +1085,18 @@ var BADGE_COLORS = [
993
1085
  var extendLog = /* @__PURE__ */ __name((logFn, name) => {
994
1086
  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(" ")} `);
995
1087
  }, "extendLog");
996
- function isBufferEncoding(options) {
997
- return isSetString(options) || options === null;
998
- }
999
- __name(isBufferEncoding, "isBufferEncoding");
1000
- function isPowerlinesWriteFileOptions(options) {
1001
- return !isBufferEncoding(options) && isSetObject(options) && "mode" in options && (options.mode === "fs" || options.mode === "virtual");
1088
+ function isFileError(err) {
1089
+ return isError(err) && "code" in err && err.code;
1002
1090
  }
1003
- __name(isPowerlinesWriteFileOptions, "isPowerlinesWriteFileOptions");
1004
- function isVirtualFileData(obj) {
1005
- return !!(isSetObject(obj) && "code" in obj && obj.code);
1091
+ __name(isFileError, "isFileError");
1092
+ function ignoreNotfound(err) {
1093
+ return isFileError(err) && (err.code === "ENOENT" || err.code === "EISDIR" ? null : err);
1006
1094
  }
1007
- __name(isVirtualFileData, "isVirtualFileData");
1095
+ __name(ignoreNotfound, "ignoreNotfound");
1008
1096
  function toFilePath(path) {
1009
1097
  return correctPath(slash(path?.toString() || ".").replace(/^file:\/\//, ""));
1010
1098
  }
1011
1099
  __name(toFilePath, "toFilePath");
1012
- var FS_METHODS = [
1013
- "mkdir",
1014
- "mkdirSync",
1015
- "rmdir",
1016
- "rmdirSync",
1017
- "unlink",
1018
- "unlinkSync",
1019
- "existsSync",
1020
- "realpathSync",
1021
- "writeFileSync",
1022
- "readFileSync",
1023
- "readdirSync",
1024
- "createWriteStream",
1025
- "WriteStream",
1026
- "createReadStream",
1027
- "ReadStream"
1028
- ];
1029
- var FS_PROMISE_METHODS = [
1030
- "mkdir",
1031
- "rm",
1032
- "rmdir",
1033
- "unlink",
1034
- "writeFile",
1035
- "readFile",
1036
- "readdir",
1037
- "stat",
1038
- "lstat"
1039
- ];
1040
- function cloneFS(originalFS) {
1041
- const clonedFS = {
1042
- ...originalFS,
1043
- promises: {
1044
- ...originalFS.promises ?? {}
1045
- }
1046
- };
1047
- for (const method of FS_METHODS) {
1048
- if (originalFS[method]) {
1049
- clonedFS[method] = originalFS[method];
1050
- }
1051
- }
1052
- originalFS.promises ??= {};
1053
- for (const method of FS_PROMISE_METHODS) {
1054
- if (originalFS.promises[method]) {
1055
- clonedFS.promises ??= {};
1056
- clonedFS.promises[method] = originalFS.promises[method];
1057
- clonedFS[method] = originalFS.promises[method];
1058
- }
1059
- }
1060
- for (const prop in clonedFS) {
1061
- if (isFunction(clonedFS[prop])) {
1062
- clonedFS[prop] = clonedFS[prop].bind(originalFS);
1063
- if (isFunction(clonedFS.promises[prop])) {
1064
- clonedFS.promises[prop] = clonedFS.promises[prop].bind(originalFS);
1065
- }
1066
- }
1067
- }
1068
- for (const prop in clonedFS.promises) {
1069
- if (isFunction(clonedFS.promises[prop])) {
1070
- clonedFS.promises[prop] = clonedFS.promises[prop].bind(originalFS);
1071
- }
1072
- }
1073
- return clonedFS;
1074
- }
1075
- __name(cloneFS, "cloneFS");
1076
- function patchFS(originalFS, vfs) {
1077
- const clonedFS = cloneFS(originalFS);
1078
- originalFS.mkdirSync = (file, options) => vfs.mkdirSync(toFilePath(file), options);
1079
- originalFS.mkdir = (file, options, callback) => vfs.mkdir(toFilePath(file), options, callback);
1080
- originalFS.promises.mkdir = async (file, options) => vfs.mkdir(toFilePath(file), options);
1081
- originalFS.unlinkSync = (file) => vfs.unlinkSync(toFilePath(file));
1082
- originalFS.promises.rm = async (file, options) => vfs.rm(toFilePath(file), options);
1083
- originalFS.promises.unlink = async (file) => vfs.unlink(toFilePath(file));
1084
- originalFS.existsSync = (file) => vfs.existsSync(toFilePath(file));
1085
- Object.defineProperty(originalFS, "realpathSync", {
1086
- value: /* @__PURE__ */ __name((file, options) => vfs.realpathSync(toFilePath(file), options), "value")
1087
- });
1088
- originalFS.writeFileSync = (file, data, options) => vfs.writeFileSync(toFilePath(file), data, options);
1089
- originalFS.promises.writeFile = async (file, data, options) => vfs.writeFile(toFilePath(file), data, options);
1090
- originalFS.readFileSync = (file, options) => vfs.readFileSync(toFilePath(file), options);
1091
- originalFS.promises.readFile = (file, options) => vfs.readFile(toFilePath(file), options);
1092
- originalFS.readdirSync = (file, options) => vfs.readdirSync(toFilePath(file), options);
1093
- originalFS.promises.readdir = (file, options) => vfs.readdir(toFilePath(file), options);
1094
- Object.defineProperty(originalFS, "statSync", {
1095
- value: /* @__PURE__ */ __name((file, options) => vfs.statSync(toFilePath(file), options), "value")
1096
- });
1097
- originalFS.stat = (file, options) => vfs.statSync(toFilePath(file), options);
1098
- originalFS.promises.stat = (file, options) => vfs.stat(toFilePath(file), options);
1099
- Object.defineProperty(originalFS, "lstatSync", {
1100
- value: /* @__PURE__ */ __name((file, options) => vfs.lstatSync(toFilePath(file), options), "value")
1101
- });
1102
- originalFS.lstat = (file, options) => vfs.lstatSync(toFilePath(file), options);
1103
- originalFS.promises.lstat = (file, options) => vfs.lstat(toFilePath(file), options);
1104
- return () => {
1105
- originalFS.mkdirSync = clonedFS.mkdirSync;
1106
- originalFS.mkdir = clonedFS.mkdir;
1107
- originalFS.promises.mkdir = clonedFS.promises.mkdir;
1108
- originalFS.unlinkSync = clonedFS.unlinkSync;
1109
- originalFS.promises.rm = clonedFS.promises.rm;
1110
- originalFS.promises.unlink = clonedFS.promises.unlink;
1111
- originalFS.existsSync = clonedFS.existsSync;
1112
- originalFS.realpathSync = clonedFS.realpathSync;
1113
- originalFS.writeFileSync = clonedFS.writeFileSync;
1114
- originalFS.promises.writeFile = clonedFS.promises.writeFile;
1115
- originalFS.readFileSync = clonedFS.readFileSync;
1116
- originalFS.promises.readFile = clonedFS.promises.readFile;
1117
- originalFS.readdirSync = clonedFS.readdirSync;
1118
- originalFS.promises.readdir = clonedFS.promises.readdir;
1119
- Object.defineProperty(originalFS, "statSync", {
1120
- value: clonedFS.statSync
1121
- });
1122
- originalFS.stat = clonedFS.stat;
1123
- originalFS.promises.stat = clonedFS.promises.stat;
1124
- Object.defineProperty(originalFS, "lstatSync", {
1125
- value: clonedFS.lstatSync
1126
- });
1127
- originalFS.lstat = clonedFS.lstat;
1128
- originalFS.promises.lstat = clonedFS.promises.lstat;
1129
- };
1130
- }
1131
- __name(patchFS, "patchFS");
1132
1100
  function isValidId(id, prefix = "powerlines") {
1133
1101
  return id.replace(/^\\0/, "").startsWith(`${prefix.replace(/:$/, "")}`);
1134
1102
  }
@@ -1138,164 +1106,368 @@ function normalizeId(id, prefix = "powerlines") {
1138
1106
  }
1139
1107
  __name(normalizeId, "normalizeId");
1140
1108
  function normalizePath(path, builtinsPath, prefix = "powerlines") {
1141
- return isValidId(toFilePath(path), prefix) ? normalizeId(toFilePath(path), prefix).replace(new RegExp(`^${prefix.replace(/:$/, "")}:`), builtinsPath) : toFilePath(path);
1109
+ return isAbsolutePath(path) ? path : isValidId(toFilePath(path), prefix) ? normalizeId(toFilePath(path), prefix).replace(new RegExp(`^${prefix.replace(/:$/, "")}:`), builtinsPath) : toFilePath(path);
1142
1110
  }
1143
1111
  __name(normalizePath, "normalizePath");
1144
- var UnifiedFS = class _UnifiedFS extends Union {
1112
+ function normalizeKey(key, sep = ":") {
1113
+ if (!key) {
1114
+ return "";
1115
+ }
1116
+ return key.replace(/[:/\\]/g, sep).replace(/^[:/\\]|[:/\\]$/g, "");
1117
+ }
1118
+ __name(normalizeKey, "normalizeKey");
1119
+ function filterKeyByBase(key, base) {
1120
+ if (base) {
1121
+ return key.startsWith(base) && key[key.length - 1] !== "$";
1122
+ }
1123
+ return key[key.length - 1] !== "$";
1124
+ }
1125
+ __name(filterKeyByBase, "filterKeyByBase");
1126
+ var BaseStorageAdapter = class {
1145
1127
  static {
1146
- __name(this, "UnifiedFS");
1128
+ __name(this, "BaseStorageAdapter");
1147
1129
  }
1148
1130
  /**
1149
- * The internal map of virtual files.
1131
+ * Indicates whether the storage adapter has been disposed.
1150
1132
  */
1151
- #virtualFS = new Volume();
1133
+ #isDisposed = false;
1152
1134
  /**
1153
- * The physical file system.
1135
+ * Configuration options for the storage adapter.
1154
1136
  */
1155
- #physicalFS = cloneFS(_fs);
1137
+ options;
1156
1138
  /**
1157
- * The context of the unified file system.
1139
+ * Constructor for the BaseStorageAdapter.
1140
+ *
1141
+ * @param options - Configuration options for the storage adapter.
1158
1142
  */
1159
- #context;
1160
- static create(context, fs2) {
1161
- let result = new _UnifiedFS(context, fs2);
1162
- result = result.use(result.#physicalFS);
1163
- if (result.#context.config.output.mode !== "fs") {
1164
- result = result.use(result.#virtualFS);
1165
- }
1166
- return result;
1143
+ constructor(options = {
1144
+ base: "/"
1145
+ }) {
1146
+ this.options = options;
1147
+ this.options.base = resolve(options.base);
1148
+ this.options.isReadOnly = !!options.isReadOnly;
1167
1149
  }
1168
1150
  /**
1169
- * Gets the virtual file system (VFS).
1151
+ * Asynchronously checks if a key exists in the storage.
1152
+ *
1153
+ * @param key - The key to check for existence.
1154
+ * @returns A promise that resolves to `true` if the key exists, otherwise `false`.
1170
1155
  */
1171
- get virtual() {
1172
- return this.#virtualFS;
1156
+ async exists(key) {
1157
+ return this.existsSync(key);
1173
1158
  }
1174
1159
  /**
1175
- * Gets the physical file system (FS).
1160
+ * Asynchronously retrieves the value associated with a given key.
1161
+ *
1162
+ * @param key - The key whose value is to be retrieved.
1163
+ * @returns A promise that resolves to the value associated with the key, or `null` if the key does not exist.
1176
1164
  */
1177
- get physical() {
1178
- return this.#physicalFS;
1165
+ async get(key) {
1166
+ return this.getSync(key);
1179
1167
  }
1180
1168
  /**
1181
- * Creates a new instance of the VirtualFileSystem.
1169
+ * Asynchronously sets the value for a given key.
1182
1170
  *
1183
- * @param context - The context of the virtual file system, typically containing options and logging functions.
1184
- * @param fs - A buffer containing the serialized virtual file system data.
1171
+ * @param key - The key to set the value for.
1172
+ * @param value - The value to set.
1185
1173
  */
1186
- constructor(context, fs2) {
1187
- super();
1188
- this.#context = context;
1189
- if (!this.#physicalFS.existsSync(this.#context.dataPath)) {
1190
- this.#physicalFS.mkdirSync(this.#context.dataPath, {
1191
- recursive: true
1192
- });
1193
- }
1194
- if (!this.#physicalFS.existsSync(this.#context.cachePath)) {
1195
- this.#physicalFS.mkdirSync(this.#context.cachePath, {
1196
- recursive: true
1197
- });
1174
+ async set(key, value) {
1175
+ if (!this.options.isReadOnly) {
1176
+ this.setSync(key, value);
1198
1177
  }
1199
- if (!this.#physicalFS.existsSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.distPath))) {
1200
- this.#physicalFS.mkdirSync(joinPaths(this.#context.workspaceConfig.workspaceRoot, this.#context.config.output.distPath), {
1201
- recursive: true
1202
- });
1178
+ }
1179
+ /**
1180
+ * Asynchronously removes a key from the storage.
1181
+ *
1182
+ * @param key - The key to remove.
1183
+ */
1184
+ async remove(key) {
1185
+ if (!this.options.isReadOnly) {
1186
+ this.removeSync(key);
1203
1187
  }
1204
- if (this.#context.config.output.mode !== "fs") {
1205
- this.#virtualFS = Volume.fromJSON(fs2._hasFiles() && fs2.files.length > 0 ? fs2.files.values().reduce((ret, file) => {
1206
- ret[file.path] = file.code;
1207
- return ret;
1208
- }, {}) : {});
1209
- if (!this.#virtualFS.existsSync(this.#context.artifactsPath)) {
1210
- this.#virtualFS.mkdirSync(this.#context.artifactsPath, {
1211
- recursive: true
1212
- });
1213
- }
1214
- if (!this.#virtualFS.existsSync(this.#context.builtinsPath)) {
1215
- this.#virtualFS.mkdirSync(this.#context.builtinsPath, {
1216
- recursive: true
1217
- });
1218
- }
1219
- if (!this.#virtualFS.existsSync(this.#context.entryPath)) {
1220
- this.#virtualFS.mkdirSync(this.#context.entryPath, {
1221
- recursive: true
1222
- });
1223
- }
1224
- if (!this.#virtualFS.existsSync(this.#context.dtsPath)) {
1225
- this.#virtualFS.mkdirSync(this.#context.dtsPath, {
1226
- recursive: true
1227
- });
1228
- }
1229
- } else if (this.#context.config.projectType === "application") {
1230
- if (!this.#physicalFS.existsSync(this.#context.artifactsPath)) {
1231
- this.#physicalFS.mkdirSync(this.#context.artifactsPath, {
1232
- recursive: true
1233
- });
1234
- }
1235
- if (!this.#physicalFS.existsSync(this.#context.builtinsPath)) {
1236
- this.#physicalFS.mkdirSync(this.#context.builtinsPath, {
1237
- recursive: true
1238
- });
1188
+ }
1189
+ /**
1190
+ * Synchronously removes all entries from the storage that match the provided base path.
1191
+ *
1192
+ * @param base - The base path to clear keys from.
1193
+ */
1194
+ clearSync(base) {
1195
+ if (!this.options.isReadOnly) {
1196
+ const keys = this.listSync(base || this.options.base);
1197
+ if (!keys.length) {
1198
+ return;
1239
1199
  }
1240
- if (!this.#physicalFS.existsSync(this.#context.entryPath)) {
1241
- this.#physicalFS.mkdirSync(this.#context.entryPath, {
1242
- recursive: true
1243
- });
1200
+ keys.map((key) => this.removeSync(base && !key.startsWith(base) ? joinPaths(base, key) : key));
1201
+ }
1202
+ }
1203
+ /**
1204
+ * Asynchronously removes all entries from the storage that match the provided base path.
1205
+ *
1206
+ * @param base - The base path to clear keys from.
1207
+ * @returns A promise that resolves when the operation is complete.
1208
+ */
1209
+ async clear(base) {
1210
+ if (!this.options.isReadOnly) {
1211
+ const keys = await this.list(base || this.options.base);
1212
+ if (!keys.length) {
1213
+ return;
1244
1214
  }
1245
- if (!this.#physicalFS.existsSync(this.#context.dtsPath)) {
1246
- this.#physicalFS.mkdirSync(this.#context.dtsPath, {
1247
- recursive: true
1248
- });
1215
+ await Promise.all(keys.map(async (key) => this.remove(base && !key.startsWith(base) ? joinPaths(base, key) : key)));
1216
+ }
1217
+ }
1218
+ /**
1219
+ * Asynchronously lists all keys under a given base path.
1220
+ *
1221
+ * @param base - The base path to list keys from.
1222
+ * @returns A promise that resolves to an array of keys under the specified base path.
1223
+ */
1224
+ async list(base) {
1225
+ return this.listSync(base);
1226
+ }
1227
+ /**
1228
+ * Disposes of the storage adapter, releasing any held resources.
1229
+ *
1230
+ * @returns A promise that resolves when the disposal is complete.
1231
+ */
1232
+ dispose() {
1233
+ return Promise.resolve();
1234
+ }
1235
+ /**
1236
+ * Async dispose method to clean up resources.
1237
+ *
1238
+ * @returns A promise that resolves when disposal is complete.
1239
+ */
1240
+ async [Symbol.asyncDispose]() {
1241
+ return this._dispose();
1242
+ }
1243
+ /**
1244
+ * Resolves a given key to its full path within the storage adapter.
1245
+ *
1246
+ * @param key - The key to resolve.
1247
+ * @returns The resolved full path for the key.
1248
+ */
1249
+ resolve(key = this.options.base) {
1250
+ if (/\.\.:|\.\.$/.test(key)) {
1251
+ throw new Error(`[${this.name}]: Invalid key: ${JSON.stringify(key)} provided to storage adapter.`);
1252
+ }
1253
+ return appendPath(correctPath(key).replace(/:/g, "/"), this.options.base);
1254
+ }
1255
+ /**
1256
+ * Disposes of the storage adapter, releasing any held resources.
1257
+ *
1258
+ * @returns A promise that resolves when the disposal is complete.
1259
+ */
1260
+ async _dispose() {
1261
+ if (!this.#isDisposed) {
1262
+ await Promise.resolve(this.dispose());
1263
+ this.#isDisposed = true;
1264
+ }
1265
+ }
1266
+ };
1267
+
1268
+ // ../powerlines/src/lib/fs/storage/file-system.ts
1269
+ var FileSystemStorageAdapter = class extends BaseStorageAdapter {
1270
+ static {
1271
+ __name(this, "FileSystemStorageAdapter");
1272
+ }
1273
+ /**
1274
+ * A name identifying the storage adapter type.
1275
+ */
1276
+ name = "file-system";
1277
+ /**
1278
+ * Constructor for the FileSystemStorageAdapter.
1279
+ *
1280
+ * @param options - Configuration options for the storage adapter.
1281
+ */
1282
+ constructor(options) {
1283
+ super(options);
1284
+ }
1285
+ /**
1286
+ * Synchronously checks if a key exists in the storage.
1287
+ *
1288
+ * @param key - The key to check for existence.
1289
+ * @returns Returns `true` if the key exists, otherwise `false`.
1290
+ */
1291
+ existsSync(key) {
1292
+ return existsSync(this.resolve(key));
1293
+ }
1294
+ /**
1295
+ * Asynchronously checks if a key exists in the storage.
1296
+ *
1297
+ * @param key - The key to check for existence.
1298
+ * @returns A promise that resolves to `true` if the key exists, otherwise `false`.
1299
+ */
1300
+ async exists(key) {
1301
+ return exists(this.resolve(key));
1302
+ }
1303
+ /**
1304
+ * Synchronously retrieves the value associated with a given key.
1305
+ *
1306
+ * @param key - The key whose value is to be retrieved.
1307
+ * @returns The value associated with the key, or `null` if the key does not exist.
1308
+ */
1309
+ getSync(key) {
1310
+ return readFileSync(this.resolve(key));
1311
+ }
1312
+ /**
1313
+ * Asynchronously retrieves the value associated with a given key.
1314
+ *
1315
+ * @param key - The key whose value is to be retrieved.
1316
+ * @returns A promise that resolves to the value associated with the key, or `null` if the key does not exist.
1317
+ */
1318
+ async get(key) {
1319
+ return readFile(this.resolve(key));
1320
+ }
1321
+ /**
1322
+ * Synchronously sets the value for a given key.
1323
+ *
1324
+ * @param key - The key to set the value for.
1325
+ * @param value - The value to set.
1326
+ */
1327
+ setSync(key, value) {
1328
+ if (!this.options.isReadOnly) {
1329
+ return writeFileSync(this.resolve(key), value);
1330
+ }
1331
+ }
1332
+ /**
1333
+ * Asynchronously sets the value for a given key.
1334
+ *
1335
+ * @param key - The key to set the value for.
1336
+ * @param value - The value to set.
1337
+ */
1338
+ async set(key, value) {
1339
+ if (!this.options.isReadOnly) {
1340
+ return writeFile$1(this.resolve(key), value);
1341
+ }
1342
+ }
1343
+ /**
1344
+ * Synchronously removes a key from the storage.
1345
+ *
1346
+ * @param key - The key to remove.
1347
+ */
1348
+ removeSync(key) {
1349
+ if (!this.options.isReadOnly) {
1350
+ try {
1351
+ return unlinkSync(this.resolve(key));
1352
+ } catch (err) {
1353
+ return ignoreNotfound(err);
1249
1354
  }
1250
1355
  }
1251
1356
  }
1252
1357
  /**
1253
- * Select the file system module to use for the operation based on the path or URL.
1358
+ * Asynchronously removes a key from the storage.
1254
1359
  *
1255
- * @param pathOrUrl - The path to perform the file system operation on.
1256
- * @param options - Options for the operation, such as output mode.
1257
- * @returns The file system module used for the operation.
1360
+ * @param key - The key to remove.
1258
1361
  */
1259
- resolveFS(pathOrUrl, options = {}) {
1260
- const mode = this.resolveMode(pathOrUrl, options);
1261
- if (mode === "virtual") {
1262
- return {
1263
- ...this.#virtualFS,
1264
- mode: "virtual"
1265
- };
1266
- } else if (mode === "fs") {
1267
- return {
1268
- ...this.#physicalFS,
1269
- mode: "fs"
1270
- };
1362
+ async remove(key) {
1363
+ if (!this.options.isReadOnly) {
1364
+ return unlink(this.resolve(key)).catch(ignoreNotfound);
1271
1365
  }
1272
- return {
1273
- ...this,
1274
- mode: this.#context.config.output.mode
1275
- };
1276
1366
  }
1277
1367
  /**
1278
- * Select the file system module to use for the operation based on the path or URL.
1368
+ * Lists all keys under a given base path synchronously.
1279
1369
  *
1280
- * @param pathOrUrl - The path to perform the file system operation on.
1281
- * @param options - Options for the operation, such as output mode.
1282
- * @returns The file system module used for the operation.
1370
+ * @param base - The base path to list keys from.
1371
+ * @returns An array of keys under the specified base path.
1283
1372
  */
1284
- resolveMode(pathOrUrl, options = {}) {
1285
- if (options.mode === "virtual" && this.#context.config.output.mode !== "fs" && isParentPath(toFilePath(pathOrUrl), this.#context.artifactsPath)) {
1286
- return "virtual";
1287
- } 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.distPath))) {
1288
- return "fs";
1373
+ listSync(base) {
1374
+ try {
1375
+ return listFilesSync(this.resolve(base), {
1376
+ ignore: this.options.ignore
1377
+ });
1378
+ } catch (err) {
1379
+ return ignoreNotfound(err) ?? [];
1289
1380
  }
1290
- return void 0;
1291
1381
  }
1292
1382
  /**
1293
- * Serializes the virtual file system (VFS) to a JSON object.
1383
+ * Asynchronously lists all keys under a given base path.
1294
1384
  *
1295
- * @returns A JSON representation of the virtual file system.
1385
+ * @param base - The base path to list keys from.
1386
+ * @returns A promise that resolves to an array of keys under the specified base path.
1296
1387
  */
1297
- toJSON() {
1298
- return this.#virtualFS.toJSON();
1388
+ async list(base) {
1389
+ return listFiles(this.resolve(base), {
1390
+ ignore: this.options.ignore
1391
+ }).catch(ignoreNotfound).then((r) => r || []);
1392
+ }
1393
+ };
1394
+ var VirtualStorageAdapter = class extends BaseStorageAdapter {
1395
+ static {
1396
+ __name(this, "VirtualStorageAdapter");
1397
+ }
1398
+ /**
1399
+ * A name identifying the storage adapter type.
1400
+ */
1401
+ name = "virtual";
1402
+ /**
1403
+ * In-memory data storage.
1404
+ */
1405
+ data = /* @__PURE__ */ new Map();
1406
+ /**
1407
+ * Constructor for the VirtualStorageAdapter.
1408
+ *
1409
+ * @param options - Configuration options for the storage adapter.
1410
+ */
1411
+ constructor(options) {
1412
+ super(options);
1413
+ }
1414
+ /**
1415
+ * Synchronously checks if a key exists in the storage.
1416
+ *
1417
+ * @param key - The key to check for existence.
1418
+ * @returns Returns `true` if the key exists, otherwise `false`.
1419
+ */
1420
+ existsSync(key) {
1421
+ return this.data.has(this.resolve(key));
1422
+ }
1423
+ /**
1424
+ * Synchronously retrieves the value associated with a given key.
1425
+ *
1426
+ * @param key - The key whose value is to be retrieved.
1427
+ * @returns The value associated with the key, or `null` if the key does not exist.
1428
+ */
1429
+ getSync(key) {
1430
+ return this.data.get(this.resolve(key)) ?? null;
1431
+ }
1432
+ /**
1433
+ * Synchronously sets the value for a given key.
1434
+ *
1435
+ * @param key - The key to set the value for.
1436
+ * @param value - The value to set.
1437
+ */
1438
+ setSync(key, value) {
1439
+ if (!this.options.isReadOnly) {
1440
+ this.data.set(this.resolve(key), value);
1441
+ }
1442
+ }
1443
+ /**
1444
+ * Synchronously removes a key from the storage.
1445
+ *
1446
+ * @param key - The key to remove.
1447
+ */
1448
+ removeSync(key) {
1449
+ if (!this.options.isReadOnly) {
1450
+ this.data.delete(this.resolve(key));
1451
+ }
1452
+ }
1453
+ /**
1454
+ * Lists all keys under a given base path synchronously.
1455
+ *
1456
+ * @param base - The base path to list keys from.
1457
+ * @returns An array of keys under the specified base path.
1458
+ */
1459
+ listSync(base) {
1460
+ return [
1461
+ ...this.data.keys().filter((key) => !base ? true : isParentPath(key, this.resolve(base)))
1462
+ ];
1463
+ }
1464
+ /**
1465
+ * Disposes of the storage adapter, releasing any held resources.
1466
+ *
1467
+ * @returns A promise that resolves when the disposal is complete.
1468
+ */
1469
+ async dispose() {
1470
+ return this.clear();
1299
1471
  }
1300
1472
  };
1301
1473
 
@@ -1317,29 +1489,23 @@ var VirtualFileSystem = class _VirtualFileSystem {
1317
1489
  */
1318
1490
  #paths;
1319
1491
  /**
1320
- * A cache for module resolution results.
1321
- */
1322
- #resolverCache;
1323
- /**
1324
1492
  * The unified volume that combines the virtual file system with the real file system.
1325
1493
  *
1326
1494
  * @remarks
1327
1495
  * This volume allows for seamless access to both virtual and real files.
1328
1496
  */
1329
- #unifiedFS;
1497
+ #storage = {
1498
+ "": new FileSystemStorageAdapter()
1499
+ };
1330
1500
  /**
1331
- * Indicator specifying if the file system module is patched
1501
+ * A cache for module resolution results.
1332
1502
  */
1333
- #isPatched = false;
1503
+ #resolverCache;
1334
1504
  /**
1335
1505
  * Indicator specifying if the virtual file system (VFS) is disposed
1336
1506
  */
1337
1507
  #isDisposed = false;
1338
1508
  /**
1339
- * Function to revert require patch
1340
- */
1341
- #revert;
1342
- /**
1343
1509
  * The context of the virtual file system.
1344
1510
  */
1345
1511
  #context;
@@ -1348,15 +1514,6 @@ var VirtualFileSystem = class _VirtualFileSystem {
1348
1514
  */
1349
1515
  #log;
1350
1516
  /**
1351
- * Checks if a path exists in the virtual file system (VFS).
1352
- *
1353
- * @param path - The path to check.
1354
- * @returns `true` if the path exists, otherwise `false`.
1355
- */
1356
- #existsSync(path) {
1357
- return this.#unifiedFS.virtual.existsSync(this.#normalizePath(path)) || this.#unifiedFS.physical.existsSync(this.#normalizePath(path)) || this.#unifiedFS.resolveFS(path).existsSync(this.#normalizePath(path));
1358
- }
1359
- /**
1360
1517
  * Normalizes a given module id by resolving it against the built-ins path.
1361
1518
  *
1362
1519
  * @param id - The module id to normalize.
@@ -1385,6 +1542,43 @@ var VirtualFileSystem = class _VirtualFileSystem {
1385
1542
  return new RegExp(`^${this.#normalizePath(path).replace(/\*\*/g, token).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(token, "g"), ".*")}$`);
1386
1543
  }
1387
1544
  /**
1545
+ * Gets the storage adapter and relative key for a given key.
1546
+ *
1547
+ * @param key - The key to get the storage adapter for.
1548
+ * @returns The storage adapter and relative key for the given key.
1549
+ */
1550
+ #getStorage(key) {
1551
+ const path = this.resolveSync(this.#normalizePath(key)) || key;
1552
+ for (const base of Object.keys(this.#storage).filter(Boolean).sort().reverse()) {
1553
+ if (isParentPath(path, base)) {
1554
+ return {
1555
+ base,
1556
+ relativeKey: replacePath(path, base),
1557
+ adapter: this.#storage[base]
1558
+ };
1559
+ }
1560
+ }
1561
+ return {
1562
+ base: "",
1563
+ relativeKey: path,
1564
+ adapter: this.#storage[""]
1565
+ };
1566
+ }
1567
+ /**
1568
+ * Gets all storage adapters that match a given base key.
1569
+ *
1570
+ * @param base - The base key to match storage adapters against.
1571
+ * @param includeParent - Whether to include parent storage adapters.
1572
+ * @returns An array of storage adapters that match the given base key.
1573
+ */
1574
+ #getStorages(base = "", includeParent = false) {
1575
+ return Object.keys(this.#storage).sort().reverse().filter((key) => isParentPath(key, base) || includeParent && isParentPath(base, key)).map((key) => ({
1576
+ relativeBase: base.length > key.length ? base.slice(key.length) : void 0,
1577
+ base: key,
1578
+ adapter: this.#storage[key]
1579
+ }));
1580
+ }
1581
+ /**
1388
1582
  * Creates a virtual file system (VFS) that is backed up to a Cap'n Proto message buffer.
1389
1583
  *
1390
1584
  * @param context - The context of the virtual file system, typically containing options and logging functions.
@@ -1394,7 +1588,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1394
1588
  if (!context.config.skipCache && existsSync(joinPaths$1(context.dataPath, "fs.bin"))) {
1395
1589
  const buffer = await readFileBuffer(joinPaths$1(context.dataPath, "fs.bin"));
1396
1590
  const message2 = new $.Message(buffer, false);
1397
- return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1591
+ const fs = message2.getRoot(FileSystem);
1592
+ const result = new _VirtualFileSystem(context, fs);
1593
+ if (fs._hasStorage() && fs.storage.length > 0) {
1594
+ await Promise.all(fs.storage.values().map(async (file) => {
1595
+ await result.write(file.path, file.code);
1596
+ }));
1597
+ }
1398
1598
  }
1399
1599
  const message = new $.Message();
1400
1600
  return new _VirtualFileSystem(context, message.initRoot(FileSystem));
@@ -1409,7 +1609,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1409
1609
  if (!context.config.skipCache && existsSync(joinPaths$1(context.dataPath, "fs.bin"))) {
1410
1610
  const buffer = readFileBufferSync(joinPaths$1(context.dataPath, "fs.bin"));
1411
1611
  const message2 = new $.Message(buffer, false);
1412
- return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1612
+ const fs = message2.getRoot(FileSystem);
1613
+ const result = new _VirtualFileSystem(context, fs);
1614
+ if (fs._hasStorage() && fs.storage.length > 0) {
1615
+ fs.storage.values().map((file) => {
1616
+ result.writeSync(file.path, file.code);
1617
+ });
1618
+ }
1413
1619
  }
1414
1620
  const message = new $.Message();
1415
1621
  return new _VirtualFileSystem(context, message.initRoot(FileSystem));
@@ -1444,6 +1650,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
1444
1650
  }, "get")
1445
1651
  });
1446
1652
  }
1653
+ /**
1654
+ * Gets the resolver cache.
1655
+ */
1447
1656
  get resolverCache() {
1448
1657
  if (!this.#resolverCache) {
1449
1658
  this.#resolverCache = create({
@@ -1462,16 +1671,34 @@ var VirtualFileSystem = class _VirtualFileSystem {
1462
1671
  * @param context - The context of the virtual file system, typically containing options and logging functions.
1463
1672
  * @param fs - A buffer containing the serialized virtual file system data.
1464
1673
  */
1465
- constructor(context, fs2) {
1674
+ constructor(context, fs) {
1466
1675
  this.#context = context;
1467
- this.#unifiedFS = UnifiedFS.create(context, fs2);
1676
+ if (isSetObject(this.#context.config.output.storage)) {
1677
+ this.#storage = {
1678
+ ...this.#storage,
1679
+ ...this.#context.config.output.storage
1680
+ };
1681
+ }
1682
+ this.#storage.virtual ??= new VirtualStorageAdapter({
1683
+ base: "/_virtual"
1684
+ });
1685
+ if (this.#context.config.output.storage !== StoragePreset.FS) {
1686
+ this.#storage[this.#context.artifactsPath] ??= new VirtualStorageAdapter({
1687
+ base: this.#context.artifactsPath
1688
+ });
1689
+ this.#storage[this.#context.builtinsPath] ??= new VirtualStorageAdapter({
1690
+ base: this.#context.builtinsPath
1691
+ });
1692
+ this.#storage[this.#context.entryPath] ??= new VirtualStorageAdapter({
1693
+ base: this.#context.entryPath
1694
+ });
1695
+ }
1468
1696
  this.#metadata = {};
1469
- if (fs2._hasMetadata()) {
1470
- this.#metadata = fs2.metadata.values().reduce((ret, metadata) => {
1697
+ if (fs._hasMetadata()) {
1698
+ this.#metadata = fs.metadata.values().reduce((ret, metadata) => {
1471
1699
  ret[metadata.id] = {
1472
1700
  id: metadata.id,
1473
1701
  type: metadata.type,
1474
- mode: metadata.mode,
1475
1702
  timestamp: metadata.timestamp || Date.now(),
1476
1703
  properties: metadata._hasProperties() ? metadata.properties.values().reduce((ret2, item) => {
1477
1704
  ret2[item.key] = item.value;
@@ -1483,12 +1710,12 @@ var VirtualFileSystem = class _VirtualFileSystem {
1483
1710
  }
1484
1711
  this.#ids = {};
1485
1712
  this.#paths = {};
1486
- if (fs2._hasIds()) {
1487
- this.#ids = fs2.ids.values().reduce((ret, identifier) => {
1713
+ if (fs._hasIds()) {
1714
+ this.#ids = fs.ids.values().reduce((ret, identifier) => {
1488
1715
  ret[identifier.path] ??= identifier.id;
1489
1716
  return ret;
1490
1717
  }, {});
1491
- this.#paths = fs2.ids.values().reduce((ret, identifier) => {
1718
+ this.#paths = fs.ids.values().reduce((ret, identifier) => {
1492
1719
  ret[identifier.id] ??= identifier.path;
1493
1720
  return ret;
1494
1721
  }, {});
@@ -1496,187 +1723,123 @@ var VirtualFileSystem = class _VirtualFileSystem {
1496
1723
  this.#log = extendLog(this.#context.log, "file-system");
1497
1724
  }
1498
1725
  /**
1499
- * Check if a path or id corresponds to a virtual file **(does not actually exists on disk)**.
1500
- *
1501
- * @param pathOrId - The path or id to check.
1502
- * @returns Whether the path or id corresponds to a virtual file **(does not actually exists on disk)**.
1503
- */
1504
- isVirtual(pathOrId, importer, options = {}) {
1505
- if (!pathOrId) {
1506
- return false;
1507
- }
1508
- const resolvedPath = this.resolveSync(pathOrId, importer, options);
1509
- if (!resolvedPath) {
1510
- return false;
1511
- }
1512
- return this.metadata[resolvedPath]?.mode === "virtual";
1513
- }
1514
- /**
1515
- * Check if a path or id corresponds to a file written to the file system **(actually exists on disk)**.
1516
- *
1517
- * @param pathOrId - The path or id to check.
1518
- * @returns Whether the path or id corresponds to a file written to the file system **(actually exists on disk)**.
1519
- */
1520
- isPhysical(pathOrId, importer, options = {}) {
1521
- if (!pathOrId) {
1522
- return false;
1523
- }
1524
- const resolvedPath = this.resolveSync(pathOrId, importer, options);
1525
- if (!resolvedPath) {
1526
- return false;
1527
- }
1528
- return this.metadata[resolvedPath]?.mode === "fs";
1529
- }
1530
- /**
1531
- * Lists files in a given path.
1532
- *
1533
- * @param path - 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
- readdirSync(path, options = "utf8") {
1538
- return this.#unifiedFS.resolveFS(path).readdirSync(toFilePath(path), options);
1539
- }
1540
- /**
1541
- * Removes a file in the virtual file system (VFS).
1726
+ * Asynchronously checks if a file exists in the virtual file system (VFS).
1542
1727
  *
1543
- * @param path - The path to create the directory at.
1544
- */
1545
- unlinkSync(path, options) {
1546
- if (!this.isFile(this.#normalizePath(path))) {
1547
- return;
1548
- }
1549
- this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${this.#normalizePath(path)}`);
1550
- this.#unifiedFS.resolveFS(path, options).unlinkSync(this.#normalizePath(path));
1551
- if (this.#ids[this.#normalizePath(path)] && this.#metadata[this.#ids[this.#normalizePath(path)]]) {
1552
- delete this.#metadata[this.#ids[this.#normalizePath(path)]];
1553
- delete this.#ids[this.#normalizePath(path)];
1554
- delete this.#paths[this.#normalizeId(path)];
1555
- this.#resolverCache.delete(this.#normalizePath(path));
1556
- }
1557
- }
1558
- /**
1559
- * Removes a file in the virtual file system (VFS).
1560
- *
1561
- * @param path - The path to create the directory at.
1728
+ * @param path - The path to the file.
1729
+ * @returns A promise that resolves to `true` if the file exists, otherwise `false`.
1562
1730
  */
1563
- async unlink(path, options) {
1564
- if (!this.isFile(this.#normalizePath(path))) {
1565
- return;
1566
- }
1567
- this.#log(LogLevelLabel.TRACE, `Removing file: ${this.#normalizePath(path)}`);
1568
- if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.unlink)) {
1569
- await this.#unifiedFS.resolveFS(path, options).promises.unlink(this.#normalizePath(path));
1570
- if (this.#ids[this.#normalizePath(path)] && this.#metadata[this.#ids[this.#normalizePath(path)]]) {
1571
- delete this.#metadata[this.#ids[this.#normalizePath(path)]];
1572
- }
1573
- } else {
1574
- this.unlinkSync(this.#normalizePath(path), options);
1575
- }
1731
+ async exists(path) {
1732
+ const { relativeKey, adapter } = this.#getStorage(path);
1733
+ return adapter.exists(relativeKey);
1576
1734
  }
1577
1735
  /**
1578
- * Removes a directory in the virtual file system (VFS).
1736
+ * Synchronously checks if a file exists in the virtual file system (VFS).
1579
1737
  *
1580
- * @param path - The path to create the directory at.
1581
- * @param options - Options for creating the directory.
1738
+ * @param path - The path to the file.
1739
+ * @returns `true` if the file exists, otherwise `false`.
1582
1740
  */
1583
- rmdirSync(path, options = {}) {
1584
- if (!this.isDirectory(this.#normalizePath(path))) {
1585
- return;
1586
- }
1587
- this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${this.#normalizePath(path)}`);
1588
- this.#unifiedFS.resolveFS(path, options).rmdirSync(this.#normalizePath(path), defu5(options, {
1589
- recursive: true
1590
- }));
1741
+ existsSync(path) {
1742
+ const { relativeKey, adapter } = this.#getStorage(path);
1743
+ return adapter.existsSync(relativeKey);
1591
1744
  }
1592
1745
  /**
1593
- * Removes a directory in the virtual file system (VFS).
1746
+ * Checks if a file is virtual in the virtual file system (VFS).
1594
1747
  *
1595
- * @param path - The path to create the directory at.
1596
- * @param options - Options for creating the directory.
1597
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1748
+ * @param path - The path to the file.
1749
+ * @returns `true` if the file is virtual, otherwise `false`.
1598
1750
  */
1599
- async rmdir(path, options = {}) {
1600
- if (!this.isDirectory(this.#normalizePath(path))) {
1601
- return;
1602
- }
1603
- this.#log(LogLevelLabel.TRACE, `Removing directory: ${this.#normalizePath(path)}`);
1604
- if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.rm)) {
1605
- await this.#unifiedFS.resolveFS(path, options).promises.rm(this.#normalizePath(path), defu5(options, {
1606
- force: true,
1607
- recursive: true
1608
- }));
1609
- } else {
1610
- this.rmdirSync(this.#normalizePath(path), defu5(options ?? {}, {
1611
- force: true,
1612
- recursive: true
1613
- }));
1751
+ isVirtual(path) {
1752
+ const resolved = this.resolveSync(path);
1753
+ if (!resolved) {
1754
+ return false;
1614
1755
  }
1756
+ return this.#getStorage(resolved)?.adapter?.name === "virtual";
1615
1757
  }
1616
1758
  /**
1617
- * Removes a file in the virtual file system (VFS).
1759
+ * Lists files in a given path.
1618
1760
  *
1619
- * @param path - The path to the file to remove.
1620
- * @param options - Options for removing the file.
1621
- * @returns A promise that resolves when the file is removed.
1761
+ * @param path - The path to list files from.
1762
+ * @returns An array of file names in the specified path.
1622
1763
  */
1623
- async rm(path, options = {}) {
1624
- this.#log(LogLevelLabel.TRACE, `Removing: ${this.#normalizePath(path)}`);
1625
- if (this.isDirectory(this.#normalizePath(path))) {
1626
- return this.rmdir(this.#normalizePath(path), options);
1764
+ listSync(path) {
1765
+ let maskedMounts = [];
1766
+ const allKeys = [];
1767
+ for (const storage of this.#getStorages(path, true)) {
1768
+ for (const key of storage.adapter.listSync(storage.relativeBase)) {
1769
+ if (!maskedMounts.some((p) => `${storage.base}${normalizeKey(key)}`.startsWith(p))) {
1770
+ allKeys.push(`${storage.base}${normalizeKey(key)}`);
1771
+ }
1772
+ }
1773
+ maskedMounts = [
1774
+ storage.base,
1775
+ ...maskedMounts.filter((p) => !p.startsWith(storage.base))
1776
+ ];
1627
1777
  }
1628
- return this.unlink(this.#normalizePath(path), options);
1778
+ return allKeys.filter((key) => filterKeyByBase(key, path));
1629
1779
  }
1630
1780
  /**
1631
- * Synchronously removes a file or directory in the virtual file system (VFS).
1781
+ * Lists files in a given path.
1632
1782
  *
1633
- * @param path - The path to the file or directory to remove.
1634
- * @param options - Options for removing the file or directory.
1783
+ * @param path - The path to list files from.
1784
+ * @returns An array of file names in the specified path.
1635
1785
  */
1636
- rmSync(path, options = {}) {
1637
- this.#log(LogLevelLabel.TRACE, `Removing: ${this.#normalizePath(path)}`);
1638
- if (this.isDirectory(this.#normalizePath(path))) {
1639
- return this.rmdirSync(this.#normalizePath(path), options);
1786
+ async list(path) {
1787
+ let maskedMounts = [];
1788
+ const allKeys = [];
1789
+ for (const storage of this.#getStorages(path, true)) {
1790
+ for (const key of await storage.adapter.list(storage.relativeBase)) {
1791
+ if (!maskedMounts.some((p) => `${storage.base}${normalizeKey(key)}`.startsWith(p))) {
1792
+ allKeys.push(`${storage.base}${normalizeKey(key)}`);
1793
+ }
1794
+ }
1795
+ maskedMounts = [
1796
+ storage.base,
1797
+ ...maskedMounts.filter((p) => !p.startsWith(storage.base))
1798
+ ];
1640
1799
  }
1641
- return this.unlinkSync(this.#normalizePath(path), options);
1800
+ return allKeys.filter((key) => filterKeyByBase(key, path));
1642
1801
  }
1643
1802
  /**
1644
- * Creates a directory in the virtual file system (VFS).
1803
+ * Removes a file in the virtual file system (VFS).
1645
1804
  *
1646
1805
  * @param path - The path to create the directory at.
1647
- * @param options - Options for creating the directory.
1648
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1649
- */
1650
- mkdirSync(path, options = {}) {
1651
- return this.#unifiedFS.resolveFS(this.#normalizePath(path), options).mkdirSync(this.#normalizePath(path), defu5(omit(options, [
1652
- "mode"
1653
- ]), {
1654
- recursive: true
1655
- }));
1806
+ */
1807
+ async remove(path) {
1808
+ const normalizedPath = this.#normalizePath(path);
1809
+ this.#log(LogLevelLabel.TRACE, `Removing file: ${normalizedPath}`);
1810
+ const { relativeKey, adapter } = this.#getStorage(normalizedPath);
1811
+ if (hasFileExtension(normalizedPath)) {
1812
+ await adapter.remove(relativeKey);
1813
+ } else {
1814
+ await adapter.clear(relativeKey);
1815
+ }
1816
+ const id = this.#ids[normalizedPath];
1817
+ if (id && this.#metadata[id]) {
1818
+ delete this.#metadata[id];
1819
+ delete this.#ids[normalizedPath];
1820
+ delete this.#paths[id];
1821
+ }
1656
1822
  }
1657
1823
  /**
1658
- * Creates a directory in the virtual file system (VFS).
1824
+ * Removes a file in the virtual file system (VFS).
1659
1825
  *
1660
1826
  * @param path - The path to create the directory at.
1661
- * @param options - Options for creating the directory.
1662
- * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
1663
1827
  */
1664
- async mkdir(path, options = {}) {
1665
- let result;
1666
- if (isFunction(this.#unifiedFS.resolveFS(this.#normalizePath(path), options).promises.mkdir)) {
1667
- result = await this.#unifiedFS.resolveFS(this.#normalizePath(path), options).promises.mkdir(this.#normalizePath(path), defu5(omit(options, [
1668
- "mode"
1669
- ]), {
1670
- recursive: true
1671
- }));
1828
+ removeSync(path) {
1829
+ const normalizedPath = this.#normalizePath(path);
1830
+ this.#log(LogLevelLabel.TRACE, `Removing file: ${normalizedPath}`);
1831
+ const { relativeKey, adapter } = this.#getStorage(normalizedPath);
1832
+ if (hasFileExtension(normalizedPath)) {
1833
+ adapter.removeSync(relativeKey);
1672
1834
  } else {
1673
- result = this.#unifiedFS.resolveFS(this.#normalizePath(path), options).mkdirSync(this.#normalizePath(path), defu5(omit(options, [
1674
- "mode"
1675
- ]), {
1676
- recursive: true
1677
- }));
1835
+ adapter.clearSync(relativeKey);
1836
+ }
1837
+ const id = this.#ids[normalizedPath];
1838
+ if (id && this.#metadata[id]) {
1839
+ delete this.#metadata[id];
1840
+ delete this.#ids[normalizedPath];
1841
+ delete this.#paths[id];
1678
1842
  }
1679
- return result;
1680
1843
  }
1681
1844
  /**
1682
1845
  * Glob files in the virtual file system (VFS) based on the provided pattern(s).
@@ -1698,38 +1861,14 @@ var VirtualFileSystem = class _VirtualFileSystem {
1698
1861
  const absPattern = isAbsolutePath(normalized) ? normalized : this.#normalizePath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1699
1862
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
1700
1863
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
1701
- const stack = [
1702
- baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
1703
- ];
1704
- while (stack.length) {
1705
- const dir = stack.pop();
1706
- let entries = [];
1707
- try {
1708
- entries = await this.readdir(dir);
1709
- } catch {
1710
- continue;
1711
- }
1712
- for (const entry of entries) {
1713
- const full = this.#normalizePath(joinPaths$1(dir, entry));
1714
- let stats;
1715
- try {
1716
- stats = this.#unifiedFS.lstatSync(full);
1717
- } catch {
1718
- stats = void 0;
1719
- }
1720
- if (!stats) continue;
1721
- if (stats.isDirectory()) {
1722
- stack.push(full);
1723
- } else if (stats.isFile()) {
1724
- if (this.#buildRegex(absPattern).test(full)) {
1725
- const resolved = this.resolveSync(full);
1726
- if (resolved && !results.includes(resolved)) {
1727
- results.push(resolved);
1728
- }
1729
- }
1864
+ await Promise.all((await this.list(baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot)).map(async (file) => {
1865
+ if (this.#buildRegex(absPattern).test(file)) {
1866
+ const resolved = this.resolveSync(file);
1867
+ if (resolved && !results.includes(resolved)) {
1868
+ results.push(resolved);
1730
1869
  }
1731
1870
  }
1732
- }
1871
+ }));
1733
1872
  }
1734
1873
  return results;
1735
1874
  }
@@ -1753,35 +1892,12 @@ var VirtualFileSystem = class _VirtualFileSystem {
1753
1892
  const absPattern = isAbsolutePath(normalized) ? normalized : this.#normalizePath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1754
1893
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
1755
1894
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
1756
- const stack = [
1757
- baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot
1758
- ];
1759
- while (stack.length) {
1760
- const dir = stack.pop();
1761
- let entries = [];
1762
- try {
1763
- entries = this.readdirSync(dir);
1764
- } catch {
1765
- continue;
1766
- }
1767
- for (const entry of entries) {
1768
- const full = this.#normalizePath(joinPaths$1(dir, entry));
1769
- let stats;
1770
- try {
1771
- stats = this.#unifiedFS.lstatSync(full);
1772
- } catch {
1773
- stats = void 0;
1774
- }
1775
- if (!stats) continue;
1776
- if (stats.isDirectory()) {
1777
- stack.push(full);
1778
- } else if (stats.isFile()) {
1779
- if (this.#buildRegex(absPattern).test(full)) {
1780
- const resolved = this.resolveSync(full);
1781
- if (resolved && !results.includes(resolved)) {
1782
- results.push(resolved);
1783
- }
1784
- }
1895
+ const files = this.listSync(baseDir && isAbsolutePath(baseDir) ? baseDir : this.#context.workspaceConfig.workspaceRoot);
1896
+ for (const file of files) {
1897
+ if (this.#buildRegex(absPattern).test(file)) {
1898
+ const resolved = this.resolveSync(file);
1899
+ if (resolved && !results.includes(resolved)) {
1900
+ results.push(resolved);
1785
1901
  }
1786
1902
  }
1787
1903
  }
@@ -1789,36 +1905,27 @@ var VirtualFileSystem = class _VirtualFileSystem {
1789
1905
  return results;
1790
1906
  }
1791
1907
  /**
1792
- * Moves a file from one path to another in the virtual file system (VFS).
1793
- *
1794
- * @param srcPath - The source path to move
1795
- * @param destPath - The destination path to move to
1796
- */
1797
- async move(srcPath, destPath) {
1798
- const content = await this.readFile(srcPath);
1799
- await this.writeFile(destPath, content);
1800
- await this.rm(srcPath);
1801
- }
1802
- /**
1803
- * Synchronously moves a file from one path to another in the virtual file system (VFS).
1804
- *
1805
- * @param srcPath - The source path to move
1806
- * @param destPath - The destination path to move to
1807
- */
1808
- moveSync(srcPath, destPath) {
1809
- const content = this.readFileSync(srcPath);
1810
- this.writeFileSync(destPath, content);
1811
- this.rmSync(srcPath);
1812
- }
1813
- /**
1814
1908
  * Copies a file from one path to another in the virtual file system (VFS).
1815
1909
  *
1816
1910
  * @param srcPath - The source path to copy
1817
1911
  * @param destPath - The destination path to copy to
1818
1912
  */
1819
1913
  async copy(srcPath, destPath) {
1820
- const content = await this.readFile(srcPath);
1821
- await this.writeFile(destPath, content);
1914
+ if (hasFileExtension(srcPath)) {
1915
+ const content = await this.read(srcPath);
1916
+ if (content !== void 0) {
1917
+ await this.write(hasFileExtension(destPath) ? destPath : joinPaths$1(destPath, findFileName(srcPath)), content);
1918
+ }
1919
+ } else {
1920
+ await Promise.all((await this.list(srcPath)).map(async (file) => {
1921
+ const relativePath2 = file.replace(this.#normalizePath(srcPath), "");
1922
+ const destinationPath = this.#normalizePath(appendPath(destPath, relativePath2));
1923
+ const content = await this.read(file);
1924
+ if (content !== void 0) {
1925
+ await this.write(destinationPath, content);
1926
+ }
1927
+ }));
1928
+ }
1822
1929
  }
1823
1930
  /**
1824
1931
  * Synchronously copies a file from one path to another in the virtual file system (VFS).
@@ -1827,51 +1934,85 @@ var VirtualFileSystem = class _VirtualFileSystem {
1827
1934
  * @param destPath - The destination path to copy to
1828
1935
  */
1829
1936
  copySync(srcPath, destPath) {
1830
- const content = this.readFileSync(srcPath);
1831
- this.writeFileSync(destPath, content);
1937
+ if (hasFileExtension(srcPath)) {
1938
+ const content = this.readSync(srcPath);
1939
+ if (content !== void 0) {
1940
+ this.writeSync(hasFileExtension(destPath) ? destPath : joinPaths$1(destPath, findFileName(srcPath)), content);
1941
+ }
1942
+ } else {
1943
+ this.listSync(srcPath).forEach((file) => {
1944
+ const relativePath2 = file.replace(this.#normalizePath(srcPath), "");
1945
+ const destinationPath = this.#normalizePath(appendPath(destPath, relativePath2));
1946
+ const content = this.readSync(file);
1947
+ if (content !== void 0) {
1948
+ this.writeSync(destinationPath, content);
1949
+ }
1950
+ });
1951
+ }
1832
1952
  }
1833
1953
  /**
1834
- * Lists files in a given path.
1954
+ * Moves a file (or files) from one path to another in the virtual file system (VFS).
1835
1955
  *
1836
- * @param pathOrId - The path to list files from.
1837
- * @param options - Options for listing files, such as encoding and recursion.
1838
- * @returns An array of file names in the specified path.
1956
+ * @param srcPath - The source path to move
1957
+ * @param destPath - The destination path to move to
1958
+ */
1959
+ async move(srcPath, destPath) {
1960
+ if (hasFileExtension(srcPath)) {
1961
+ await this.copy(srcPath, destPath);
1962
+ await this.remove(srcPath);
1963
+ } else {
1964
+ await Promise.all((await this.list(srcPath)).map(async (file) => {
1965
+ await this.copy(file, destPath);
1966
+ await this.remove(file);
1967
+ }));
1968
+ }
1969
+ }
1970
+ /**
1971
+ * Synchronously moves a file (or files) from one path to another in the virtual file system (VFS).
1972
+ *
1973
+ * @param srcPath - The source path to move
1974
+ * @param destPath - The destination path to move to
1839
1975
  */
1840
- async readdir(pathOrId, options = "utf8") {
1841
- return this.#unifiedFS.resolveFS(pathOrId).promises.readdir(toFilePath(pathOrId), options);
1976
+ moveSync(srcPath, destPath) {
1977
+ if (hasFileExtension(srcPath)) {
1978
+ this.copySync(srcPath, destPath);
1979
+ this.removeSync(srcPath);
1980
+ } else {
1981
+ this.listSync(srcPath).forEach((file) => {
1982
+ this.copySync(file, destPath);
1983
+ this.removeSync(file);
1984
+ });
1985
+ }
1842
1986
  }
1843
1987
  /**
1844
1988
  * Asynchronously reads a file from the virtual file system (VFS).
1845
1989
  *
1846
- * @param pathOrId - The path or ID of the file to read.
1990
+ * @param path - The path or ID of the file to read.
1847
1991
  * @returns A promise that resolves to the contents of the file as a string, or undefined if the file does not exist.
1848
1992
  */
1849
- async readFile(pathOrId, options = "utf8") {
1850
- const filePath = await this.resolve(pathOrId);
1851
- if (filePath && this.isFile(filePath)) {
1852
- let result;
1853
- if (isFunction(this.#unifiedFS.resolveFS(filePath).promises.readFile)) {
1854
- result = (await this.#unifiedFS.resolveFS(filePath).promises.readFile(filePath, options))?.toString("utf8");
1855
- } else {
1856
- result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
1857
- }
1858
- return isBuffer(result) ? bufferToString(result) : result;
1993
+ async read(path) {
1994
+ const filePath = await this.resolve(path);
1995
+ if (!filePath) {
1996
+ return void 0;
1859
1997
  }
1860
- return void 0;
1998
+ const { relativeKey, adapter } = this.#getStorage(filePath);
1999
+ this.#log(LogLevelLabel.TRACE, `Reading ${adapter.name} file: ${filePath}`);
2000
+ return await adapter.get(relativeKey) ?? void 0;
1861
2001
  }
1862
2002
  /**
1863
2003
  * Synchronously reads a file from the virtual file system (VFS).
1864
2004
  *
1865
- * @param pathOrId - The path or ID of the file to read.
2005
+ * @param path - The path or ID of the file to read.
1866
2006
  * @returns The contents of the file as a string, or undefined if the file does not exist.
1867
2007
  */
1868
- readFileSync(pathOrId, options = "utf8") {
1869
- const filePath = this.resolveSync(pathOrId);
1870
- if (filePath && this.isFile(filePath)) {
1871
- const result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
1872
- return isBuffer(result) ? bufferToString(result) : result;
2008
+ readSync(path) {
2009
+ const filePath = this.resolveSync(path);
2010
+ if (!filePath) {
2011
+ return void 0;
1873
2012
  }
1874
- return void 0;
2013
+ const { relativeKey, adapter } = this.#getStorage(filePath);
2014
+ this.#log(LogLevelLabel.TRACE, `Reading ${adapter.name} file: ${filePath}`);
2015
+ return adapter.getSync(relativeKey) ?? void 0;
1875
2016
  }
1876
2017
  /**
1877
2018
  * Writes a file to the virtual file system (VFS).
@@ -1881,41 +2022,28 @@ var VirtualFileSystem = class _VirtualFileSystem {
1881
2022
  * @param options - Optional parameters for writing the file.
1882
2023
  * @returns A promise that resolves when the file is written.
1883
2024
  */
1884
- async writeFile(path, data = "", options = "utf8") {
1885
- if (!this.isDirectory(findFilePath(this.#normalizePath(path)))) {
1886
- await this.mkdir(findFilePath(this.#normalizePath(path)), isPowerlinesWriteFileOptions(options) ? options : void 0);
1887
- }
1888
- const metadata = isVirtualFileData(data) ? data : {};
1889
- metadata.id = this.#normalizeId(path);
1890
- let code = isVirtualFileData(data) ? metadata.code : data;
1891
- if ((!isPowerlinesWriteFileOptions(options) || !options.skipFormat) && isSetString(code)) {
2025
+ async write(path, data = "", options = {}) {
2026
+ let code = data;
2027
+ if (!options.skipFormat) {
1892
2028
  const resolvedConfig = await resolveConfig(this.#normalizePath(path));
1893
2029
  if (resolvedConfig) {
1894
- code = await format(code, {
2030
+ code = await format(data, {
1895
2031
  absolutePath: this.#normalizePath(path),
1896
2032
  ...resolvedConfig
1897
2033
  });
1898
2034
  }
1899
2035
  }
1900
- const outputMode = this.#unifiedFS.resolveMode(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
1901
- this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1902
- this.#metadata[metadata.id] = {
1903
- mode: outputMode,
2036
+ const { relativeKey, adapter } = this.#getStorage(path);
2037
+ this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} to ${adapter.name === "virtual" ? "the virtual file system" : adapter.name === "file-system" ? "the local file system" : adapter.name} (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
2038
+ const id = options?.meta?.id || this.#normalizeId(path);
2039
+ this.#metadata[id] = {
1904
2040
  variant: "normal",
1905
2041
  timestamp: Date.now(),
1906
- ...metadata
2042
+ ...options.meta ?? {}
1907
2043
  };
1908
- this.#paths[metadata.id] = this.#normalizePath(path);
1909
- this.#ids[this.#normalizePath(path)] = metadata.id;
1910
- const ifs = this.#unifiedFS.resolveFS(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
1911
- if (isFunction(ifs.promises.writeFile)) {
1912
- return ifs.promises.writeFile(this.#normalizePath(path), code, isSetObject(options) ? omit(options, [
1913
- "mode"
1914
- ]) : "utf8");
1915
- }
1916
- return ifs.writeFileSync(this.#normalizePath(path), code, isSetObject(options) ? omit(options, [
1917
- "mode"
1918
- ]) : "utf8");
2044
+ this.#paths[id] = this.#normalizePath(path);
2045
+ this.#ids[this.#normalizePath(path)] = id;
2046
+ return adapter.set(relativeKey, code);
1919
2047
  }
1920
2048
  /**
1921
2049
  * Synchronously writes a file to the virtual file system (VFS).
@@ -1924,38 +2052,18 @@ var VirtualFileSystem = class _VirtualFileSystem {
1924
2052
  * @param data - The contents of the file.
1925
2053
  * @param options - Optional parameters for writing the file.
1926
2054
  */
1927
- writeFileSync(path, data = "", options = "utf8") {
1928
- if (!this.isDirectory(findFilePath(this.#normalizePath(path)))) {
1929
- this.mkdirSync(findFilePath(this.#normalizePath(path)), isPowerlinesWriteFileOptions(options) ? options : void 0);
1930
- }
1931
- const metadata = isVirtualFileData(data) ? data : {};
1932
- metadata.id = this.#normalizeId(path);
1933
- const code = isVirtualFileData(data) ? metadata.code : data;
1934
- const outputMode = this.#unifiedFS.resolveMode(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
1935
- this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1936
- this.#metadata[metadata.id] = {
1937
- mode: outputMode,
2055
+ writeSync(path, data = "", options = {}) {
2056
+ const { relativeKey, adapter } = this.#getStorage(path);
2057
+ this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} file to ${adapter.name === "virtual" ? "the virtual file system" : adapter.name === "file-system" ? "the local file system" : adapter.name} (size: ${prettyBytes(new Blob(toArray(data)).size)})`);
2058
+ const id = options?.meta?.id || this.#normalizeId(path);
2059
+ this.#metadata[id] = {
1938
2060
  variant: "normal",
1939
2061
  timestamp: Date.now(),
1940
- ...metadata
2062
+ ...options.meta ?? {}
1941
2063
  };
1942
- this.#paths[metadata.id] = this.#normalizePath(path);
1943
- this.#ids[this.#normalizePath(path)] = metadata.id;
1944
- const writeStream = this.#unifiedFS.resolveFS(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0).createWriteStream(this.#normalizePath(path));
1945
- try {
1946
- writeStream.write(code);
1947
- } finally {
1948
- writeStream.close();
1949
- }
1950
- }
1951
- /**
1952
- * Synchronously checks if a file exists in the virtual file system (VFS).
1953
- *
1954
- * @param pathOrId - The path or ID of the file to check.
1955
- * @returns `true` if the file exists, otherwise `false`.
1956
- */
1957
- existsSync(pathOrId) {
1958
- return !!this.resolveSync(pathOrId);
2064
+ this.#paths[id] = this.#normalizePath(path);
2065
+ this.#ids[this.#normalizePath(path)] = id;
2066
+ return adapter.setSync(relativeKey, data);
1959
2067
  }
1960
2068
  /**
1961
2069
  * Retrieves the metadata of a file in the virtual file system (VFS).
@@ -1971,78 +2079,6 @@ var VirtualFileSystem = class _VirtualFileSystem {
1971
2079
  return void 0;
1972
2080
  }
1973
2081
  /**
1974
- * Checks if a file exists in the virtual file system (VFS).
1975
- *
1976
- * @remarks
1977
- * 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.
1978
- *
1979
- * @param pathOrId - The path of the file to check.
1980
- * @returns `true` if the file exists, otherwise `false`.
1981
- */
1982
- isFile(pathOrId) {
1983
- const resolved = this.resolveSync(pathOrId);
1984
- 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()));
1985
- }
1986
- /**
1987
- * Checks if a directory exists in the virtual file system (VFS).
1988
- *
1989
- * @param pathOrId - The path of the directory to check.
1990
- * @returns `true` if the directory exists, otherwise `false`.
1991
- */
1992
- isDirectory(pathOrId) {
1993
- const resolved = this.resolveSync(pathOrId);
1994
- 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()));
1995
- }
1996
- /**
1997
- * Retrieves the status of a file in the virtual file system (VFS).
1998
- *
1999
- * @param pathOrId - The path or ID of the file to retrieve status for.
2000
- * @returns A promise that resolves to the file's status information, or false if the file does not exist.
2001
- */
2002
- async stat(pathOrId, options) {
2003
- return this.#unifiedFS.resolveFS(pathOrId).promises.stat(await this.resolve(pathOrId) || pathOrId, options);
2004
- }
2005
- /**
2006
- * Synchronously retrieves the status of a file in the virtual file system (VFS).
2007
- *
2008
- * @param pathOrId - The path or ID of the file to retrieve status for.
2009
- * @returns The file's status information, or false if the file does not exist.
2010
- */
2011
- statSync(pathOrId) {
2012
- return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolveSync(pathOrId) || pathOrId);
2013
- }
2014
- /**
2015
- * Retrieves the status of a symbolic link in the virtual file system (VFS).
2016
- *
2017
- * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
2018
- * @returns A promise that resolves to the symbolic link's status information, or false if the link does not exist.
2019
- */
2020
- async lstat(pathOrId, options) {
2021
- return this.#unifiedFS.resolveFS(pathOrId).promises.lstat(await this.resolve(pathOrId) || pathOrId, options);
2022
- }
2023
- /**
2024
- * Synchronously retrieves the status of a symbolic link in the virtual file system (VFS).
2025
- *
2026
- * @param pathOrId - The path or ID of the symbolic link to retrieve status for.
2027
- * @returns The symbolic link's status information, or false if the link does not exist.
2028
- */
2029
- lstatSync(pathOrId, options) {
2030
- return this.#unifiedFS.resolveFS(pathOrId).lstatSync(this.resolveSync(pathOrId) || pathOrId, options);
2031
- }
2032
- /**
2033
- * Resolves a path or ID to its real path in the virtual file system (VFS).
2034
- *
2035
- * @param pathOrId - The path or ID to resolve.
2036
- * @returns The resolved real path if it exists, otherwise undefined.
2037
- */
2038
- realpathSync(pathOrId) {
2039
- const filePath = this.resolveSync(pathOrId);
2040
- if (!filePath) {
2041
- throw new Error(`File not found: ${pathOrId}`);
2042
- }
2043
- return filePath;
2044
- }
2045
- /**
2046
2082
  * A helper function to resolve modules in the virtual file system (VFS).
2047
2083
  *
2048
2084
  * @remarks
@@ -2059,9 +2095,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2059
2095
  * @returns A promise that resolves to the resolved module path.
2060
2096
  */
2061
2097
  async resolve(id, importer, options = {}) {
2062
- let result = this.resolverCache.get(this.#normalizeId(id));
2063
- if (result) {
2064
- return result;
2098
+ if (isAbsolutePath(id)) {
2099
+ return id;
2100
+ }
2101
+ let result;
2102
+ if (!this.#context.config.skipCache) {
2103
+ result = this.resolverCache.get(this.#normalizeId(id));
2104
+ if (result) {
2105
+ return result;
2106
+ }
2065
2107
  }
2066
2108
  result = this.paths[this.#normalizeId(id)];
2067
2109
  if (!result) {
@@ -2076,12 +2118,14 @@ var VirtualFileSystem = class _VirtualFileSystem {
2076
2118
  for (const combination of getResolutionCombinations(id, {
2077
2119
  paths
2078
2120
  })) {
2079
- if (this.#existsSync(combination)) {
2121
+ const { relativeKey, adapter } = this.#getStorage(combination);
2122
+ if (await adapter.exists(relativeKey)) {
2080
2123
  result = combination;
2124
+ break;
2081
2125
  }
2082
2126
  }
2083
2127
  try {
2084
- result = await resolve(id, {
2128
+ result = await resolve$1(id, {
2085
2129
  paths
2086
2130
  });
2087
2131
  } catch {
@@ -2089,7 +2133,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2089
2133
  }
2090
2134
  if (result) {
2091
2135
  result = toAbsolutePath(appendPath(result, this.#context.config.projectRoot), this.#context.workspaceConfig.workspaceRoot);
2092
- this.resolverCache.set(this.#normalizeId(id), result);
2136
+ if (!this.#context.config.skipCache) {
2137
+ this.resolverCache.set(this.#normalizeId(id), result);
2138
+ }
2093
2139
  }
2094
2140
  return result;
2095
2141
  }
@@ -2110,9 +2156,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2110
2156
  * @returns The resolved module path.
2111
2157
  */
2112
2158
  resolveSync(id, importer, options = {}) {
2113
- let result = this.resolverCache.get(this.#normalizeId(id));
2114
- if (result) {
2115
- return result;
2159
+ if (isAbsolutePath(id)) {
2160
+ return id;
2161
+ }
2162
+ let result;
2163
+ if (!this.#context.config.skipCache) {
2164
+ result = this.resolverCache.get(this.#normalizeId(id));
2165
+ if (result) {
2166
+ return result;
2167
+ }
2116
2168
  }
2117
2169
  result = this.paths[this.#normalizeId(id)];
2118
2170
  if (!result) {
@@ -2121,14 +2173,16 @@ var VirtualFileSystem = class _VirtualFileSystem {
2121
2173
  paths.push(importer);
2122
2174
  }
2123
2175
  paths.push(this.#context.workspaceConfig.workspaceRoot);
2124
- paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot));
2125
- paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.sourceRoot));
2126
- paths.push(...Object.keys(this.#context.tsconfig?.options?.paths ?? {}).filter((tsconfigPath) => id.startsWith(tsconfigPath.replace(/\*$/, ""))).map((tsconfigPath) => this.#context.tsconfig?.options?.paths?.[tsconfigPath]).flat().filter(Boolean).map((tsconfigPath) => appendPath(tsconfigPath, this.#context.workspaceConfig.workspaceRoot)));
2176
+ paths.push(appendPath(this.#context.config.projectRoot, this.#context.workspaceConfig.workspaceRoot));
2177
+ paths.push(appendPath(this.#context.config.sourceRoot, this.#context.workspaceConfig.workspaceRoot));
2178
+ paths.push(...Object.keys(this.#context.tsconfig.options.paths ?? {}).filter((tsconfigPath) => id.startsWith(tsconfigPath.replace(/\*$/, ""))).map((tsconfigPath) => this.#context.tsconfig.options.paths?.[tsconfigPath]).flat().filter(Boolean).map((tsconfigPath) => appendPath(tsconfigPath, this.#context.workspaceConfig.workspaceRoot)));
2127
2179
  for (const combination of getResolutionCombinations(id, {
2128
2180
  paths
2129
2181
  })) {
2130
- if (this.#existsSync(combination)) {
2182
+ const { relativeKey, adapter } = this.#getStorage(combination);
2183
+ if (adapter.existsSync(relativeKey)) {
2131
2184
  result = combination;
2185
+ break;
2132
2186
  }
2133
2187
  }
2134
2188
  try {
@@ -2140,7 +2194,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2140
2194
  }
2141
2195
  if (result) {
2142
2196
  result = toAbsolutePath(appendPath(result, this.#context.config.projectRoot), this.#context.workspaceConfig.workspaceRoot);
2143
- this.resolverCache.set(this.#normalizeId(id), result);
2197
+ if (!this.#context.config.skipCache) {
2198
+ this.resolverCache.set(this.#normalizeId(id), result);
2199
+ }
2144
2200
  }
2145
2201
  return result;
2146
2202
  }
@@ -2151,27 +2207,27 @@ var VirtualFileSystem = class _VirtualFileSystem {
2151
2207
  if (!this.#isDisposed) {
2152
2208
  this.#isDisposed = true;
2153
2209
  this.#log(LogLevelLabel.DEBUG, "Disposing virtual file system...");
2154
- await this.unlink(joinPaths$1(this.#context.dataPath, "fs.bin"));
2210
+ await this.remove(joinPaths$1(this.#context.dataPath, "fs.bin"));
2155
2211
  const message = new $.Message();
2156
- const fs2 = message.initRoot(FileSystem);
2157
- const virtualFiles = Object.entries(this.#unifiedFS.toJSON()).filter(([, code]) => code);
2158
- const files = fs2._initFiles(virtualFiles.length);
2159
- virtualFiles.filter(([, code]) => code).forEach(([path, code], index) => {
2160
- const fd = files.get(index);
2212
+ const fs = message.initRoot(FileSystem);
2213
+ const paths = await this.list();
2214
+ const storage = fs._initStorage(paths.length);
2215
+ await Promise.all(paths.map(async (path, index) => {
2216
+ const code = await this.read(path);
2217
+ const fd = storage.get(index);
2161
2218
  fd.path = path;
2162
2219
  fd.code = code || "";
2163
- });
2164
- const ids = fs2._initIds(Object.keys(this.ids).length);
2220
+ }));
2221
+ const ids = fs._initIds(Object.keys(this.ids).length);
2165
2222
  Object.entries(this.ids).filter(([, path]) => path).forEach(([id, path], index) => {
2166
2223
  const fileId = ids.get(index);
2167
2224
  fileId.id = id;
2168
2225
  fileId.path = path;
2169
2226
  });
2170
- const metadata = fs2._initMetadata(Object.keys(this.metadata).length);
2227
+ const metadata = fs._initMetadata(Object.keys(this.metadata).length);
2171
2228
  Object.entries(this.metadata).filter(([, value]) => value).forEach(([id, value], index) => {
2172
2229
  const fileMetadata = metadata.get(index);
2173
2230
  fileMetadata.id = id;
2174
- fileMetadata.mode = value.mode;
2175
2231
  fileMetadata.type = value.type;
2176
2232
  fileMetadata.timestamp = value.timestamp ?? BigInt(Date.now());
2177
2233
  if (value.properties) {
@@ -2184,134 +2240,40 @@ var VirtualFileSystem = class _VirtualFileSystem {
2184
2240
  }
2185
2241
  });
2186
2242
  await writeFileBuffer(joinPaths$1(this.#context.dataPath, "fs.bin"), message.toArrayBuffer());
2187
- this.#resolverCache.save(true);
2188
- this.#log(LogLevelLabel.DEBUG, "Virtual file system disposed.");
2189
- }
2190
- }
2191
- /**
2192
- * Initializes the virtual file system (VFS) by patching the file system module if necessary.
2193
- */
2194
- [__VFS_PATCH__]() {
2195
- if (!this.#isPatched && this.#context.config.output.mode !== "fs") {
2196
- this.#revert = patchFS(_fs, this);
2197
- this.#isPatched = true;
2198
- }
2199
- }
2200
- /**
2201
- * Reverts the file system module to its original state if it was previously patched.
2202
- */
2203
- [__VFS_REVERT__]() {
2204
- if (this.#isPatched && this.#context.config.output.mode !== "fs") {
2205
- if (!this.#revert) {
2206
- throw new Error("Attempting to revert File System patch prior to calling `__init__` function");
2207
- }
2208
- this.#revert?.();
2209
- this.#isPatched = false;
2210
- }
2211
- }
2243
+ if (!this.#context.config.skipCache) {
2244
+ this.#resolverCache.save(true);
2245
+ }
2246
+ await Promise.all(this.#getStorages().map(async (storage2) => storage2.adapter.dispose()));
2247
+ this.#log(LogLevelLabel.TRACE, "Virtual file system has been disposed.");
2248
+ }
2249
+ }
2250
+ // /**
2251
+ // * Initializes the virtual file system (VFS) by patching the file system module if necessary.
2252
+ // */
2253
+ // public [__VFS_PATCH__]() {
2254
+ // if (!this.#isPatched && this.#context.config.output.mode !== "fs") {
2255
+ // this.#revert = patchFS(fs, this);
2256
+ // this.#isPatched = true;
2257
+ // }
2258
+ // }
2259
+ // /**
2260
+ // * Reverts the file system module to its original state if it was previously patched.
2261
+ // */
2262
+ // public [__VFS_REVERT__]() {
2263
+ // if (this.#isPatched && this.#context.config.output.mode !== "fs") {
2264
+ // if (!this.#revert) {
2265
+ // throw new Error(
2266
+ // "Attempting to revert File System patch prior to calling `__init__` function"
2267
+ // );
2268
+ // }
2269
+ // this.#revert?.();
2270
+ // this.#isPatched = false;
2271
+ // }
2272
+ // }
2212
2273
  async [Symbol.asyncDispose]() {
2213
2274
  return this.dispose();
2214
2275
  }
2215
2276
  };
2216
- var VirtualFileSystemHost = class VirtualFileSystemHost2 extends InMemoryFileSystemHost {
2217
- static {
2218
- __name(this, "VirtualFileSystemHost");
2219
- }
2220
- #fs;
2221
- constructor(fs2) {
2222
- super();
2223
- this.#fs = fs2;
2224
- }
2225
- deleteSync(path) {
2226
- this.#fs.rmSync(path);
2227
- }
2228
- readDirSync(dirPath) {
2229
- return this.#fs.readdirSync(dirPath).reduce((ret, entry) => {
2230
- const fullPath = this.#fs.resolveSync(joinPaths(dirPath, entry));
2231
- if (fullPath) {
2232
- ret.push({
2233
- name: entry,
2234
- isDirectory: this.#fs.isDirectory(fullPath),
2235
- isFile: this.#fs.isFile(fullPath),
2236
- isSymlink: false
2237
- });
2238
- }
2239
- return ret;
2240
- }, []);
2241
- }
2242
- async readFile(filePath) {
2243
- if (!this.#fs.existsSync(filePath)) {
2244
- throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
2245
- }
2246
- return await this.#fs.readFile(filePath);
2247
- }
2248
- readFileSync(filePath) {
2249
- if (!this.#fs.existsSync(filePath)) {
2250
- throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
2251
- }
2252
- return this.#fs.readFileSync(filePath);
2253
- }
2254
- async writeFile(filePath, fileText) {
2255
- return this.#fs.writeFile(filePath, fileText);
2256
- }
2257
- writeFileSync(filePath, fileText) {
2258
- this.#fs.writeFileSync(filePath, fileText);
2259
- }
2260
- async mkdir(dirPath) {
2261
- await this.#fs.mkdir(dirPath);
2262
- }
2263
- mkdirSync(dirPath) {
2264
- this.#fs.mkdirSync(dirPath);
2265
- }
2266
- async move(srcPath, destPath) {
2267
- await this.#fs.move(srcPath, destPath);
2268
- }
2269
- moveSync(srcPath, destPath) {
2270
- this.#fs.moveSync(srcPath, destPath);
2271
- }
2272
- async copy(srcPath, destPath) {
2273
- await this.#fs.copy(srcPath, destPath);
2274
- }
2275
- copySync(srcPath, destPath) {
2276
- this.#fs.copySync(srcPath, destPath);
2277
- }
2278
- async fileExists(filePath) {
2279
- return this.#fs.isFile(filePath);
2280
- }
2281
- fileExistsSync(filePath) {
2282
- return this.#fs.isFile(filePath);
2283
- }
2284
- async directoryExists(dirPath) {
2285
- return this.#fs.isDirectory(dirPath);
2286
- }
2287
- directoryExistsSync(dirPath) {
2288
- return this.#fs.isDirectory(dirPath);
2289
- }
2290
- realpathSync(path) {
2291
- return this.#fs.resolveSync(path) || path;
2292
- }
2293
- getCurrentDirectory() {
2294
- return "/";
2295
- }
2296
- async glob(patterns) {
2297
- return this.#fs.glob(patterns);
2298
- }
2299
- globSync(patterns) {
2300
- return this.#fs.globSync(patterns);
2301
- }
2302
- };
2303
- function createProgram(context, override) {
2304
- const project = new Project({
2305
- compilerOptions: {
2306
- ...context.tsconfig.options
2307
- },
2308
- tsConfigFilePath: context.tsconfig.tsconfigFilePath,
2309
- fileSystem: new VirtualFileSystemHost(context.fs),
2310
- ...override
2311
- });
2312
- return project;
2313
- }
2314
- __name(createProgram, "createProgram");
2315
2277
 
2316
2278
  // ../powerlines/src/lib/contexts/context.ts
2317
2279
  var configCache = /* @__PURE__ */ new WeakMap();
@@ -2512,7 +2474,7 @@ var PowerlinesContext = class _PowerlinesContext {
2512
2474
  * Get the path to the artifacts directory for the project
2513
2475
  */
2514
2476
  get artifactsPath() {
2515
- return joinPaths(this.workspaceConfig.workspaceRoot, this.config.projectRoot, this.config.output.artifactsFolder);
2477
+ return joinPaths(this.workspaceConfig.workspaceRoot, this.config.projectRoot, this.config.output.artifactsPath);
2516
2478
  }
2517
2479
  /**
2518
2480
  * Get the path to the builtin modules used by the project
@@ -2652,7 +2614,7 @@ var PowerlinesContext = class _PowerlinesContext {
2652
2614
  if (!resolvedId) {
2653
2615
  return void 0;
2654
2616
  }
2655
- const code = await this.fs.readFile(resolvedId);
2617
+ const code = await this.fs.read(resolvedId);
2656
2618
  if (!code) {
2657
2619
  return void 0;
2658
2620
  }
@@ -2666,7 +2628,7 @@ var PowerlinesContext = class _PowerlinesContext {
2666
2628
  */
2667
2629
  async getBuiltins() {
2668
2630
  return Promise.all(Object.entries(this.fs.metadata).filter(([, meta]) => meta && meta.type === "builtin").map(async ([path, meta]) => {
2669
- const code = await this.fs.readFile(path);
2631
+ const code = await this.fs.read(path);
2670
2632
  return {
2671
2633
  ...meta,
2672
2634
  path,
@@ -2682,11 +2644,8 @@ var PowerlinesContext = class _PowerlinesContext {
2682
2644
  * @param options - Optional write file options
2683
2645
  */
2684
2646
  async emitEntry(code, path, options = {}) {
2685
- return this.fs.writeFile(isAbsolute(path) ? path : appendPath(path, this.entryPath), {
2686
- code,
2647
+ return this.fs.write(isAbsolute(path) ? path : appendPath(path, this.entryPath), code, defu6(options, {
2687
2648
  type: "entry"
2688
- }, defu5(options, {
2689
- mode: this.config.output.mode
2690
2649
  }));
2691
2650
  }
2692
2651
  /**
@@ -2698,12 +2657,8 @@ var PowerlinesContext = class _PowerlinesContext {
2698
2657
  * @param options - Optional write file options
2699
2658
  */
2700
2659
  async emitBuiltin(code, id, path, options = {}) {
2701
- return this.fs.writeFile(path ? isAbsolute(path) ? path : joinPaths(this.builtinsPath, path) : appendPath(id, this.builtinsPath), {
2702
- id,
2703
- code,
2660
+ return this.fs.write(path ? isAbsolute(path) ? path : joinPaths(this.builtinsPath, path) : appendPath(id, this.builtinsPath), code, defu6(options, {
2704
2661
  type: "builtin"
2705
- }, defu5(options, {
2706
- mode: this.config.output.mode
2707
2662
  }));
2708
2663
  }
2709
2664
  /**
@@ -2897,9 +2852,9 @@ var PowerlinesContext = class _PowerlinesContext {
2897
2852
  userConfig
2898
2853
  });
2899
2854
  }
2900
- this.config.tsconfig ??= getTsconfigFilePath(this.workspaceConfig.workspaceRoot, cacheKey.projectRoot, config.tsconfig);
2855
+ config.tsconfig ??= getTsconfigFilePath(this.workspaceConfig.workspaceRoot, cacheKey.projectRoot, config.tsconfig);
2901
2856
  if (isSetObject(config)) {
2902
- this.resolvedConfig = defu5({
2857
+ this.resolvedConfig = defu6({
2903
2858
  inlineConfig: this.config.inlineConfig,
2904
2859
  userConfig: this.config.userConfig
2905
2860
  }, options.isHighPriority ? this.#getConfigProps(config) : {}, {
@@ -2914,12 +2869,11 @@ var PowerlinesContext = class _PowerlinesContext {
2914
2869
  version: this.packageJson?.version,
2915
2870
  description: this.packageJson?.description,
2916
2871
  sourceRoot: this.projectJson?.sourceRoot || appendPath("src", cacheKey.projectRoot),
2917
- output: {
2872
+ output: defu6(config.output ?? {}, {
2918
2873
  outputPath: cacheKey.projectRoot ? joinPaths(this.workspaceConfig?.directories?.build || "dist", cacheKey.projectRoot) : this.workspaceConfig?.directories?.build || "dist",
2919
- mode: "virtual",
2874
+ artifactsPath: joinPaths(cacheKey.projectRoot, `.${config.framework ?? "powerlines"}`),
2920
2875
  dts: joinPaths(cacheKey.projectRoot, `${config.framework ?? "powerlines"}.d.ts`),
2921
2876
  builtinPrefix: config.framework ?? "powerlines",
2922
- artifactsFolder: joinPaths(cacheKey.projectRoot, `.${config.framework ?? "powerlines"}`),
2923
2877
  assets: [
2924
2878
  {
2925
2879
  glob: "LICENSE"
@@ -2933,7 +2887,7 @@ var PowerlinesContext = class _PowerlinesContext {
2933
2887
  glob: "package.json"
2934
2888
  }
2935
2889
  ]
2936
- }
2890
+ })
2937
2891
  }, options.isHighPriority ? {} : this.#getConfigProps(config), {
2938
2892
  inlineConfig: {},
2939
2893
  userConfig: {},
@@ -2978,10 +2932,10 @@ var PowerlinesContext = class _PowerlinesContext {
2978
2932
  ])));
2979
2933
  if (this.config.projectRoot && this.config.projectRoot !== "." && this.config.projectRoot !== "./" && this.config.projectRoot !== this.workspaceConfig.workspaceRoot) {
2980
2934
  this.config.output.outputPath ??= joinPaths("dist", this.config.projectRoot);
2981
- this.config.output.distPath ??= joinPaths(this.config.projectRoot, "dist");
2935
+ this.config.output.buildPath ??= joinPaths(this.config.projectRoot, "dist");
2982
2936
  } else {
2983
2937
  this.config.output.outputPath ??= "dist";
2984
- this.config.output.distPath ??= "dist";
2938
+ this.config.output.buildPath ??= "dist";
2985
2939
  }
2986
2940
  this.config.output.assets = getUnique(this.config.output.assets.map((asset) => {
2987
2941
  return {
@@ -3019,7 +2973,7 @@ var PowerlinesContext = class _PowerlinesContext {
3019
2973
  this.#fs ??= await VirtualFileSystem.create(this);
3020
2974
  }
3021
2975
  mergeUserConfig(from = {}, into = this.config.userConfig ?? {}) {
3022
- this.config.userConfig = defu5({
2976
+ this.config.userConfig = defu6({
3023
2977
  entry: Array.isArray(from.entry) && from.entry.length > 0 ? from.entry : Array.isArray(into?.entry) && into.entry.length > 0 ? into.entry : []
3024
2978
  }, omit(from ?? {}, [
3025
2979
  "entry"
@@ -3324,12 +3278,49 @@ var PowerlinesAPIContext = class _PowerlinesAPIContext extends PowerlinesContext
3324
3278
  }
3325
3279
  return context;
3326
3280
  }
3281
+ /**
3282
+ * Update the context using a new user configuration options
3283
+ *
3284
+ * @param userConfig - The new user configuration options.
3285
+ */
3286
+ async withUserConfig(userConfig, options = {
3287
+ isHighPriority: true
3288
+ }) {
3289
+ await super.withUserConfig(userConfig, options);
3290
+ await Promise.all(Object.keys(this.#environments).map(async (name) => {
3291
+ await this.#environments[name].withUserConfig(userConfig, options);
3292
+ }));
3293
+ }
3294
+ /**
3295
+ * Update the context using a new inline configuration options
3296
+ *
3297
+ * @param inlineConfig - The new inline configuration options.
3298
+ */
3299
+ async withInlineConfig(inlineConfig, options = {
3300
+ isHighPriority: true
3301
+ }) {
3302
+ await super.withInlineConfig(inlineConfig, options);
3303
+ await Promise.all(Object.keys(this.#environments).map(async (name) => {
3304
+ await this.#environments[name].withInlineConfig(inlineConfig, options);
3305
+ }));
3306
+ }
3307
+ /**
3308
+ * Add a plugin to the API context and all environments
3309
+ *
3310
+ * @param plugin - The plugin to add.
3311
+ */
3327
3312
  async addPlugin(plugin) {
3328
3313
  this.plugins.push(plugin);
3329
3314
  await Promise.all(Object.keys(this.environments).map(async (name) => {
3330
3315
  await this.environments[name].addPlugin(plugin);
3331
3316
  }));
3332
3317
  }
3318
+ /**
3319
+ * Get an environment by name, or the default environment if no name is provided
3320
+ *
3321
+ * @param name - The name of the environment to retrieve.
3322
+ * @returns The requested environment context.
3323
+ */
3333
3324
  async getEnvironment(name) {
3334
3325
  let environment;
3335
3326
  if (name) {
@@ -3451,21 +3442,17 @@ ${formatLogMessage(context.config)}`);
3451
3442
  await writeMetaFile(context);
3452
3443
  context.persistedMeta = context.meta;
3453
3444
  if (!context.fs.existsSync(context.cachePath)) {
3454
- await context.fs.mkdir(context.cachePath, {
3455
- mode: "fs"
3456
- });
3445
+ await createDirectory(context.cachePath);
3457
3446
  }
3458
3447
  if (!context.fs.existsSync(context.dataPath)) {
3459
- await context.fs.mkdir(context.dataPath, {
3460
- mode: "fs"
3461
- });
3448
+ await createDirectory(context.dataPath);
3462
3449
  }
3463
3450
  await this.callPreHook(context, "prepare");
3464
3451
  await this.callNormalHook(context, "prepare");
3465
3452
  if (context.config.output.dts !== false) {
3466
3453
  context.log(LogLevelLabel.TRACE, `Preparing the TypeScript definitions for the Powerlines project.`);
3467
3454
  if (context.fs.existsSync(context.dtsPath)) {
3468
- await context.fs.unlink(context.dtsPath);
3455
+ await context.fs.remove(context.dtsPath);
3469
3456
  }
3470
3457
  context.log(LogLevelLabel.TRACE, "Transforming built-ins runtime modules files.");
3471
3458
  const builtinFilePaths = await Promise.all((await context.getBuiltins()).map(async (file) => {
@@ -3552,7 +3539,7 @@ ${formatLogMessage(context.config)}`);
3552
3539
  generatedTypes = result;
3553
3540
  }
3554
3541
  }
3555
- await context.fs.writeFile(context.dtsPath, `${directives ? `${directives.map((directive) => `/// <reference types="${directive}" />`).join("\n")}
3542
+ await context.fs.write(context.dtsPath, `${directives ? `${directives.map((directive) => `/// <reference types="${directive}" />`).join("\n")}
3556
3543
 
3557
3544
  ` : ""}${getFileHeader(context, {
3558
3545
  directive: null,
@@ -3560,9 +3547,7 @@ ${formatLogMessage(context.config)}`);
3560
3547
  })}
3561
3548
 
3562
3549
  ${formatTypes(generatedTypes)}
3563
- `, {
3564
- mode: "fs"
3565
- });
3550
+ `);
3566
3551
  }
3567
3552
  context.tsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.config.tsconfig);
3568
3553
  if (!context.tsconfig) {
@@ -3630,8 +3615,8 @@ ${formatTypes(generatedTypes)}
3630
3615
  await this.prepare(inlineConfig);
3631
3616
  await this.#executeEnvironments(async (context) => {
3632
3617
  this.context.log(LogLevelLabel.TRACE, "Cleaning the project's dist and artifacts directories.");
3633
- await context.fs.rmdir(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.output.distPath));
3634
- await context.fs.rmdir(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.output.artifactsFolder));
3618
+ await context.fs.remove(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.output.buildPath));
3619
+ await context.fs.remove(joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.output.artifactsPath));
3635
3620
  await callHook(context, "clean", {
3636
3621
  sequential: true
3637
3622
  });
@@ -3673,11 +3658,11 @@ ${formatTypes(generatedTypes)}
3673
3658
  await this.#executeEnvironments(async (context) => {
3674
3659
  await this.callPreHook(context, "build");
3675
3660
  await this.callNormalHook(context, "build");
3676
- if (context.config.output.distPath !== context.config.output.outputPath) {
3677
- const sourcePath = appendPath(context.config.output.distPath, context.workspaceConfig.workspaceRoot);
3661
+ if (context.config.output.buildPath !== context.config.output.outputPath) {
3662
+ const sourcePath = appendPath(context.config.output.buildPath, context.workspaceConfig.workspaceRoot);
3678
3663
  const destinationPath = joinPaths$1(appendPath(context.config.output.outputPath, context.workspaceConfig.workspaceRoot), "dist");
3679
3664
  if (sourcePath !== destinationPath) {
3680
- context.log(LogLevelLabel.INFO, `Copying build output files from project's build directory (${context.config.output.distPath}) to the workspace's output directory (${context.config.output.outputPath}).`);
3665
+ context.log(LogLevelLabel.INFO, `Copying build output files from project's build directory (${context.config.output.buildPath}) to the workspace's output directory (${context.config.output.outputPath}).`);
3681
3666
  await copyFiles({
3682
3667
  input: sourcePath,
3683
3668
  glob: "**/*"
@@ -4020,7 +4005,7 @@ function withExecutor(command, executorFn) {
4020
4005
  throw new Error("The executor requires `projectsConfigurations` on the context object.");
4021
4006
  }
4022
4007
  const projectConfig = context.projectsConfigurations.projects[context.projectName];
4023
- const api = await src_default.from(workspaceConfig.workspaceRoot, defu5({
4008
+ const api = await src_default.from(workspaceConfig.workspaceRoot, defu6({
4024
4009
  root: projectConfig.root,
4025
4010
  type: projectConfig.projectType,
4026
4011
  sourceRoot: projectConfig.sourceRoot,
@@ -4033,7 +4018,7 @@ function withExecutor(command, executorFn) {
4033
4018
  }
4034
4019
  }, options));
4035
4020
  try {
4036
- return await Promise.resolve(executorFn(defu5({
4021
+ return await Promise.resolve(executorFn(defu6({
4037
4022
  projectName: context.projectName,
4038
4023
  options,
4039
4024
  workspaceConfig,