@powerlines/nx 0.10.26 → 0.10.28

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 (42) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{chunk-ACE6O62X.js → chunk-2PYUYDPD.js} +11 -11
  3. package/dist/{chunk-6WVDB4DZ.js → chunk-2YSHMNU6.js} +2 -2
  4. package/dist/{chunk-ONWCIW2E.mjs → chunk-5WHBT2BW.mjs} +1 -1
  5. package/dist/{chunk-PJYRCGK4.js → chunk-7E3PRE6W.js} +2 -2
  6. package/dist/{chunk-6UH4EGMN.mjs → chunk-DLZ7E67Y.mjs} +1 -1
  7. package/dist/{chunk-BXKPRYNH.mjs → chunk-DMX7BNND.mjs} +22 -14
  8. package/dist/{chunk-7TPTVC3S.js → chunk-GVA7U7C4.js} +2 -2
  9. package/dist/{chunk-2SFOQMAA.js → chunk-HLYNF7YE.js} +533 -654
  10. package/dist/{chunk-B5L3T46G.js → chunk-HVWVP6CD.js} +2 -2
  11. package/dist/{chunk-JPTGZQLU.js → chunk-MAMHMV35.js} +22 -14
  12. package/dist/{chunk-A26KXB6A.js → chunk-ND7VF7PZ.js} +2 -2
  13. package/dist/{chunk-4A6Y7MGQ.js → chunk-PM5JBU7Z.js} +2 -2
  14. package/dist/{chunk-IAWSQ5AX.mjs → chunk-QE2RQBEB.mjs} +527 -648
  15. package/dist/{chunk-Z22G7IM3.mjs → chunk-RIM7CNHX.mjs} +1 -1
  16. package/dist/{chunk-KCL7KVDF.mjs → chunk-VQX5TBLP.mjs} +1 -1
  17. package/dist/{chunk-X6GFPXO4.mjs → chunk-WGIN2BGP.mjs} +11 -11
  18. package/dist/{chunk-L46S3DXB.mjs → chunk-Y4WK22DY.mjs} +1 -1
  19. package/dist/{chunk-A7SAZMVH.mjs → chunk-ZIBEDH47.mjs} +1 -1
  20. package/dist/executors.js +14 -14
  21. package/dist/executors.mjs +7 -7
  22. package/dist/index.js +17 -17
  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/dist/src/types/plugin.d.mts +24 -0
  41. package/dist/src/types/plugin.d.ts +24 -0
  42. package/package.json +8 -8
@@ -1,4 +1,4 @@
1
- import { loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, loadUserConfigFile, writeMetaFile } from './chunk-X6GFPXO4.mjs';
1
+ import { loadWorkspaceConfig, CACHE_HASH_LENGTH, PROJECT_ROOT_HASH_LENGTH, getPrefixedProjectRootHash, loadUserConfigFile, writeMetaFile } from './chunk-WGIN2BGP.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';
@@ -14,7 +14,7 @@ import { createDirectory } from '@stryke/fs/helpers';
14
14
  import { install } from '@stryke/fs/install';
15
15
  import { listFiles, listFilesSync } from '@stryke/fs/list-files';
16
16
  import { isPackageExists, isPackageListed, doesPackageMatch, getPackageListing } from '@stryke/fs/package-fns';
17
- import { resolvePackage } from '@stryke/fs/resolve';
17
+ import { getResolutionCombinations, resolve, resolveSync, resolvePackage } from '@stryke/fs/resolve';
18
18
  import { appendPath } from '@stryke/path/append';
19
19
  import { joinPaths as joinPaths$1 } from '@stryke/path/join-paths';
20
20
  import { replacePath, replaceExtension } from '@stryke/path/replace';
@@ -28,13 +28,13 @@ import chalk5 from 'chalk';
28
28
  import Handlebars from 'handlebars';
29
29
  import { declare } from '@babel/helper-plugin-utils';
30
30
  import * as t from '@babel/types';
31
- import ts2, { createProgram, createCompilerHost, getPreEmitDiagnostics, getLineAndCharacterOfPosition, flattenDiagnosticMessageText } from 'typescript';
31
+ import ts2, { flattenDiagnosticMessageText } from 'typescript';
32
32
  import { getPackageName, hasPackageVersion, getPackageVersion } from '@stryke/string-format/package';
33
33
  import { getObjectDiff } from '@donedeal0/superdiff';
34
34
  import { readJsonFile, readJsonFileSync } from '@stryke/fs/json';
35
35
  import { loadTsConfig } from '@stryke/fs/tsconfig';
36
36
  import { StormJSON } from '@stryke/json/storm-json';
37
- import { findFileDotExtensionSafe, findFilePath, relativePath, findFileName } from '@stryke/path/file-path-fns';
37
+ import { findFilePath, relativePath, findFileName, findFileDotExtensionSafe } from '@stryke/path/file-path-fns';
38
38
  import { titleCase } from '@stryke/string-format/title-case';
39
39
  import { writeFile as writeFile$1 } from '@stryke/fs/write-file';
40
40
  import { resolveConfig, format } from 'prettier';
@@ -49,6 +49,7 @@ import { joinPaths } from '@stryke/path/join';
49
49
  import { isNull } from '@stryke/type-checks/is-null';
50
50
  import { isString } from '@stryke/type-checks/is-string';
51
51
  import { uuid } from '@stryke/unique-id/uuid';
52
+ import { tsconfigPathsToRegExp, match } from 'bundle-require';
52
53
  import { createJiti } from 'jiti';
53
54
  import { isUndefined } from '@stryke/type-checks/is-undefined';
54
55
  import { parseTypeDefinition } from '@stryke/convert/parse-type-definition';
@@ -56,8 +57,10 @@ import { isFile } from '@stryke/fs/is-file';
56
57
  import * as $ from '@stryke/capnp';
57
58
  import { bufferToString } from '@stryke/convert/buffer-to-string';
58
59
  import { readFileBuffer, readFileBufferSync, writeFileBuffer } from '@stryke/fs/buffer';
60
+ import { toAbsolutePath } from '@stryke/path/correct-path';
59
61
  import { prettyBytes } from '@stryke/string-format/pretty-bytes';
60
62
  import { isBuffer } from '@stryke/type-checks/is-buffer';
63
+ import { create } from 'flat-cache';
61
64
  import { Blob } from 'node:buffer';
62
65
  import _fs from 'node:fs';
63
66
  import { getColor } from '@storm-software/config-tools/utilities/colors';
@@ -65,6 +68,7 @@ import { noop } from '@stryke/helpers/noop';
65
68
  import { isParentPath } from '@stryke/path/is-parent-path';
66
69
  import { Volume } from 'memfs';
67
70
  import { Union } from 'unionfs';
71
+ import { InMemoryFileSystemHost, Project } from 'ts-morph';
68
72
  import { isObject } from '@stryke/type-checks/is-object';
69
73
 
70
74
  function resolveModulePath(nodePath, state) {
@@ -72,7 +76,7 @@ function resolveModulePath(nodePath, state) {
72
76
  return;
73
77
  }
74
78
  const sourcePath = nodePath.node.value;
75
- const resolvedPath = state.context?.fs.resolve(sourcePath);
79
+ const resolvedPath = state.context?.fs.resolveSync(sourcePath);
76
80
  if (resolvedPath) {
77
81
  nodePath.replaceWith(t.stringLiteral(
78
82
  // Remove the file extension if it exists
@@ -176,33 +180,31 @@ function formatTypes(code) {
176
180
  ).replaceAll("#private;", "").replace(/__Ω/g, "");
177
181
  }
178
182
  __name(formatTypes, "formatTypes");
179
- async function emitTypes(context, tsconfig, files) {
180
- context.log(LogLevelLabel.TRACE, "Creating the TypeScript compiler host");
181
- const program = createProgram(files, tsconfig.options, createCompilerHost(tsconfig.options));
182
- context.log(LogLevelLabel.TRACE, `Running the TypeScript compiler for ${context.builtins.length} built-in runtime files.`);
183
+ async function emitTypes(context, files) {
184
+ context.log(LogLevelLabel.TRACE, `Running the TypeScript compiler for ${files.length} generated runtime files.`);
185
+ context.program.addSourceFilesAtPaths(files);
186
+ const result = context.program.emitToMemory({
187
+ emitOnlyDtsFiles: true
188
+ });
183
189
  let builtinModules = "";
184
- const emitResult = program.emit(void 0, (fileName, text, _, __, sourceFiles, _data) => {
185
- const sourceFile = sourceFiles?.[0];
186
- if (sourceFile?.fileName && !fileName.endsWith(".map")) {
187
- if (context.builtins.some((file) => file === sourceFile.fileName || context.fs.metadata[file]?.id && context.fs.metadata[file]?.id === sourceFile.fileName)) {
190
+ for (const file of result.getFiles()) {
191
+ if (!file.filePath.endsWith(".map")) {
192
+ if (context.builtins.some((builtin) => builtin === file.filePath || context.fs.metadata[builtin]?.id && context.fs.metadata[builtin]?.id === file.filePath)) {
193
+ const module = await context.fs.resolve(file.filePath);
188
194
  builtinModules += `
189
- declare module "${context.fs.resolve(sourceFile.fileName)}" {
190
- ${text.trim().replace(/^\s*export\s*declare\s*/gm, "export ").replace(/^\s*declare\s*/gm, "")}
191
- }
192
- `;
195
+ declare module "${module}" {
196
+ ${file.text.trim().replace(/^\s*export\s*declare\s*/gm, "export ").replace(/^\s*declare\s*/gm, "")}
197
+ }
198
+ `;
193
199
  }
194
200
  }
195
- }, void 0, true);
196
- const diagnostics = getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
201
+ }
197
202
  const diagnosticMessages = [];
198
- diagnostics.forEach((diagnostic) => {
199
- if (diagnostic.file) {
200
- const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
201
- const message = flattenDiagnosticMessageText(diagnostic.messageText, "\n");
202
- diagnosticMessages.push(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
203
+ result.getDiagnostics().forEach((diagnostic) => {
204
+ if (diagnostic.getSourceFile()?.getBaseName()) {
205
+ diagnosticMessages.push(`${diagnostic.getSourceFile()?.getBaseName()} (${(diagnostic.getLineNumber() ?? 0) + 1}): ${flattenDiagnosticMessageText(diagnostic.getMessageText().toString(), "\n")}`);
203
206
  } else {
204
- const message = flattenDiagnosticMessageText(diagnostic.messageText, "\n");
205
- diagnosticMessages.push(message);
207
+ diagnosticMessages.push(flattenDiagnosticMessageText(diagnostic.getMessageText().toString(), "\n"));
206
208
  }
207
209
  });
208
210
  const diagnosticMessage = diagnosticMessages.join("\n");
@@ -517,6 +519,7 @@ async function initializeTsconfig(context) {
517
519
  const tsconfigFilePath = getTsconfigFilePath(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.config.tsconfig);
518
520
  context.tsconfig.originalTsconfigJson = await readJsonFile(tsconfigFilePath);
519
521
  context.tsconfig.tsconfigJson = await resolveTsconfigChanges(context);
522
+ context.log(LogLevelLabel.TRACE, "Writing updated TypeScript configuration (tsconfig.json) file to disk.");
520
523
  await context.fs.writeFile(tsconfigFilePath, StormJSON.stringify(context.tsconfig.tsconfigJson), {
521
524
  mode: "fs"
522
525
  });
@@ -624,6 +627,7 @@ function createDefaultEnvironment(userConfig) {
624
627
  __name(createDefaultEnvironment, "createDefaultEnvironment");
625
628
  function resolveOptions(options) {
626
629
  return defu5(options, {
630
+ debug: options.logLevel === "trace",
627
631
  interopDefault: true,
628
632
  fsCache: options.mode !== "development" ? joinPaths$1(options.cacheDir, "jiti") : false,
629
633
  moduleCache: options.mode !== "development"
@@ -717,8 +721,6 @@ function replacePathTokens(context, path) {
717
721
  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));
718
722
  }
719
723
  __name(replacePathTokens, "replacePathTokens");
720
-
721
- // ../powerlines/src/lib/entry.ts
722
724
  function resolveEntryInputFile(context, typeDefinition) {
723
725
  return replacePath(typeDefinition.file, joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot));
724
726
  }
@@ -866,187 +868,6 @@ var FileMetadata = class _FileMetadata extends $.Struct {
866
868
  return "FileMetadata_" + super.toString();
867
869
  }
868
870
  };
869
- var ChunkData = class extends $.Struct {
870
- static {
871
- __name(this, "ChunkData");
872
- }
873
- static _capnp = {
874
- displayName: "ChunkData",
875
- id: "84076f13b057f83a",
876
- size: new $.ObjectSize(8, 4)
877
- };
878
- /**
879
- * An additional name for the file.
880
- *
881
- */
882
- get id() {
883
- return $.utils.getText(0, this);
884
- }
885
- set id(value) {
886
- $.utils.setText(0, value, this);
887
- }
888
- /**
889
- * Files that are implicitly loaded after one of the specified files.
890
- *
891
- */
892
- get name() {
893
- return $.utils.getText(1, this);
894
- }
895
- set name(value) {
896
- $.utils.setText(1, value, this);
897
- }
898
- _adoptImplicitlyLoadedAfterOneOf(value) {
899
- $.utils.adopt(value, $.utils.getPointer(2, this));
900
- }
901
- _disownImplicitlyLoadedAfterOneOf() {
902
- return $.utils.disown(this.implicitlyLoadedAfterOneOf);
903
- }
904
- /**
905
- * The importer of the file.
906
- *
907
- */
908
- get implicitlyLoadedAfterOneOf() {
909
- return $.utils.getList(2, $.TextList, this);
910
- }
911
- _hasImplicitlyLoadedAfterOneOf() {
912
- return !$.utils.isNull($.utils.getPointer(2, this));
913
- }
914
- _initImplicitlyLoadedAfterOneOf(length) {
915
- return $.utils.initList(2, $.TextList, length, this);
916
- }
917
- set implicitlyLoadedAfterOneOf(value) {
918
- $.utils.copyFrom(value, $.utils.getPointer(2, this));
919
- }
920
- /**
921
- * The signature preservation mode for the file.
922
- *
923
- */
924
- get importer() {
925
- return $.utils.getText(3, this);
926
- }
927
- set importer(value) {
928
- $.utils.setText(3, value, this);
929
- }
930
- get preserveSignature() {
931
- return $.utils.getUint16(0, this);
932
- }
933
- set preserveSignature(value) {
934
- $.utils.setUint16(0, value, this);
935
- }
936
- toString() {
937
- return "ChunkData_" + super.toString();
938
- }
939
- };
940
- var PrebuiltData = class extends $.Struct {
941
- static {
942
- __name(this, "PrebuiltData");
943
- }
944
- static _capnp = {
945
- displayName: "PrebuiltData",
946
- id: "c5b1a6ca696328ee",
947
- size: new $.ObjectSize(0, 4)
948
- };
949
- /**
950
- * An additional name for the file.
951
- *
952
- */
953
- get id() {
954
- return $.utils.getText(0, this);
955
- }
956
- set id(value) {
957
- $.utils.setText(0, value, this);
958
- }
959
- /**
960
- * The file exports.
961
- *
962
- */
963
- get name() {
964
- return $.utils.getText(1, this);
965
- }
966
- set name(value) {
967
- $.utils.setText(1, value, this);
968
- }
969
- _adoptExports(value) {
970
- $.utils.adopt(value, $.utils.getPointer(2, this));
971
- }
972
- _disownExports() {
973
- return $.utils.disown(this.exports);
974
- }
975
- /**
976
- * The source map for the file.
977
- *
978
- */
979
- get exports() {
980
- return $.utils.getList(2, $.TextList, this);
981
- }
982
- _hasExports() {
983
- return !$.utils.isNull($.utils.getPointer(2, this));
984
- }
985
- _initExports(length) {
986
- return $.utils.initList(2, $.TextList, length, this);
987
- }
988
- set exports(value) {
989
- $.utils.copyFrom(value, $.utils.getPointer(2, this));
990
- }
991
- get map() {
992
- return $.utils.getText(3, this);
993
- }
994
- set map(value) {
995
- $.utils.setText(3, value, this);
996
- }
997
- toString() {
998
- return "PrebuiltData_" + super.toString();
999
- }
1000
- };
1001
- var AssetData = class extends $.Struct {
1002
- static {
1003
- __name(this, "AssetData");
1004
- }
1005
- static _capnp = {
1006
- displayName: "AssetData",
1007
- id: "da660c6c1fa4c830",
1008
- size: new $.ObjectSize(8, 3)
1009
- };
1010
- /**
1011
- * An additional name for the file.
1012
- *
1013
- */
1014
- get id() {
1015
- return $.utils.getText(0, this);
1016
- }
1017
- set id(value) {
1018
- $.utils.setText(0, value, this);
1019
- }
1020
- /**
1021
- * Indicates whether the file needs a code reference.
1022
- *
1023
- */
1024
- get name() {
1025
- return $.utils.getText(1, this);
1026
- }
1027
- set name(value) {
1028
- $.utils.setText(1, value, this);
1029
- }
1030
- /**
1031
- * The original file name before any transformations.
1032
- *
1033
- */
1034
- get needsCodeReference() {
1035
- return $.utils.getBit(0, this);
1036
- }
1037
- set needsCodeReference(value) {
1038
- $.utils.setBit(0, value, this);
1039
- }
1040
- get originalFileName() {
1041
- return $.utils.getText(2, this);
1042
- }
1043
- set originalFileName(value) {
1044
- $.utils.setText(2, value, this);
1045
- }
1046
- toString() {
1047
- return "AssetData_" + super.toString();
1048
- }
1049
- };
1050
871
  var FileId = class extends $.Struct {
1051
872
  static {
1052
873
  __name(this, "FileId");
@@ -1112,14 +933,11 @@ var FileSystem = class _FileSystem extends $.Struct {
1112
933
  static _capnp = {
1113
934
  displayName: "FileSystem",
1114
935
  id: "ae0c23d43e56abcf",
1115
- size: new $.ObjectSize(0, 6)
936
+ size: new $.ObjectSize(0, 3)
1116
937
  };
1117
938
  static _Ids;
1118
939
  static _Files;
1119
940
  static _Metadata;
1120
- static _Assets;
1121
- static _Chunks;
1122
- static _Prebuilt;
1123
941
  _adoptIds(value) {
1124
942
  $.utils.adopt(value, $.utils.getPointer(0, this));
1125
943
  }
@@ -1174,60 +992,6 @@ var FileSystem = class _FileSystem extends $.Struct {
1174
992
  set metadata(value) {
1175
993
  $.utils.copyFrom(value, $.utils.getPointer(2, this));
1176
994
  }
1177
- _adoptAssets(value) {
1178
- $.utils.adopt(value, $.utils.getPointer(3, this));
1179
- }
1180
- _disownAssets() {
1181
- return $.utils.disown(this.assets);
1182
- }
1183
- get assets() {
1184
- return $.utils.getList(3, _FileSystem._Assets, this);
1185
- }
1186
- _hasAssets() {
1187
- return !$.utils.isNull($.utils.getPointer(3, this));
1188
- }
1189
- _initAssets(length) {
1190
- return $.utils.initList(3, _FileSystem._Assets, length, this);
1191
- }
1192
- set assets(value) {
1193
- $.utils.copyFrom(value, $.utils.getPointer(3, this));
1194
- }
1195
- _adoptChunks(value) {
1196
- $.utils.adopt(value, $.utils.getPointer(4, this));
1197
- }
1198
- _disownChunks() {
1199
- return $.utils.disown(this.chunks);
1200
- }
1201
- get chunks() {
1202
- return $.utils.getList(4, _FileSystem._Chunks, this);
1203
- }
1204
- _hasChunks() {
1205
- return !$.utils.isNull($.utils.getPointer(4, this));
1206
- }
1207
- _initChunks(length) {
1208
- return $.utils.initList(4, _FileSystem._Chunks, length, this);
1209
- }
1210
- set chunks(value) {
1211
- $.utils.copyFrom(value, $.utils.getPointer(4, this));
1212
- }
1213
- _adoptPrebuilt(value) {
1214
- $.utils.adopt(value, $.utils.getPointer(5, this));
1215
- }
1216
- _disownPrebuilt() {
1217
- return $.utils.disown(this.prebuilt);
1218
- }
1219
- get prebuilt() {
1220
- return $.utils.getList(5, _FileSystem._Prebuilt, this);
1221
- }
1222
- _hasPrebuilt() {
1223
- return !$.utils.isNull($.utils.getPointer(5, this));
1224
- }
1225
- _initPrebuilt(length) {
1226
- return $.utils.initList(5, _FileSystem._Prebuilt, length, this);
1227
- }
1228
- set prebuilt(value) {
1229
- $.utils.copyFrom(value, $.utils.getPointer(5, this));
1230
- }
1231
995
  toString() {
1232
996
  return "FileSystem_" + super.toString();
1233
997
  }
@@ -1236,9 +1000,6 @@ FileMetadata._Properties = $.CompositeList(FileMetadata_KeyValuePair);
1236
1000
  FileSystem._Ids = $.CompositeList(FileId);
1237
1001
  FileSystem._Files = $.CompositeList(FileData);
1238
1002
  FileSystem._Metadata = $.CompositeList(FileMetadata);
1239
- FileSystem._Assets = $.CompositeList(AssetData);
1240
- FileSystem._Chunks = $.CompositeList(ChunkData);
1241
- FileSystem._Prebuilt = $.CompositeList(PrebuiltData);
1242
1003
 
1243
1004
  // ../powerlines/src/types/fs.ts
1244
1005
  var __VFS_PATCH__ = "__VFS_PATCH__";
@@ -1286,13 +1047,9 @@ function isBufferEncoding(options) {
1286
1047
  }
1287
1048
  __name(isBufferEncoding, "isBufferEncoding");
1288
1049
  function isPowerlinesWriteFileOptions(options) {
1289
- return !isBufferEncoding(options) && isSetObject(options) && ("skipFormat" in options || "mode" in options && (options.mode === "fs" || options.mode === "virtual"));
1050
+ return !isBufferEncoding(options) && isSetObject(options) && "mode" in options && (options.mode === "fs" || options.mode === "virtual");
1290
1051
  }
1291
1052
  __name(isPowerlinesWriteFileOptions, "isPowerlinesWriteFileOptions");
1292
- function isNodeWriteFileOptions(options) {
1293
- return !isUndefined(options) && (isBufferEncoding(options) || !isPowerlinesWriteFileOptions(options));
1294
- }
1295
- __name(isNodeWriteFileOptions, "isNodeWriteFileOptions");
1296
1053
  function isVirtualFileData(obj) {
1297
1054
  return !!(isSetObject(obj) && "code" in obj && obj.code);
1298
1055
  }
@@ -1429,6 +1186,18 @@ function patchFS(originalFS, vfs) {
1429
1186
  };
1430
1187
  }
1431
1188
  __name(patchFS, "patchFS");
1189
+ function isValidId(id, prefix = "powerlines") {
1190
+ return id.replace(/^\\0/, "").startsWith(`${prefix.replace(/:$/, "")}`);
1191
+ }
1192
+ __name(isValidId, "isValidId");
1193
+ function normalizeId(id, prefix = "powerlines") {
1194
+ return `${prefix.replace(/:$/, "")}:${toFilePath(id).replace(new RegExp(`^${prefix.replace(/:$/, "")}:`), "").replace(/^\\0/, "").replace(findFileDotExtensionSafe(toFilePath(id)), "")}`;
1195
+ }
1196
+ __name(normalizeId, "normalizeId");
1197
+ function normalizePath(path, builtinsPath, prefix = "powerlines") {
1198
+ return isValidId(toFilePath(path), prefix) ? normalizeId(toFilePath(path), prefix).replace(new RegExp(`^${prefix.replace(/:$/, "")}:`), builtinsPath) : toFilePath(path);
1199
+ }
1200
+ __name(normalizePath, "normalizePath");
1432
1201
  var UnifiedFS = class _UnifiedFS extends Union {
1433
1202
  static {
1434
1203
  __name(this, "UnifiedFS");
@@ -1605,9 +1374,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
1605
1374
  */
1606
1375
  #paths;
1607
1376
  /**
1608
- * A map of virtual file paths to their underlying file content.
1377
+ * A cache for module resolution results.
1609
1378
  */
1610
- #cachedResolver = /* @__PURE__ */ new Map();
1379
+ #resolverCache;
1611
1380
  /**
1612
1381
  * The unified volume that combines the virtual file system with the real file system.
1613
1382
  *
@@ -1642,189 +1411,35 @@ var VirtualFileSystem = class _VirtualFileSystem {
1642
1411
  * @returns `true` if the path exists, otherwise `false`.
1643
1412
  */
1644
1413
  #existsSync(path) {
1645
- const formattedPath = this.formatPath(path);
1646
- return this.#unifiedFS.virtual.existsSync(formattedPath) || this.#unifiedFS.physical.existsSync(formattedPath) || this.#unifiedFS.resolveFS(path).existsSync(formattedPath);
1647
- }
1648
- /**
1649
- * Builds a regular expression from a string pattern for path matching.
1650
- *
1651
- * @param strPattern - The string pattern to convert.
1652
- * @returns A regular expression for matching paths.
1653
- */
1654
- #buildRegex(strPattern) {
1655
- const token = "::GLOBSTAR::";
1656
- return new RegExp(`^${this.formatPath(strPattern).replace(/\*\*/g, token).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(token, "g"), ".*")}$`);
1414
+ return this.#unifiedFS.virtual.existsSync(this.#normalizePath(path)) || this.#unifiedFS.physical.existsSync(this.#normalizePath(path)) || this.#unifiedFS.resolveFS(path).existsSync(this.#normalizePath(path));
1657
1415
  }
1658
1416
  /**
1659
- * Formats a file id by removing the file extension and prepending the runtime prefix.
1417
+ * Normalizes a given module id by resolving it against the built-ins path.
1660
1418
  *
1661
- * @param id - The file ID to format.
1662
- * @returns The formatted file ID.
1419
+ * @param id - The module id to normalize.
1420
+ * @returns The normalized module id.
1663
1421
  */
1664
- #formatId(id) {
1665
- const formattedId = toFilePath(id);
1666
- return `${this.#context.config.output.builtinPrefix}:${formattedId.replace(new RegExp(`^${this.#context.config.output.builtinPrefix}:`), "").replace(/^\\0/, "").replace(findFileDotExtensionSafe(formattedId), "")}`;
1667
- }
1668
- /**
1669
- * Resolves an id parameter to a corresponding virtual file path in the virtual file system (VFS).
1670
- *
1671
- * @param id - The id to resolve.
1672
- * @returns The resolved file id if it exists, otherwise undefined.
1673
- */
1674
- #resolveId(id) {
1675
- if (this.#ids[this.#formatId(id)]) {
1676
- return this.#ids[this.#formatId(id)] || false;
1677
- }
1678
- return false;
1679
- }
1680
- /**
1681
- * Resolves a path parameter to a corresponding virtual file path in the virtual file system (VFS).
1682
- *
1683
- * @param path - The path to resolve.
1684
- * @param options - Optional parameters for resolving the path.
1685
- * @returns The resolved file path if it exists, otherwise undefined.
1686
- */
1687
- #resolvePath(path, options = {}) {
1688
- if (isAbsolutePath(path)) {
1689
- if (this.#existsSync(path)) {
1690
- return path;
1691
- }
1692
- const result = this.#checkVariants(path);
1693
- if (result) {
1694
- return result;
1695
- }
1696
- }
1697
- for (const parentPath of this.#resolveParentPaths(path, options.paths)) {
1698
- const request = joinPaths$1(parentPath, path);
1699
- if (this.#existsSync(request)) {
1700
- return request;
1701
- }
1702
- const result = this.#checkVariants(request);
1703
- if (result) {
1704
- return result;
1705
- }
1706
- }
1707
- return false;
1708
- }
1709
- /**
1710
- * Resolves parent paths for a given request.
1711
- *
1712
- * @param request - The request path to resolve parent paths for.
1713
- * @param parents - An optional array of parent paths to consider.
1714
- * @returns An array of resolved parent paths.
1715
- */
1716
- #resolveParentPaths(request, parents = []) {
1717
- let paths = [
1718
- this.#context.workspaceConfig.workspaceRoot,
1719
- joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot)
1720
- ];
1721
- if (this.#context.tsconfig.options.paths) {
1722
- paths = this.#context.tsconfig.options.paths ? Object.keys(this.#context.tsconfig.options.paths).filter((tsconfigPath) => request.startsWith(tsconfigPath.replaceAll("*", ""))).map((tsconfigPath) => this.#context.tsconfig.options.paths?.[tsconfigPath]).flat().reduce((ret, path) => {
1723
- if (path && !ret.includes(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path))) {
1724
- ret.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path));
1725
- }
1726
- return ret;
1727
- }, paths) : paths;
1728
- }
1729
- return paths.reduce((ret, path) => {
1730
- if (!ret.includes(path)) {
1731
- ret.push(path);
1732
- }
1733
- return ret;
1734
- }, parents.filter(Boolean).map((p) => this.formatPath(p)));
1422
+ #normalizeId(id) {
1423
+ return normalizeId(id, this.#context.config.output.builtinPrefix);
1735
1424
  }
1736
1425
  /**
1737
- * Clears the resolver cache for a given path.
1426
+ * Normalizes a given path by resolving it against the project root, workspace root, and built-ins path.
1738
1427
  *
1739
- * @param path - The path to clear the resolver cache for.
1428
+ * @param path - The path to normalize.
1429
+ * @returns The normalized path.
1740
1430
  */
1741
- #clearResolverCache(path) {
1742
- this.#cachedResolver.keys().filter((key) => key.startsWith(toFilePath(path))).forEach((key) => this.#cachedResolver.delete(key));
1431
+ #normalizePath(path) {
1432
+ return normalizePath(path, this.#context.builtinsPath, this.#context.config.output.builtinPrefix);
1743
1433
  }
1744
1434
  /**
1745
- * Check if the file exists with different variants (index, extensions).
1746
- *
1747
- * @param request - The request path to check.
1748
- * @param parentPath - An optional parent path to prepend to the request.
1749
- * @returns The file path if it exists, otherwise false.
1750
- */
1751
- #checkVariants(request, parentPath) {
1752
- const path = parentPath ? joinPaths$1(parentPath, request) : request;
1753
- let file = this.#checkExtensions(path);
1754
- if (file) {
1755
- return file;
1756
- }
1757
- file = this.#checkIndex(path);
1758
- if (file) {
1759
- return file;
1760
- }
1761
- return false;
1762
- }
1763
- /**
1764
- * Check if the index file exists in the given request path.
1765
- *
1766
- * @param request - The request path to check.
1767
- * @returns The index file path if it exists, otherwise false.
1768
- */
1769
- #checkIndex(request) {
1770
- let file = joinPaths$1(request, "index");
1771
- if (this.#existsSync(file)) {
1772
- return file;
1773
- }
1774
- file = this.#checkExtensions(file);
1775
- if (file) {
1776
- return file;
1777
- }
1778
- return false;
1779
- }
1780
- /**
1781
- * Check if the file exists with different extensions.
1435
+ * Builds a regular expression from a string pattern for path matching.
1782
1436
  *
1783
- * @param request - The request path to check.
1784
- * @returns The file path if it exists with any of the checked extensions, otherwise false.
1437
+ * @param path - The string pattern to convert.
1438
+ * @returns A regular expression for matching paths.
1785
1439
  */
1786
- #checkExtensions(request) {
1787
- let file = `${request}.ts`;
1788
- if (this.#existsSync(file)) {
1789
- return file;
1790
- }
1791
- file = `${request}.mts`;
1792
- if (this.#existsSync(file)) {
1793
- return file;
1794
- }
1795
- file = `${request}.cts`;
1796
- if (this.#existsSync(file)) {
1797
- return file;
1798
- }
1799
- file = `${request}.tsx`;
1800
- if (this.#existsSync(file)) {
1801
- return file;
1802
- }
1803
- file = `${request}.js`;
1804
- if (this.#existsSync(file)) {
1805
- return file;
1806
- }
1807
- file = `${request}.mjs`;
1808
- if (this.#existsSync(file)) {
1809
- return file;
1810
- }
1811
- file = `${request}.cjs`;
1812
- if (this.#existsSync(file)) {
1813
- return file;
1814
- }
1815
- file = `${request}.jsx`;
1816
- if (this.#existsSync(file)) {
1817
- return file;
1818
- }
1819
- file = `${request}.json`;
1820
- if (this.#existsSync(file)) {
1821
- return file;
1822
- }
1823
- file = `${request}.d.ts`;
1824
- if (this.#existsSync(file)) {
1825
- return file;
1826
- }
1827
- return false;
1440
+ #buildRegex(path) {
1441
+ const token = "::GLOBSTAR::";
1442
+ return new RegExp(`^${this.#normalizePath(path).replace(/\*\*/g, token).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(token, "g"), ".*")}$`);
1828
1443
  }
1829
1444
  /**
1830
1445
  * Creates a virtual file system (VFS) that is backed up to a Cap'n Proto message buffer.
@@ -1833,8 +1448,8 @@ var VirtualFileSystem = class _VirtualFileSystem {
1833
1448
  * @returns A promise that resolves to a new virtual file system instance.
1834
1449
  */
1835
1450
  static async create(context) {
1836
- if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1837
- const buffer = await readFileBuffer(joinPaths$1(context.cachePath, "fs.bin"));
1451
+ if (!context.config.skipCache && existsSync(joinPaths$1(context.dataPath, "fs.bin"))) {
1452
+ const buffer = await readFileBuffer(joinPaths$1(context.dataPath, "fs.bin"));
1838
1453
  const message2 = new $.Message(buffer, false);
1839
1454
  return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1840
1455
  }
@@ -1848,8 +1463,8 @@ var VirtualFileSystem = class _VirtualFileSystem {
1848
1463
  * @returns A new virtual file system instance.
1849
1464
  */
1850
1465
  static createSync(context) {
1851
- if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1852
- const buffer = readFileBufferSync(joinPaths$1(context.cachePath, "fs.bin"));
1466
+ if (!context.config.skipCache && existsSync(joinPaths$1(context.dataPath, "fs.bin"))) {
1467
+ const buffer = readFileBufferSync(joinPaths$1(context.dataPath, "fs.bin"));
1853
1468
  const message2 = new $.Message(buffer, false);
1854
1469
  return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1855
1470
  }
@@ -1860,19 +1475,43 @@ var VirtualFileSystem = class _VirtualFileSystem {
1860
1475
  * A map of file ids to their metadata.
1861
1476
  */
1862
1477
  get metadata() {
1863
- return this.#metadata;
1478
+ return new Proxy(this.#metadata, {
1479
+ get: /* @__PURE__ */ __name((target, prop) => {
1480
+ return target[this.#normalizeId(prop)];
1481
+ }, "get")
1482
+ });
1864
1483
  }
1865
1484
  /**
1866
- * A map of module ids to their file paths.
1485
+ * A map of file paths to their module ids.
1867
1486
  */
1868
1487
  get ids() {
1869
- return this.#ids;
1488
+ return new Proxy(this.#paths, {
1489
+ get: /* @__PURE__ */ __name((target, prop) => {
1490
+ return target[this.#normalizePath(prop)];
1491
+ }, "get")
1492
+ });
1870
1493
  }
1871
1494
  /**
1872
- * A map of virtual file paths to their IDs.
1495
+ * A map of module ids to their file paths.
1873
1496
  */
1874
1497
  get paths() {
1875
- return this.#paths;
1498
+ return new Proxy(this.#paths, {
1499
+ get: /* @__PURE__ */ __name((target, prop) => {
1500
+ return target[this.#normalizeId(prop)];
1501
+ }, "get")
1502
+ });
1503
+ }
1504
+ get resolverCache() {
1505
+ if (!this.#resolverCache) {
1506
+ this.#resolverCache = create({
1507
+ cacheId: "module-resolution",
1508
+ cacheDir: this.#context.cachePath,
1509
+ ttl: 60 * 60 * 1e3,
1510
+ lruSize: 5e3,
1511
+ persistInterval: 100
1512
+ });
1513
+ }
1514
+ return this.#resolverCache;
1876
1515
  }
1877
1516
  /**
1878
1517
  * Creates a new instance of the {@link VirtualFileSystem}.
@@ -1917,17 +1556,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1917
1556
  * Check if a path or id corresponds to a virtual file **(does not actually exists on disk)**.
1918
1557
  *
1919
1558
  * @param pathOrId - The path or id to check.
1920
- * @param options - Optional parameters for resolving the path.
1921
1559
  * @returns Whether the path or id corresponds to a virtual file **(does not actually exists on disk)**.
1922
1560
  */
1923
- isVirtual(pathOrId, options = {}) {
1561
+ isVirtual(pathOrId, importer, options = {}) {
1924
1562
  if (!pathOrId) {
1925
1563
  return false;
1926
1564
  }
1927
- const resolvedPath = this.resolve(pathOrId, {
1928
- ...options,
1929
- pathType: "file"
1930
- });
1565
+ const resolvedPath = this.resolveSync(pathOrId, importer, options);
1931
1566
  if (!resolvedPath) {
1932
1567
  return false;
1933
1568
  }
@@ -1937,17 +1572,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1937
1572
  * Check if a path or id corresponds to a file written to the file system **(actually exists on disk)**.
1938
1573
  *
1939
1574
  * @param pathOrId - The path or id to check.
1940
- * @param options - Optional parameters for resolving the path.
1941
1575
  * @returns Whether the path or id corresponds to a file written to the file system **(actually exists on disk)**.
1942
1576
  */
1943
- isPhysical(pathOrId, options = {}) {
1577
+ isPhysical(pathOrId, importer, options = {}) {
1944
1578
  if (!pathOrId) {
1945
1579
  return false;
1946
1580
  }
1947
- const resolvedPath = this.resolve(pathOrId, {
1948
- ...options,
1949
- pathType: "file"
1950
- });
1581
+ const resolvedPath = this.resolveSync(pathOrId, importer, options);
1951
1582
  if (!resolvedPath) {
1952
1583
  return false;
1953
1584
  }
@@ -1969,16 +1600,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
1969
1600
  * @param path - The path to create the directory at.
1970
1601
  */
1971
1602
  unlinkSync(path, options) {
1972
- const formattedPath = toFilePath(path);
1973
- if (!this.isFile(formattedPath)) {
1603
+ if (!this.isFile(this.#normalizePath(path))) {
1974
1604
  return;
1975
1605
  }
1976
- this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${formattedPath}`);
1977
- this.#unifiedFS.resolveFS(path, options).unlinkSync(formattedPath);
1978
- if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1979
- delete this.metadata[this.paths[formattedPath]];
1606
+ this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${this.#normalizePath(path)}`);
1607
+ this.#unifiedFS.resolveFS(path, options).unlinkSync(this.#normalizePath(path));
1608
+ if (this.#ids[this.#normalizePath(path)] && this.#metadata[this.#ids[this.#normalizePath(path)]]) {
1609
+ delete this.#metadata[this.#ids[this.#normalizePath(path)]];
1610
+ delete this.#ids[this.#normalizePath(path)];
1611
+ delete this.#paths[this.#normalizeId(path)];
1612
+ this.#resolverCache.delete(this.#normalizePath(path));
1980
1613
  }
1981
- this.#clearResolverCache(formattedPath);
1982
1614
  }
1983
1615
  /**
1984
1616
  * Removes a file in the virtual file system (VFS).
@@ -1986,19 +1618,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
1986
1618
  * @param path - The path to create the directory at.
1987
1619
  */
1988
1620
  async unlink(path, options) {
1989
- const formattedPath = toFilePath(path);
1990
- if (!this.isFile(formattedPath)) {
1621
+ if (!this.isFile(this.#normalizePath(path))) {
1991
1622
  return;
1992
1623
  }
1993
- this.#log(LogLevelLabel.TRACE, `Removing file: ${formattedPath}`);
1624
+ this.#log(LogLevelLabel.TRACE, `Removing file: ${this.#normalizePath(path)}`);
1994
1625
  if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.unlink)) {
1995
- await this.#unifiedFS.resolveFS(path, options).promises.unlink(formattedPath);
1996
- if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1997
- delete this.metadata[this.paths[formattedPath]];
1626
+ await this.#unifiedFS.resolveFS(path, options).promises.unlink(this.#normalizePath(path));
1627
+ if (this.#ids[this.#normalizePath(path)] && this.#metadata[this.#ids[this.#normalizePath(path)]]) {
1628
+ delete this.#metadata[this.#ids[this.#normalizePath(path)]];
1998
1629
  }
1999
- this.#clearResolverCache(formattedPath);
2000
1630
  } else {
2001
- this.unlinkSync(formattedPath, options);
1631
+ this.unlinkSync(this.#normalizePath(path), options);
2002
1632
  }
2003
1633
  }
2004
1634
  /**
@@ -2008,15 +1638,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
2008
1638
  * @param options - Options for creating the directory.
2009
1639
  */
2010
1640
  rmdirSync(path, options = {}) {
2011
- const formattedPath = toFilePath(path);
2012
- if (!this.isDirectory(formattedPath)) {
1641
+ if (!this.isDirectory(this.#normalizePath(path))) {
2013
1642
  return;
2014
1643
  }
2015
- this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${formattedPath}`);
2016
- this.#unifiedFS.resolveFS(path, options).rmdirSync(formattedPath, defu5(options, {
1644
+ this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${this.#normalizePath(path)}`);
1645
+ this.#unifiedFS.resolveFS(path, options).rmdirSync(this.#normalizePath(path), defu5(options, {
2017
1646
  recursive: true
2018
1647
  }));
2019
- this.#clearResolverCache(formattedPath);
2020
1648
  }
2021
1649
  /**
2022
1650
  * Removes a directory in the virtual file system (VFS).
@@ -2026,19 +1654,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
2026
1654
  * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
2027
1655
  */
2028
1656
  async rmdir(path, options = {}) {
2029
- const formattedPath = toFilePath(path);
2030
- if (!this.isDirectory(formattedPath)) {
1657
+ if (!this.isDirectory(this.#normalizePath(path))) {
2031
1658
  return;
2032
1659
  }
2033
- this.#log(LogLevelLabel.TRACE, `Removing directory: ${formattedPath}`);
1660
+ this.#log(LogLevelLabel.TRACE, `Removing directory: ${this.#normalizePath(path)}`);
2034
1661
  if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.rm)) {
2035
- await this.#unifiedFS.resolveFS(path, options).promises.rm(formattedPath, defu5(options, {
1662
+ await this.#unifiedFS.resolveFS(path, options).promises.rm(this.#normalizePath(path), defu5(options, {
2036
1663
  force: true,
2037
1664
  recursive: true
2038
1665
  }));
2039
- this.#clearResolverCache(formattedPath);
2040
1666
  } else {
2041
- this.rmdirSync(formattedPath, defu5(options ?? {}, {
1667
+ this.rmdirSync(this.#normalizePath(path), defu5(options ?? {}, {
2042
1668
  force: true,
2043
1669
  recursive: true
2044
1670
  }));
@@ -2052,11 +1678,11 @@ var VirtualFileSystem = class _VirtualFileSystem {
2052
1678
  * @returns A promise that resolves when the file is removed.
2053
1679
  */
2054
1680
  async rm(path, options = {}) {
2055
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
2056
- if (this.isDirectory(path)) {
2057
- return this.rmdir(path, options);
1681
+ this.#log(LogLevelLabel.TRACE, `Removing: ${this.#normalizePath(path)}`);
1682
+ if (this.isDirectory(this.#normalizePath(path))) {
1683
+ return this.rmdir(this.#normalizePath(path), options);
2058
1684
  }
2059
- return this.unlink(path, options);
1685
+ return this.unlink(this.#normalizePath(path), options);
2060
1686
  }
2061
1687
  /**
2062
1688
  * Synchronously removes a file or directory in the virtual file system (VFS).
@@ -2065,11 +1691,11 @@ var VirtualFileSystem = class _VirtualFileSystem {
2065
1691
  * @param options - Options for removing the file or directory.
2066
1692
  */
2067
1693
  rmSync(path, options = {}) {
2068
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
2069
- if (this.isDirectory(path)) {
2070
- return this.rmdirSync(path, options);
1694
+ this.#log(LogLevelLabel.TRACE, `Removing: ${this.#normalizePath(path)}`);
1695
+ if (this.isDirectory(this.#normalizePath(path))) {
1696
+ return this.rmdirSync(this.#normalizePath(path), options);
2071
1697
  }
2072
- return this.unlinkSync(path, options);
1698
+ return this.unlinkSync(this.#normalizePath(path), options);
2073
1699
  }
2074
1700
  /**
2075
1701
  * Creates a directory in the virtual file system (VFS).
@@ -2079,9 +1705,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2079
1705
  * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
2080
1706
  */
2081
1707
  mkdirSync(path, options = {}) {
2082
- const filePath = toFilePath(path);
2083
- this.#clearResolverCache(filePath);
2084
- return this.#unifiedFS.resolveFS(filePath, options).mkdirSync(filePath, defu5(options ?? {}, {
1708
+ return this.#unifiedFS.resolveFS(this.#normalizePath(path), options).mkdirSync(this.#normalizePath(path), defu5(omit(options, [
1709
+ "mode"
1710
+ ]), {
2085
1711
  recursive: true
2086
1712
  }));
2087
1713
  }
@@ -2094,17 +1720,19 @@ var VirtualFileSystem = class _VirtualFileSystem {
2094
1720
  */
2095
1721
  async mkdir(path, options = {}) {
2096
1722
  let result;
2097
- const filePath = toFilePath(path);
2098
- if (isFunction(this.#unifiedFS.resolveFS(filePath, options).promises.mkdir)) {
2099
- result = await this.#unifiedFS.resolveFS(filePath, options).promises.mkdir(filePath, defu5(options ?? {}, {
1723
+ if (isFunction(this.#unifiedFS.resolveFS(this.#normalizePath(path), options).promises.mkdir)) {
1724
+ result = await this.#unifiedFS.resolveFS(this.#normalizePath(path), options).promises.mkdir(this.#normalizePath(path), defu5(omit(options, [
1725
+ "mode"
1726
+ ]), {
2100
1727
  recursive: true
2101
1728
  }));
2102
1729
  } else {
2103
- result = this.#unifiedFS.resolveFS(filePath, options).mkdirSync(filePath, defu5(options ?? {}, {
1730
+ result = this.#unifiedFS.resolveFS(this.#normalizePath(path), options).mkdirSync(this.#normalizePath(path), defu5(omit(options, [
1731
+ "mode"
1732
+ ]), {
2104
1733
  recursive: true
2105
1734
  }));
2106
1735
  }
2107
- this.#clearResolverCache(filePath);
2108
1736
  return result;
2109
1737
  }
2110
1738
  /**
@@ -2116,17 +1744,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2116
1744
  async glob(patterns) {
2117
1745
  const results = [];
2118
1746
  for (const pattern of toArray(patterns)) {
2119
- const normalized = this.formatPath(pattern);
1747
+ const normalized = this.#normalizePath(pattern);
2120
1748
  if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
2121
- const resolved = this.resolve(normalized, {
2122
- pathType: "file"
2123
- });
1749
+ const resolved = this.resolveSync(normalized);
2124
1750
  if (resolved && !results.includes(resolved)) {
2125
1751
  results.push(resolved);
2126
1752
  }
2127
1753
  continue;
2128
1754
  }
2129
- const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1755
+ const absPattern = isAbsolutePath(normalized) ? normalized : this.#normalizePath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
2130
1756
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
2131
1757
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
2132
1758
  const stack = [
@@ -2141,7 +1767,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2141
1767
  continue;
2142
1768
  }
2143
1769
  for (const entry of entries) {
2144
- const full = this.formatPath(joinPaths$1(dir, entry));
1770
+ const full = this.#normalizePath(joinPaths$1(dir, entry));
2145
1771
  let stats;
2146
1772
  try {
2147
1773
  stats = this.#unifiedFS.lstatSync(full);
@@ -2153,9 +1779,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2153
1779
  stack.push(full);
2154
1780
  } else if (stats.isFile()) {
2155
1781
  if (this.#buildRegex(absPattern).test(full)) {
2156
- const resolved = this.resolve(full, {
2157
- pathType: "file"
2158
- });
1782
+ const resolved = this.resolveSync(full);
2159
1783
  if (resolved && !results.includes(resolved)) {
2160
1784
  results.push(resolved);
2161
1785
  }
@@ -2175,17 +1799,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2175
1799
  globSync(patterns) {
2176
1800
  const results = [];
2177
1801
  for (const pattern of toArray(patterns)) {
2178
- const normalized = this.formatPath(pattern);
1802
+ const normalized = this.#normalizePath(pattern);
2179
1803
  if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
2180
- const resolved = this.resolve(normalized, {
2181
- pathType: "file"
2182
- });
1804
+ const resolved = this.resolveSync(normalized);
2183
1805
  if (resolved && !results.includes(resolved)) {
2184
1806
  results.push(resolved);
2185
1807
  }
2186
1808
  continue;
2187
1809
  }
2188
- const absPattern = isAbsolutePath(normalized) ? normalized : this.formatPath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
1810
+ const absPattern = isAbsolutePath(normalized) ? normalized : this.#normalizePath(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, normalized));
2189
1811
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
2190
1812
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
2191
1813
  const stack = [
@@ -2200,7 +1822,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2200
1822
  continue;
2201
1823
  }
2202
1824
  for (const entry of entries) {
2203
- const full = this.formatPath(joinPaths$1(dir, entry));
1825
+ const full = this.#normalizePath(joinPaths$1(dir, entry));
2204
1826
  let stats;
2205
1827
  try {
2206
1828
  stats = this.#unifiedFS.lstatSync(full);
@@ -2212,9 +1834,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2212
1834
  stack.push(full);
2213
1835
  } else if (stats.isFile()) {
2214
1836
  if (this.#buildRegex(absPattern).test(full)) {
2215
- const resolved = this.resolve(full, {
2216
- pathType: "file"
2217
- });
1837
+ const resolved = this.resolveSync(full);
2218
1838
  if (resolved && !results.includes(resolved)) {
2219
1839
  results.push(resolved);
2220
1840
  }
@@ -2284,21 +1904,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2284
1904
  * @returns A promise that resolves to the contents of the file as a string, or undefined if the file does not exist.
2285
1905
  */
2286
1906
  async readFile(pathOrId, options = "utf8") {
2287
- if (!pathOrId) {
2288
- return void 0;
2289
- }
2290
- const filePath = this.resolve(toFilePath(pathOrId), {
2291
- pathType: "file"
2292
- });
2293
- if (filePath) {
1907
+ const filePath = await this.resolve(pathOrId);
1908
+ if (filePath && this.isFile(filePath)) {
2294
1909
  let result;
2295
1910
  if (isFunction(this.#unifiedFS.resolveFS(filePath).promises.readFile)) {
2296
1911
  result = (await this.#unifiedFS.resolveFS(filePath).promises.readFile(filePath, options))?.toString("utf8");
2297
1912
  } else {
2298
1913
  result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
2299
1914
  }
2300
- const content = isBuffer(result) ? bufferToString(result) : result;
2301
- return content;
1915
+ return isBuffer(result) ? bufferToString(result) : result;
2302
1916
  }
2303
1917
  return void 0;
2304
1918
  }
@@ -2309,16 +1923,10 @@ var VirtualFileSystem = class _VirtualFileSystem {
2309
1923
  * @returns The contents of the file as a string, or undefined if the file does not exist.
2310
1924
  */
2311
1925
  readFileSync(pathOrId, options = "utf8") {
2312
- if (!pathOrId) {
2313
- return void 0;
2314
- }
2315
- const filePath = this.resolve(toFilePath(pathOrId), {
2316
- pathType: "file"
2317
- });
2318
- if (filePath) {
1926
+ const filePath = this.resolveSync(pathOrId);
1927
+ if (filePath && this.isFile(filePath)) {
2319
1928
  const result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
2320
- const content = isBuffer(result) ? bufferToString(result) : result;
2321
- return content;
1929
+ return isBuffer(result) ? bufferToString(result) : result;
2322
1930
  }
2323
1931
  return void 0;
2324
1932
  }
@@ -2331,34 +1939,40 @@ var VirtualFileSystem = class _VirtualFileSystem {
2331
1939
  * @returns A promise that resolves when the file is written.
2332
1940
  */
2333
1941
  async writeFile(path, data = "", options = "utf8") {
2334
- const formattedPath = this.formatPath(path);
2335
- if (!this.isDirectory(findFilePath(formattedPath))) {
2336
- await this.mkdir(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
1942
+ if (!this.isDirectory(findFilePath(this.#normalizePath(path)))) {
1943
+ await this.mkdir(findFilePath(this.#normalizePath(path)), isPowerlinesWriteFileOptions(options) ? options : void 0);
2337
1944
  }
2338
- let code = isVirtualFileData(data) ? data.code : data;
1945
+ const metadata = isVirtualFileData(data) ? data : {};
1946
+ metadata.id = this.#normalizeId(path);
1947
+ let code = isVirtualFileData(data) ? metadata.code : data;
2339
1948
  if ((!isPowerlinesWriteFileOptions(options) || !options.skipFormat) && isSetString(code)) {
2340
- const resolvedConfig = await resolveConfig(formattedPath);
1949
+ const resolvedConfig = await resolveConfig(this.#normalizePath(path));
2341
1950
  if (resolvedConfig) {
2342
1951
  code = await format(code, {
2343
- absolutePath: formattedPath,
1952
+ absolutePath: this.#normalizePath(path),
2344
1953
  ...resolvedConfig
2345
1954
  });
2346
1955
  }
2347
1956
  }
2348
- const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
2349
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
2350
- this.metadata[formattedPath] = {
1957
+ const outputMode = this.#unifiedFS.resolveMode(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
1958
+ this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1959
+ this.#metadata[metadata.id] = {
2351
1960
  mode: outputMode,
2352
1961
  variant: "normal",
2353
1962
  timestamp: Date.now(),
2354
- ...isVirtualFileData(data) ? data : {}
1963
+ ...metadata
2355
1964
  };
2356
- this.#clearResolverCache(formattedPath);
2357
- const ifs = this.#unifiedFS.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
1965
+ this.#paths[metadata.id] = this.#normalizePath(path);
1966
+ this.#ids[this.#normalizePath(path)] = metadata.id;
1967
+ const ifs = this.#unifiedFS.resolveFS(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
2358
1968
  if (isFunction(ifs.promises.writeFile)) {
2359
- return ifs.promises.writeFile(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1969
+ return ifs.promises.writeFile(this.#normalizePath(path), code, isSetObject(options) ? omit(options, [
1970
+ "mode"
1971
+ ]) : "utf8");
2360
1972
  }
2361
- return ifs.writeFileSync(formattedPath, code, isNodeWriteFileOptions(options) ? options : "utf8");
1973
+ return ifs.writeFileSync(this.#normalizePath(path), code, isSetObject(options) ? omit(options, [
1974
+ "mode"
1975
+ ]) : "utf8");
2362
1976
  }
2363
1977
  /**
2364
1978
  * Synchronously writes a file to the virtual file system (VFS).
@@ -2368,21 +1982,23 @@ var VirtualFileSystem = class _VirtualFileSystem {
2368
1982
  * @param options - Optional parameters for writing the file.
2369
1983
  */
2370
1984
  writeFileSync(path, data = "", options = "utf8") {
2371
- const formattedPath = this.formatPath(path);
2372
- if (!this.isDirectory(findFilePath(formattedPath))) {
2373
- this.mkdirSync(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
2374
- }
2375
- const code = isVirtualFileData(data) ? data.code : data;
2376
- const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
2377
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
2378
- this.metadata[formattedPath] = {
1985
+ if (!this.isDirectory(findFilePath(this.#normalizePath(path)))) {
1986
+ this.mkdirSync(findFilePath(this.#normalizePath(path)), isPowerlinesWriteFileOptions(options) ? options : void 0);
1987
+ }
1988
+ const metadata = isVirtualFileData(data) ? data : {};
1989
+ metadata.id = this.#normalizeId(path);
1990
+ const code = isVirtualFileData(data) ? metadata.code : data;
1991
+ const outputMode = this.#unifiedFS.resolveMode(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0);
1992
+ this.#log(LogLevelLabel.TRACE, `Writing ${this.#normalizePath(path)} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
1993
+ this.#metadata[metadata.id] = {
2379
1994
  mode: outputMode,
2380
1995
  variant: "normal",
2381
1996
  timestamp: Date.now(),
2382
- ...isVirtualFileData(data) ? data : {}
1997
+ ...metadata
2383
1998
  };
2384
- this.#clearResolverCache(formattedPath);
2385
- const writeStream = this.#unifiedFS.resolveFS(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0).createWriteStream(formattedPath);
1999
+ this.#paths[metadata.id] = this.#normalizePath(path);
2000
+ this.#ids[this.#normalizePath(path)] = metadata.id;
2001
+ const writeStream = this.#unifiedFS.resolveFS(this.#normalizePath(path), isPowerlinesWriteFileOptions(options) ? options : void 0).createWriteStream(this.#normalizePath(path));
2386
2002
  try {
2387
2003
  writeStream.write(code);
2388
2004
  } finally {
@@ -2396,7 +2012,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2396
2012
  * @returns `true` if the file exists, otherwise `false`.
2397
2013
  */
2398
2014
  existsSync(pathOrId) {
2399
- return this.resolve(pathOrId) !== false;
2015
+ return !!this.resolveSync(pathOrId);
2400
2016
  }
2401
2017
  /**
2402
2018
  * Retrieves the metadata of a file in the virtual file system (VFS).
@@ -2405,7 +2021,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2405
2021
  * @returns The metadata of the file, or undefined if the file does not exist.
2406
2022
  */
2407
2023
  getMetadata(pathOrId) {
2408
- const resolved = this.resolve(pathOrId);
2024
+ const resolved = this.resolveSync(pathOrId);
2409
2025
  if (resolved && this.metadata[resolved]) {
2410
2026
  return this.metadata[resolved];
2411
2027
  }
@@ -2421,7 +2037,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2421
2037
  * @returns `true` if the file exists, otherwise `false`.
2422
2038
  */
2423
2039
  isFile(pathOrId) {
2424
- const resolved = this.resolve(pathOrId);
2040
+ const resolved = this.resolveSync(pathOrId);
2425
2041
  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()));
2426
2042
  }
2427
2043
  /**
@@ -2431,7 +2047,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2431
2047
  * @returns `true` if the directory exists, otherwise `false`.
2432
2048
  */
2433
2049
  isDirectory(pathOrId) {
2434
- const resolved = this.resolve(pathOrId);
2050
+ const resolved = this.resolveSync(pathOrId);
2435
2051
  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()));
2436
2052
  }
2437
2053
  /**
@@ -2441,7 +2057,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2441
2057
  * @returns A promise that resolves to the file's status information, or false if the file does not exist.
2442
2058
  */
2443
2059
  async stat(pathOrId, options) {
2444
- return this.#unifiedFS.resolveFS(pathOrId).promises.stat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
2060
+ return this.#unifiedFS.resolveFS(pathOrId).promises.stat(await this.resolve(pathOrId) || pathOrId, options);
2445
2061
  }
2446
2062
  /**
2447
2063
  * Synchronously retrieves the status of a file in the virtual file system (VFS).
@@ -2450,7 +2066,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2450
2066
  * @returns The file's status information, or false if the file does not exist.
2451
2067
  */
2452
2068
  statSync(pathOrId) {
2453
- return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId));
2069
+ return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolveSync(pathOrId) || pathOrId);
2454
2070
  }
2455
2071
  /**
2456
2072
  * Retrieves the status of a symbolic link in the virtual file system (VFS).
@@ -2459,7 +2075,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2459
2075
  * @returns A promise that resolves to the symbolic link's status information, or false if the link does not exist.
2460
2076
  */
2461
2077
  async lstat(pathOrId, options) {
2462
- return this.#unifiedFS.resolveFS(pathOrId).promises.lstat(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
2078
+ return this.#unifiedFS.resolveFS(pathOrId).promises.lstat(await this.resolve(pathOrId) || pathOrId, options);
2463
2079
  }
2464
2080
  /**
2465
2081
  * Synchronously retrieves the status of a symbolic link in the virtual file system (VFS).
@@ -2468,7 +2084,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2468
2084
  * @returns The symbolic link's status information, or false if the link does not exist.
2469
2085
  */
2470
2086
  lstatSync(pathOrId, options) {
2471
- return this.#unifiedFS.resolveFS(pathOrId).lstatSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId), options);
2087
+ return this.#unifiedFS.resolveFS(pathOrId).lstatSync(this.resolveSync(pathOrId) || pathOrId, options);
2472
2088
  }
2473
2089
  /**
2474
2090
  * Resolves a path or ID to its real path in the virtual file system (VFS).
@@ -2477,52 +2093,113 @@ var VirtualFileSystem = class _VirtualFileSystem {
2477
2093
  * @returns The resolved real path if it exists, otherwise undefined.
2478
2094
  */
2479
2095
  realpathSync(pathOrId) {
2480
- const filePath = this.resolve(toFilePath(pathOrId));
2096
+ const filePath = this.resolveSync(pathOrId);
2481
2097
  if (!filePath) {
2482
- throw new Error(`File not found: ${toFilePath(pathOrId)}`);
2098
+ throw new Error(`File not found: ${pathOrId}`);
2483
2099
  }
2484
2100
  return filePath;
2485
2101
  }
2486
2102
  /**
2487
- * Resolves a path or ID parameter to a corresponding virtual file path in the virtual file system (VFS).
2103
+ * A helper function to resolve modules in the virtual file system (VFS).
2488
2104
  *
2489
- * @param pathOrId - The path or ID to resolve.
2490
- * @param options - Optional parameters for resolving the path, such as whether to include the file extension.
2491
- * @returns The resolved file path if it exists, otherwise undefined.
2492
- */
2493
- resolve(pathOrId, options = {}) {
2494
- const formattedPathOrId = toFilePath(pathOrId);
2495
- const resolverKey = `${formattedPathOrId}${options.withExtension ? "-ext" : ""}${options.paths ? `-${murmurhash(options.paths)}` : ""}${options.pathType ? `-${options.pathType}` : ""}`;
2496
- if (this.#cachedResolver.has(resolverKey)) {
2497
- return this.#cachedResolver.get(resolverKey);
2498
- }
2499
- let result = this.#resolveId(formattedPathOrId);
2500
- if (!result) {
2501
- result = this.#resolvePath(formattedPathOrId, options);
2105
+ * @remarks
2106
+ * This function can be used to resolve modules relative to the project root directory.
2107
+ *
2108
+ * @example
2109
+ * ```ts
2110
+ * const resolved = await context.resolvePath("some-module", "/path/to/importer");
2111
+ * ```
2112
+ *
2113
+ * @param id - The module to resolve.
2114
+ * @param importer - An optional path to the importer module.
2115
+ * @param options - Additional resolution options.
2116
+ * @returns A promise that resolves to the resolved module path.
2117
+ */
2118
+ async resolve(id, importer, options = {}) {
2119
+ let result = this.resolverCache.get(this.#normalizeId(id));
2120
+ if (result) {
2121
+ return result;
2502
2122
  }
2123
+ result = this.paths[this.#normalizeId(id)];
2503
2124
  if (!result) {
2504
- result = false;
2125
+ const paths = options.paths ?? [];
2126
+ if (importer && !paths.includes(importer)) {
2127
+ paths.push(importer);
2128
+ }
2129
+ paths.push(this.#context.workspaceConfig.workspaceRoot);
2130
+ paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot));
2131
+ paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.sourceRoot));
2132
+ 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)));
2133
+ for (const combination of getResolutionCombinations(id, {
2134
+ paths
2135
+ })) {
2136
+ if (this.#existsSync(combination)) {
2137
+ result = combination;
2138
+ }
2139
+ }
2140
+ try {
2141
+ result = await resolve(id, {
2142
+ paths
2143
+ });
2144
+ } catch {
2145
+ }
2505
2146
  }
2506
- if (result && options.withExtension === false) {
2507
- return result.replace(/\.[m|c]?[t|j]sx?$/, "");
2147
+ if (result) {
2148
+ result = toAbsolutePath(appendPath(result, this.#context.config.projectRoot), this.#context.workspaceConfig.workspaceRoot);
2149
+ this.resolverCache.set(this.#normalizeId(id), result);
2508
2150
  }
2509
- this.#cachedResolver.set(resolverKey, result);
2510
2151
  return result;
2511
2152
  }
2512
2153
  /**
2513
- * Converts a relative path to an absolute path based on the workspace and project root.
2154
+ * A synchronous helper function to resolve modules using the Jiti resolver
2155
+ *
2156
+ * @remarks
2157
+ * This function can be used to resolve modules relative to the project root directory.
2514
2158
  *
2515
- * @param path - The relative path to convert.
2516
- * @returns The absolute path.
2517
- */
2518
- formatPath(path) {
2519
- const formattedPath = toFilePath(path);
2520
- if (isAbsolutePath(formattedPath) || formattedPath.startsWith(this.#context.workspaceConfig.workspaceRoot)) {
2521
- return formattedPath;
2522
- } else if (formattedPath.startsWith(this.#context.config.projectRoot)) {
2523
- return joinPaths$1(this.#context.workspaceConfig.workspaceRoot, formattedPath);
2159
+ * @example
2160
+ * ```ts
2161
+ * const resolvedPath = context.resolveSync("some-module", "/path/to/importer");
2162
+ * ```
2163
+ *
2164
+ * @param id - The module to resolve.
2165
+ * @param importer - An optional path to the importer module.
2166
+ * @param options - Additional resolution options.
2167
+ * @returns The resolved module path.
2168
+ */
2169
+ resolveSync(id, importer, options = {}) {
2170
+ let result = this.resolverCache.get(this.#normalizeId(id));
2171
+ if (result) {
2172
+ return result;
2173
+ }
2174
+ result = this.paths[this.#normalizeId(id)];
2175
+ if (!result) {
2176
+ const paths = options.paths ?? [];
2177
+ if (importer && !paths.includes(importer)) {
2178
+ paths.push(importer);
2179
+ }
2180
+ paths.push(this.#context.workspaceConfig.workspaceRoot);
2181
+ paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot));
2182
+ paths.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.sourceRoot));
2183
+ 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)));
2184
+ for (const combination of getResolutionCombinations(id, {
2185
+ paths
2186
+ })) {
2187
+ if (this.#existsSync(combination)) {
2188
+ result = combination;
2189
+ }
2190
+ }
2191
+ try {
2192
+ result = resolveSync(id, {
2193
+ paths
2194
+ });
2195
+ } catch {
2196
+ }
2524
2197
  }
2525
- return formattedPath;
2198
+ if (result) {
2199
+ result = toAbsolutePath(appendPath(result, this.#context.config.projectRoot), this.#context.workspaceConfig.workspaceRoot);
2200
+ this.resolverCache.set(this.#normalizeId(id), result);
2201
+ }
2202
+ return result;
2526
2203
  }
2527
2204
  /**
2528
2205
  * Disposes of the virtual file system (VFS) by saving its state to disk.
@@ -2531,7 +2208,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2531
2208
  if (!this.#isDisposed) {
2532
2209
  this.#isDisposed = true;
2533
2210
  this.#log(LogLevelLabel.DEBUG, "Disposing virtual file system...");
2534
- await this.unlink(joinPaths$1(this.#context.cachePath, "fs.bin"));
2211
+ await this.unlink(joinPaths$1(this.#context.dataPath, "fs.bin"));
2535
2212
  const message = new $.Message();
2536
2213
  const fs2 = message.initRoot(FileSystem);
2537
2214
  const virtualFS = this.#unifiedFS.toJSON();
@@ -2540,7 +2217,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2540
2217
  virtualFiles.forEach(([path, code], index) => {
2541
2218
  const fd = files.get(index);
2542
2219
  fd.path = path;
2543
- fd.code = code;
2220
+ fd.code = code || "";
2544
2221
  });
2545
2222
  const ids = fs2._initIds(Object.keys(this.ids).length);
2546
2223
  Object.entries(this.ids).forEach(([id, path], index) => {
@@ -2564,7 +2241,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2564
2241
  });
2565
2242
  }
2566
2243
  });
2567
- await writeFileBuffer(joinPaths$1(this.#context.cachePath, "fs.bin"), message.toArrayBuffer());
2244
+ await writeFileBuffer(joinPaths$1(this.#context.dataPath, "fs.bin"), message.toArrayBuffer());
2245
+ this.#resolverCache.save(true);
2246
+ this.#log(LogLevelLabel.DEBUG, "Virtual file system disposed.");
2568
2247
  }
2569
2248
  }
2570
2249
  /**
@@ -2592,6 +2271,105 @@ var VirtualFileSystem = class _VirtualFileSystem {
2592
2271
  return this.dispose();
2593
2272
  }
2594
2273
  };
2274
+ var VirtualFileSystemHost = class VirtualFileSystemHost2 extends InMemoryFileSystemHost {
2275
+ static {
2276
+ __name(this, "VirtualFileSystemHost");
2277
+ }
2278
+ #fs;
2279
+ constructor(fs2) {
2280
+ super();
2281
+ this.#fs = fs2;
2282
+ }
2283
+ deleteSync(path) {
2284
+ this.#fs.rmSync(path);
2285
+ }
2286
+ readDirSync(dirPath) {
2287
+ return this.#fs.readdirSync(dirPath).reduce((ret, entry) => {
2288
+ const fullPath = this.#fs.resolveSync(joinPaths(dirPath, entry));
2289
+ if (fullPath) {
2290
+ ret.push({
2291
+ name: entry,
2292
+ isDirectory: this.#fs.isDirectory(fullPath),
2293
+ isFile: this.#fs.isFile(fullPath),
2294
+ isSymlink: false
2295
+ });
2296
+ }
2297
+ return ret;
2298
+ }, []);
2299
+ }
2300
+ async readFile(filePath) {
2301
+ if (!this.#fs.existsSync(filePath)) {
2302
+ throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
2303
+ }
2304
+ return await this.#fs.readFile(filePath);
2305
+ }
2306
+ readFileSync(filePath) {
2307
+ if (!this.#fs.existsSync(filePath)) {
2308
+ throw new Error(`File not found: '${filePath}'. Please check the path and try again.`);
2309
+ }
2310
+ return this.#fs.readFileSync(filePath);
2311
+ }
2312
+ async writeFile(filePath, fileText) {
2313
+ return this.#fs.writeFile(filePath, fileText);
2314
+ }
2315
+ writeFileSync(filePath, fileText) {
2316
+ this.#fs.writeFileSync(filePath, fileText);
2317
+ }
2318
+ async mkdir(dirPath) {
2319
+ await this.#fs.mkdir(dirPath);
2320
+ }
2321
+ mkdirSync(dirPath) {
2322
+ this.#fs.mkdirSync(dirPath);
2323
+ }
2324
+ async move(srcPath, destPath) {
2325
+ await this.#fs.move(srcPath, destPath);
2326
+ }
2327
+ moveSync(srcPath, destPath) {
2328
+ this.#fs.moveSync(srcPath, destPath);
2329
+ }
2330
+ async copy(srcPath, destPath) {
2331
+ await this.#fs.copy(srcPath, destPath);
2332
+ }
2333
+ copySync(srcPath, destPath) {
2334
+ this.#fs.copySync(srcPath, destPath);
2335
+ }
2336
+ async fileExists(filePath) {
2337
+ return this.#fs.isFile(filePath);
2338
+ }
2339
+ fileExistsSync(filePath) {
2340
+ return this.#fs.isFile(filePath);
2341
+ }
2342
+ async directoryExists(dirPath) {
2343
+ return this.#fs.isDirectory(dirPath);
2344
+ }
2345
+ directoryExistsSync(dirPath) {
2346
+ return this.#fs.isDirectory(dirPath);
2347
+ }
2348
+ realpathSync(path) {
2349
+ return this.#fs.resolveSync(path) || path;
2350
+ }
2351
+ getCurrentDirectory() {
2352
+ return "/";
2353
+ }
2354
+ async glob(patterns) {
2355
+ return this.#fs.glob(patterns);
2356
+ }
2357
+ globSync(patterns) {
2358
+ return this.#fs.globSync(patterns);
2359
+ }
2360
+ };
2361
+ function createProgram(context, override) {
2362
+ const project = new Project({
2363
+ compilerOptions: {
2364
+ ...context.tsconfig.options
2365
+ },
2366
+ tsConfigFilePath: context.tsconfig.tsconfigFilePath,
2367
+ fileSystem: new VirtualFileSystemHost(context.fs),
2368
+ ...override
2369
+ });
2370
+ return project;
2371
+ }
2372
+ __name(createProgram, "createProgram");
2595
2373
 
2596
2374
  // ../powerlines/src/lib/contexts/context.ts
2597
2375
  var configCache = /* @__PURE__ */ new WeakMap();
@@ -2613,6 +2391,8 @@ var PowerlinesContext = class _PowerlinesContext {
2613
2391
  #envPaths;
2614
2392
  #fs;
2615
2393
  #tsconfig;
2394
+ #program;
2395
+ #resolvePatterns = [];
2616
2396
  #getConfigProps(config = {}) {
2617
2397
  return {
2618
2398
  variant: config.build?.variant,
@@ -2704,7 +2484,7 @@ var PowerlinesContext = class _PowerlinesContext {
2704
2484
  */
2705
2485
  get tsconfig() {
2706
2486
  if (!this.#tsconfig) {
2707
- this.#tsconfig = {
2487
+ this.tsconfig = {
2708
2488
  tsconfigFilePath: this.config.tsconfig
2709
2489
  };
2710
2490
  }
@@ -2715,6 +2495,7 @@ var PowerlinesContext = class _PowerlinesContext {
2715
2495
  */
2716
2496
  set tsconfig(value) {
2717
2497
  this.#tsconfig = value;
2498
+ this.#resolvePatterns = tsconfigPathsToRegExp(value?.options?.paths ?? {});
2718
2499
  }
2719
2500
  /**
2720
2501
  * The virtual file system interface for the project
@@ -2839,6 +2620,106 @@ var PowerlinesContext = class _PowerlinesContext {
2839
2620
  return Object.values(this.fs.metadata).filter((meta) => meta && meta.type === "builtin").map((meta) => meta?.id).filter(Boolean);
2840
2621
  }
2841
2622
  /**
2623
+ * The {@link Project} instance used for type reflection and module manipulation
2624
+ *
2625
+ * @see https://ts-morph.com/
2626
+ *
2627
+ * @remarks
2628
+ * This instance is created lazily on first access.
2629
+ */
2630
+ get program() {
2631
+ if (!this.#program) {
2632
+ this.#program = createProgram(this, {
2633
+ skipAddingFilesFromTsConfig: true
2634
+ });
2635
+ }
2636
+ return this.#program;
2637
+ }
2638
+ /**
2639
+ * A helper function to resolve modules in the Virtual File System
2640
+ *
2641
+ * @remarks
2642
+ * This function can be used to resolve modules relative to the project root directory.
2643
+ *
2644
+ * @example
2645
+ * ```ts
2646
+ * const resolved = await context.resolve("some-module", "/path/to/importer");
2647
+ * ```
2648
+ *
2649
+ * @param id - The module to resolve.
2650
+ * @param importer - An optional path to the importer module.
2651
+ * @param options - Additional resolution options.
2652
+ * @returns A promise that resolves to the resolved module path.
2653
+ */
2654
+ async resolveId(id, importer, options = {}) {
2655
+ if (this.fs.isVirtual(id)) {
2656
+ const result = await this.fs.resolve(id, importer, options);
2657
+ if (!result) {
2658
+ return void 0;
2659
+ }
2660
+ return {
2661
+ id: `\0${result}`,
2662
+ external: this.config.projectType !== "application"
2663
+ };
2664
+ }
2665
+ if (this.config.build.skipNodeModulesBundle) {
2666
+ if (match(id, this.#resolvePatterns) || match(id, this.config.build.noExternal)) {
2667
+ return void 0;
2668
+ }
2669
+ if (match(id, this.config.build.external) || id.startsWith("node:")) {
2670
+ return {
2671
+ id,
2672
+ external: true
2673
+ };
2674
+ }
2675
+ if (!/^[A-Z]:[/\\]|^\.{0,2}\/|^\.{1,2}$/.test(id)) {
2676
+ return {
2677
+ id,
2678
+ external: true
2679
+ };
2680
+ }
2681
+ } else {
2682
+ if (match(id, this.config.build.noExternal)) {
2683
+ return void 0;
2684
+ }
2685
+ if (match(id, this.config.build.external) || id.startsWith("node:")) {
2686
+ return {
2687
+ id,
2688
+ external: true
2689
+ };
2690
+ }
2691
+ }
2692
+ return void 0;
2693
+ }
2694
+ /**
2695
+ * A helper function to load modules from the Virtual File System
2696
+ *
2697
+ * @remarks
2698
+ * This function can be used to load modules relative to the project root directory.
2699
+ *
2700
+ * @example
2701
+ * ```ts
2702
+ * const module = await context.load("some-module", "/path/to/importer");
2703
+ * ```
2704
+ *
2705
+ * @param id - The module to load.
2706
+ * @returns A promise that resolves to the loaded module.
2707
+ */
2708
+ async load(id) {
2709
+ const resolvedId = await this.fs.resolve(id);
2710
+ if (!resolvedId) {
2711
+ return void 0;
2712
+ }
2713
+ const code = await this.fs.readFile(resolvedId);
2714
+ if (!code) {
2715
+ return void 0;
2716
+ }
2717
+ return {
2718
+ code,
2719
+ map: null
2720
+ };
2721
+ }
2722
+ /**
2842
2723
  * Get the builtin virtual files that exist in the Powerlines virtual file system
2843
2724
  */
2844
2725
  async getBuiltins() {
@@ -3061,6 +2942,7 @@ var PowerlinesContext = class _PowerlinesContext {
3061
2942
  projectRoot: cacheKey.projectRoot,
3062
2943
  cacheDir: this.cachePath,
3063
2944
  mode: cacheKey.mode,
2945
+ logLevel: config.logLevel || this.config?.logLevel || this.workspaceConfig.logLevel || "info",
3064
2946
  skipCache: cacheKey.skipCache
3065
2947
  });
3066
2948
  const userConfig = await loadUserConfigFile(cacheKey.projectRoot, this.workspaceConfig.workspaceRoot, this.resolver, cacheKey.command, cacheKey.mode, cacheKey.configFile, cacheKey.framework);
@@ -3174,6 +3056,24 @@ var PowerlinesContext = class _PowerlinesContext {
3174
3056
  ret.push(plugin);
3175
3057
  return ret;
3176
3058
  }, []);
3059
+ if (this.config.tsconfig) {
3060
+ this.config.tsconfig = replacePathTokens(this, this.config.tsconfig);
3061
+ }
3062
+ if (this.config.output.dts) {
3063
+ this.config.output.dts = replacePathTokens(this, this.config.output.dts);
3064
+ }
3065
+ if (this.config.build.polyfill) {
3066
+ this.config.build.polyfill = this.config.build.polyfill.map((polyfill) => replacePathTokens(this, polyfill));
3067
+ }
3068
+ if (this.config.output.assets) {
3069
+ this.config.output.assets = this.config.output.assets.map((asset) => ({
3070
+ ...asset,
3071
+ glob: replacePathTokens(this, asset.glob),
3072
+ ignore: asset.ignore ? asset.ignore.map((ignore) => replacePathTokens(this, ignore)) : void 0,
3073
+ input: replacePathTokens(this, asset.input),
3074
+ output: replacePathTokens(this, asset.output)
3075
+ }));
3076
+ }
3177
3077
  this.#fs ??= await VirtualFileSystem.create(this);
3178
3078
  }
3179
3079
  mergeUserConfig(from = {}, into = this.config.userConfig ?? {}) {
@@ -3603,13 +3503,9 @@ ${context.entry.map((entry) => `- ${entry.input.file || entry.file}${entry.outpu
3603
3503
  await resolveTsconfig(context);
3604
3504
  await installDependencies(context);
3605
3505
  await this.callPostHook(context, "configResolved");
3606
- if (context.config.build.polyfill) {
3607
- context.config.build.polyfill = context.config.build.polyfill.map((polyfill) => replacePathTokens(context, polyfill));
3608
- }
3609
3506
  context.log(LogLevelLabel.TRACE, `Powerlines configuration has been resolved:
3610
3507
 
3611
3508
  ${formatLogMessage(context.config)}`);
3612
- context.fs[__VFS_PATCH__]();
3613
3509
  await writeMetaFile(context);
3614
3510
  context.persistedMeta = context.meta;
3615
3511
  if (!existsSync(context.cachePath)) {
@@ -3659,35 +3555,19 @@ ${formatLogMessage(context.config)}`);
3659
3555
  if (!typescriptPath) {
3660
3556
  throw new Error("Could not resolve TypeScript package location. Please ensure TypeScript is installed.");
3661
3557
  }
3662
- const files = builtinFilePaths.reduce((ret, fileName) => {
3663
- const formatted = replacePath(fileName, context.workspaceConfig.workspaceRoot);
3664
- if (!ret.includes(formatted)) {
3665
- ret.push(formatted);
3666
- }
3667
- return ret;
3668
- }, [
3669
- joinPaths$1(typescriptPath, "lib", "lib.esnext.full.d.ts")
3670
- ]);
3671
- context.log(LogLevelLabel.TRACE, "Parsing TypeScript configuration for the Powerlines project.");
3672
- const resolvedTsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.tsconfig.tsconfigFilePath, defu5({
3673
- compilerOptions: {
3674
- strict: false,
3675
- noEmit: false,
3676
- declaration: true,
3677
- declarationMap: false,
3678
- emitDeclarationOnly: true,
3679
- skipLibCheck: true
3558
+ const files = builtinFilePaths.reduce(
3559
+ (ret, fileName) => {
3560
+ const formatted = replacePath(fileName, context.workspaceConfig.workspaceRoot);
3561
+ if (!ret.includes(formatted)) {
3562
+ ret.push(formatted);
3563
+ }
3564
+ return ret;
3680
3565
  },
3681
- exclude: [
3682
- "node_modules",
3683
- "dist"
3684
- ],
3685
- include: files
3686
- }, context.config.tsconfigRaw ?? {}));
3687
- resolvedTsconfig.options.configFilePath = joinPaths$1(context.workspaceConfig.workspaceRoot, context.tsconfig.tsconfigFilePath);
3688
- resolvedTsconfig.options.pathsBasePath = context.workspaceConfig.workspaceRoot;
3689
- resolvedTsconfig.options.suppressOutputPathCheck = true;
3690
- let generatedTypes = await emitTypes(context, resolvedTsconfig, files);
3566
+ []
3567
+ // [joinPaths(typescriptPath, "lib", "lib.esnext.full.d.ts")]
3568
+ );
3569
+ context.log(LogLevelLabel.TRACE, "Parsing TypeScript configuration for the Powerlines project.");
3570
+ let generatedTypes = await emitTypes(context, files);
3691
3571
  context.log(LogLevelLabel.TRACE, `Generating TypeScript declaration file in ${context.config.output.dts}.`);
3692
3572
  const directives = [];
3693
3573
  let result = await this.callPreHook(context, "generateTypes", generatedTypes);
@@ -3741,7 +3621,6 @@ ${formatTypes(generatedTypes)}
3741
3621
  }
3742
3622
  await this.callPostHook(context, "prepare");
3743
3623
  await writeMetaFile(context);
3744
- context.fs[__VFS_REVERT__]();
3745
3624
  });
3746
3625
  this.context.log(LogLevelLabel.INFO, "Powerlines API has been prepared successfully");
3747
3626
  }