@powerlines/nx 0.10.27 → 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 (30) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{chunk-LQRLEK65.mjs → chunk-5WHBT2BW.mjs} +1 -1
  3. package/dist/{chunk-ELZO2KAE.js → chunk-7E3PRE6W.js} +2 -2
  4. package/dist/{chunk-LH6XKDMA.mjs → chunk-DLZ7E67Y.mjs} +1 -1
  5. package/dist/{chunk-YPABMWPC.js → chunk-GVA7U7C4.js} +2 -2
  6. package/dist/{chunk-UAUZWBTW.js → chunk-HLYNF7YE.js} +521 -644
  7. package/dist/{chunk-V5EQMHJX.js → chunk-HVWVP6CD.js} +2 -2
  8. package/dist/{chunk-I7QVZOFS.js → chunk-ND7VF7PZ.js} +2 -2
  9. package/dist/{chunk-2W5L3QE3.js → chunk-PM5JBU7Z.js} +2 -2
  10. package/dist/{chunk-U2ZZ4QLS.mjs → chunk-QE2RQBEB.mjs} +524 -647
  11. package/dist/{chunk-WAXOGGDZ.mjs → chunk-RIM7CNHX.mjs} +1 -1
  12. package/dist/{chunk-WNLIJGN4.mjs → chunk-VQX5TBLP.mjs} +1 -1
  13. package/dist/{chunk-EWXGKWHK.mjs → chunk-ZIBEDH47.mjs} +1 -1
  14. package/dist/executors.js +13 -13
  15. package/dist/executors.mjs +6 -6
  16. package/dist/index.js +13 -13
  17. package/dist/index.mjs +6 -6
  18. package/dist/src/base/base-executor.js +2 -2
  19. package/dist/src/base/base-executor.mjs +1 -1
  20. package/dist/src/executors/build/executor.js +4 -4
  21. package/dist/src/executors/build/executor.mjs +2 -2
  22. package/dist/src/executors/clean/executor.js +4 -4
  23. package/dist/src/executors/clean/executor.mjs +2 -2
  24. package/dist/src/executors/docs/executor.js +4 -4
  25. package/dist/src/executors/docs/executor.mjs +2 -2
  26. package/dist/src/executors/lint/executor.js +4 -4
  27. package/dist/src/executors/lint/executor.mjs +2 -2
  28. package/dist/src/executors/prepare/executor.js +4 -4
  29. package/dist/src/executors/prepare/executor.mjs +2 -2
  30. package/package.json +8 -8
@@ -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
  });
@@ -718,8 +721,6 @@ function replacePathTokens(context, path) {
718
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));
719
722
  }
720
723
  __name(replacePathTokens, "replacePathTokens");
721
-
722
- // ../powerlines/src/lib/entry.ts
723
724
  function resolveEntryInputFile(context, typeDefinition) {
724
725
  return replacePath(typeDefinition.file, joinPaths$1(context.workspaceConfig.workspaceRoot, context.config.projectRoot));
725
726
  }
@@ -867,187 +868,6 @@ var FileMetadata = class _FileMetadata extends $.Struct {
867
868
  return "FileMetadata_" + super.toString();
868
869
  }
869
870
  };
870
- var ChunkData = class extends $.Struct {
871
- static {
872
- __name(this, "ChunkData");
873
- }
874
- static _capnp = {
875
- displayName: "ChunkData",
876
- id: "84076f13b057f83a",
877
- size: new $.ObjectSize(8, 4)
878
- };
879
- /**
880
- * An additional name for the file.
881
- *
882
- */
883
- get id() {
884
- return $.utils.getText(0, this);
885
- }
886
- set id(value) {
887
- $.utils.setText(0, value, this);
888
- }
889
- /**
890
- * Files that are implicitly loaded after one of the specified files.
891
- *
892
- */
893
- get name() {
894
- return $.utils.getText(1, this);
895
- }
896
- set name(value) {
897
- $.utils.setText(1, value, this);
898
- }
899
- _adoptImplicitlyLoadedAfterOneOf(value) {
900
- $.utils.adopt(value, $.utils.getPointer(2, this));
901
- }
902
- _disownImplicitlyLoadedAfterOneOf() {
903
- return $.utils.disown(this.implicitlyLoadedAfterOneOf);
904
- }
905
- /**
906
- * The importer of the file.
907
- *
908
- */
909
- get implicitlyLoadedAfterOneOf() {
910
- return $.utils.getList(2, $.TextList, this);
911
- }
912
- _hasImplicitlyLoadedAfterOneOf() {
913
- return !$.utils.isNull($.utils.getPointer(2, this));
914
- }
915
- _initImplicitlyLoadedAfterOneOf(length) {
916
- return $.utils.initList(2, $.TextList, length, this);
917
- }
918
- set implicitlyLoadedAfterOneOf(value) {
919
- $.utils.copyFrom(value, $.utils.getPointer(2, this));
920
- }
921
- /**
922
- * The signature preservation mode for the file.
923
- *
924
- */
925
- get importer() {
926
- return $.utils.getText(3, this);
927
- }
928
- set importer(value) {
929
- $.utils.setText(3, value, this);
930
- }
931
- get preserveSignature() {
932
- return $.utils.getUint16(0, this);
933
- }
934
- set preserveSignature(value) {
935
- $.utils.setUint16(0, value, this);
936
- }
937
- toString() {
938
- return "ChunkData_" + super.toString();
939
- }
940
- };
941
- var PrebuiltData = class extends $.Struct {
942
- static {
943
- __name(this, "PrebuiltData");
944
- }
945
- static _capnp = {
946
- displayName: "PrebuiltData",
947
- id: "c5b1a6ca696328ee",
948
- size: new $.ObjectSize(0, 4)
949
- };
950
- /**
951
- * An additional name for the file.
952
- *
953
- */
954
- get id() {
955
- return $.utils.getText(0, this);
956
- }
957
- set id(value) {
958
- $.utils.setText(0, value, this);
959
- }
960
- /**
961
- * The file exports.
962
- *
963
- */
964
- get name() {
965
- return $.utils.getText(1, this);
966
- }
967
- set name(value) {
968
- $.utils.setText(1, value, this);
969
- }
970
- _adoptExports(value) {
971
- $.utils.adopt(value, $.utils.getPointer(2, this));
972
- }
973
- _disownExports() {
974
- return $.utils.disown(this.exports);
975
- }
976
- /**
977
- * The source map for the file.
978
- *
979
- */
980
- get exports() {
981
- return $.utils.getList(2, $.TextList, this);
982
- }
983
- _hasExports() {
984
- return !$.utils.isNull($.utils.getPointer(2, this));
985
- }
986
- _initExports(length) {
987
- return $.utils.initList(2, $.TextList, length, this);
988
- }
989
- set exports(value) {
990
- $.utils.copyFrom(value, $.utils.getPointer(2, this));
991
- }
992
- get map() {
993
- return $.utils.getText(3, this);
994
- }
995
- set map(value) {
996
- $.utils.setText(3, value, this);
997
- }
998
- toString() {
999
- return "PrebuiltData_" + super.toString();
1000
- }
1001
- };
1002
- var AssetData = class extends $.Struct {
1003
- static {
1004
- __name(this, "AssetData");
1005
- }
1006
- static _capnp = {
1007
- displayName: "AssetData",
1008
- id: "da660c6c1fa4c830",
1009
- size: new $.ObjectSize(8, 3)
1010
- };
1011
- /**
1012
- * An additional name for the file.
1013
- *
1014
- */
1015
- get id() {
1016
- return $.utils.getText(0, this);
1017
- }
1018
- set id(value) {
1019
- $.utils.setText(0, value, this);
1020
- }
1021
- /**
1022
- * Indicates whether the file needs a code reference.
1023
- *
1024
- */
1025
- get name() {
1026
- return $.utils.getText(1, this);
1027
- }
1028
- set name(value) {
1029
- $.utils.setText(1, value, this);
1030
- }
1031
- /**
1032
- * The original file name before any transformations.
1033
- *
1034
- */
1035
- get needsCodeReference() {
1036
- return $.utils.getBit(0, this);
1037
- }
1038
- set needsCodeReference(value) {
1039
- $.utils.setBit(0, value, this);
1040
- }
1041
- get originalFileName() {
1042
- return $.utils.getText(2, this);
1043
- }
1044
- set originalFileName(value) {
1045
- $.utils.setText(2, value, this);
1046
- }
1047
- toString() {
1048
- return "AssetData_" + super.toString();
1049
- }
1050
- };
1051
871
  var FileId = class extends $.Struct {
1052
872
  static {
1053
873
  __name(this, "FileId");
@@ -1113,14 +933,11 @@ var FileSystem = class _FileSystem extends $.Struct {
1113
933
  static _capnp = {
1114
934
  displayName: "FileSystem",
1115
935
  id: "ae0c23d43e56abcf",
1116
- size: new $.ObjectSize(0, 6)
936
+ size: new $.ObjectSize(0, 3)
1117
937
  };
1118
938
  static _Ids;
1119
939
  static _Files;
1120
940
  static _Metadata;
1121
- static _Assets;
1122
- static _Chunks;
1123
- static _Prebuilt;
1124
941
  _adoptIds(value) {
1125
942
  $.utils.adopt(value, $.utils.getPointer(0, this));
1126
943
  }
@@ -1175,60 +992,6 @@ var FileSystem = class _FileSystem extends $.Struct {
1175
992
  set metadata(value) {
1176
993
  $.utils.copyFrom(value, $.utils.getPointer(2, this));
1177
994
  }
1178
- _adoptAssets(value) {
1179
- $.utils.adopt(value, $.utils.getPointer(3, this));
1180
- }
1181
- _disownAssets() {
1182
- return $.utils.disown(this.assets);
1183
- }
1184
- get assets() {
1185
- return $.utils.getList(3, _FileSystem._Assets, this);
1186
- }
1187
- _hasAssets() {
1188
- return !$.utils.isNull($.utils.getPointer(3, this));
1189
- }
1190
- _initAssets(length) {
1191
- return $.utils.initList(3, _FileSystem._Assets, length, this);
1192
- }
1193
- set assets(value) {
1194
- $.utils.copyFrom(value, $.utils.getPointer(3, this));
1195
- }
1196
- _adoptChunks(value) {
1197
- $.utils.adopt(value, $.utils.getPointer(4, this));
1198
- }
1199
- _disownChunks() {
1200
- return $.utils.disown(this.chunks);
1201
- }
1202
- get chunks() {
1203
- return $.utils.getList(4, _FileSystem._Chunks, this);
1204
- }
1205
- _hasChunks() {
1206
- return !$.utils.isNull($.utils.getPointer(4, this));
1207
- }
1208
- _initChunks(length) {
1209
- return $.utils.initList(4, _FileSystem._Chunks, length, this);
1210
- }
1211
- set chunks(value) {
1212
- $.utils.copyFrom(value, $.utils.getPointer(4, this));
1213
- }
1214
- _adoptPrebuilt(value) {
1215
- $.utils.adopt(value, $.utils.getPointer(5, this));
1216
- }
1217
- _disownPrebuilt() {
1218
- return $.utils.disown(this.prebuilt);
1219
- }
1220
- get prebuilt() {
1221
- return $.utils.getList(5, _FileSystem._Prebuilt, this);
1222
- }
1223
- _hasPrebuilt() {
1224
- return !$.utils.isNull($.utils.getPointer(5, this));
1225
- }
1226
- _initPrebuilt(length) {
1227
- return $.utils.initList(5, _FileSystem._Prebuilt, length, this);
1228
- }
1229
- set prebuilt(value) {
1230
- $.utils.copyFrom(value, $.utils.getPointer(5, this));
1231
- }
1232
995
  toString() {
1233
996
  return "FileSystem_" + super.toString();
1234
997
  }
@@ -1237,9 +1000,6 @@ FileMetadata._Properties = $.CompositeList(FileMetadata_KeyValuePair);
1237
1000
  FileSystem._Ids = $.CompositeList(FileId);
1238
1001
  FileSystem._Files = $.CompositeList(FileData);
1239
1002
  FileSystem._Metadata = $.CompositeList(FileMetadata);
1240
- FileSystem._Assets = $.CompositeList(AssetData);
1241
- FileSystem._Chunks = $.CompositeList(ChunkData);
1242
- FileSystem._Prebuilt = $.CompositeList(PrebuiltData);
1243
1003
 
1244
1004
  // ../powerlines/src/types/fs.ts
1245
1005
  var __VFS_PATCH__ = "__VFS_PATCH__";
@@ -1287,13 +1047,9 @@ function isBufferEncoding(options) {
1287
1047
  }
1288
1048
  __name(isBufferEncoding, "isBufferEncoding");
1289
1049
  function isPowerlinesWriteFileOptions(options) {
1290
- 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");
1291
1051
  }
1292
1052
  __name(isPowerlinesWriteFileOptions, "isPowerlinesWriteFileOptions");
1293
- function isNodeWriteFileOptions(options) {
1294
- return !isUndefined(options) && (isBufferEncoding(options) || !isPowerlinesWriteFileOptions(options));
1295
- }
1296
- __name(isNodeWriteFileOptions, "isNodeWriteFileOptions");
1297
1053
  function isVirtualFileData(obj) {
1298
1054
  return !!(isSetObject(obj) && "code" in obj && obj.code);
1299
1055
  }
@@ -1430,6 +1186,18 @@ function patchFS(originalFS, vfs) {
1430
1186
  };
1431
1187
  }
1432
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");
1433
1201
  var UnifiedFS = class _UnifiedFS extends Union {
1434
1202
  static {
1435
1203
  __name(this, "UnifiedFS");
@@ -1606,9 +1374,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
1606
1374
  */
1607
1375
  #paths;
1608
1376
  /**
1609
- * A map of virtual file paths to their underlying file content.
1377
+ * A cache for module resolution results.
1610
1378
  */
1611
- #cachedResolver = /* @__PURE__ */ new Map();
1379
+ #resolverCache;
1612
1380
  /**
1613
1381
  * The unified volume that combines the virtual file system with the real file system.
1614
1382
  *
@@ -1643,189 +1411,35 @@ var VirtualFileSystem = class _VirtualFileSystem {
1643
1411
  * @returns `true` if the path exists, otherwise `false`.
1644
1412
  */
1645
1413
  #existsSync(path) {
1646
- const formattedPath = this.formatPath(path);
1647
- return this.#unifiedFS.virtual.existsSync(formattedPath) || this.#unifiedFS.physical.existsSync(formattedPath) || this.#unifiedFS.resolveFS(path).existsSync(formattedPath);
1648
- }
1649
- /**
1650
- * Builds a regular expression from a string pattern for path matching.
1651
- *
1652
- * @param strPattern - The string pattern to convert.
1653
- * @returns A regular expression for matching paths.
1654
- */
1655
- #buildRegex(strPattern) {
1656
- const token = "::GLOBSTAR::";
1657
- 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));
1658
1415
  }
1659
1416
  /**
1660
- * 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.
1661
1418
  *
1662
- * @param id - The file ID to format.
1663
- * @returns The formatted file ID.
1419
+ * @param id - The module id to normalize.
1420
+ * @returns The normalized module id.
1664
1421
  */
1665
- #formatId(id) {
1666
- const formattedId = toFilePath(id);
1667
- return `${this.#context.config.output.builtinPrefix}:${formattedId.replace(new RegExp(`^${this.#context.config.output.builtinPrefix}:`), "").replace(/^\\0/, "").replace(findFileDotExtensionSafe(formattedId), "")}`;
1668
- }
1669
- /**
1670
- * Resolves an id parameter to a corresponding virtual file path in the virtual file system (VFS).
1671
- *
1672
- * @param id - The id to resolve.
1673
- * @returns The resolved file id if it exists, otherwise undefined.
1674
- */
1675
- #resolveId(id) {
1676
- if (this.#ids[this.#formatId(id)]) {
1677
- return this.#ids[this.#formatId(id)] || false;
1678
- }
1679
- return false;
1680
- }
1681
- /**
1682
- * Resolves a path parameter to a corresponding virtual file path in the virtual file system (VFS).
1683
- *
1684
- * @param path - The path to resolve.
1685
- * @param options - Optional parameters for resolving the path.
1686
- * @returns The resolved file path if it exists, otherwise undefined.
1687
- */
1688
- #resolvePath(path, options = {}) {
1689
- if (isAbsolutePath(path)) {
1690
- if (this.#existsSync(path)) {
1691
- return path;
1692
- }
1693
- const result = this.#checkVariants(path);
1694
- if (result) {
1695
- return result;
1696
- }
1697
- }
1698
- for (const parentPath of this.#resolveParentPaths(path, options.paths)) {
1699
- const request = joinPaths$1(parentPath, path);
1700
- if (this.#existsSync(request)) {
1701
- return request;
1702
- }
1703
- const result = this.#checkVariants(request);
1704
- if (result) {
1705
- return result;
1706
- }
1707
- }
1708
- return false;
1709
- }
1710
- /**
1711
- * Resolves parent paths for a given request.
1712
- *
1713
- * @param request - The request path to resolve parent paths for.
1714
- * @param parents - An optional array of parent paths to consider.
1715
- * @returns An array of resolved parent paths.
1716
- */
1717
- #resolveParentPaths(request, parents = []) {
1718
- let paths = [
1719
- this.#context.workspaceConfig.workspaceRoot,
1720
- joinPaths$1(this.#context.workspaceConfig.workspaceRoot, this.#context.config.projectRoot)
1721
- ];
1722
- if (this.#context.tsconfig.options.paths) {
1723
- 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) => {
1724
- if (path && !ret.includes(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path))) {
1725
- ret.push(joinPaths$1(this.#context.workspaceConfig.workspaceRoot, path));
1726
- }
1727
- return ret;
1728
- }, paths) : paths;
1729
- }
1730
- return paths.reduce((ret, path) => {
1731
- if (!ret.includes(path)) {
1732
- ret.push(path);
1733
- }
1734
- return ret;
1735
- }, parents.filter(Boolean).map((p) => this.formatPath(p)));
1422
+ #normalizeId(id) {
1423
+ return normalizeId(id, this.#context.config.output.builtinPrefix);
1736
1424
  }
1737
1425
  /**
1738
- * 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.
1739
1427
  *
1740
- * @param path - The path to clear the resolver cache for.
1428
+ * @param path - The path to normalize.
1429
+ * @returns The normalized path.
1741
1430
  */
1742
- #clearResolverCache(path) {
1743
- 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);
1744
1433
  }
1745
1434
  /**
1746
- * Check if the file exists with different variants (index, extensions).
1747
- *
1748
- * @param request - The request path to check.
1749
- * @param parentPath - An optional parent path to prepend to the request.
1750
- * @returns The file path if it exists, otherwise false.
1751
- */
1752
- #checkVariants(request, parentPath) {
1753
- const path = parentPath ? joinPaths$1(parentPath, request) : request;
1754
- let file = this.#checkExtensions(path);
1755
- if (file) {
1756
- return file;
1757
- }
1758
- file = this.#checkIndex(path);
1759
- if (file) {
1760
- return file;
1761
- }
1762
- return false;
1763
- }
1764
- /**
1765
- * Check if the index file exists in the given request path.
1766
- *
1767
- * @param request - The request path to check.
1768
- * @returns The index file path if it exists, otherwise false.
1769
- */
1770
- #checkIndex(request) {
1771
- let file = joinPaths$1(request, "index");
1772
- if (this.#existsSync(file)) {
1773
- return file;
1774
- }
1775
- file = this.#checkExtensions(file);
1776
- if (file) {
1777
- return file;
1778
- }
1779
- return false;
1780
- }
1781
- /**
1782
- * Check if the file exists with different extensions.
1435
+ * Builds a regular expression from a string pattern for path matching.
1783
1436
  *
1784
- * @param request - The request path to check.
1785
- * @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.
1786
1439
  */
1787
- #checkExtensions(request) {
1788
- let file = `${request}.ts`;
1789
- if (this.#existsSync(file)) {
1790
- return file;
1791
- }
1792
- file = `${request}.mts`;
1793
- if (this.#existsSync(file)) {
1794
- return file;
1795
- }
1796
- file = `${request}.cts`;
1797
- if (this.#existsSync(file)) {
1798
- return file;
1799
- }
1800
- file = `${request}.tsx`;
1801
- if (this.#existsSync(file)) {
1802
- return file;
1803
- }
1804
- file = `${request}.js`;
1805
- if (this.#existsSync(file)) {
1806
- return file;
1807
- }
1808
- file = `${request}.mjs`;
1809
- if (this.#existsSync(file)) {
1810
- return file;
1811
- }
1812
- file = `${request}.cjs`;
1813
- if (this.#existsSync(file)) {
1814
- return file;
1815
- }
1816
- file = `${request}.jsx`;
1817
- if (this.#existsSync(file)) {
1818
- return file;
1819
- }
1820
- file = `${request}.json`;
1821
- if (this.#existsSync(file)) {
1822
- return file;
1823
- }
1824
- file = `${request}.d.ts`;
1825
- if (this.#existsSync(file)) {
1826
- return file;
1827
- }
1828
- 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"), ".*")}$`);
1829
1443
  }
1830
1444
  /**
1831
1445
  * Creates a virtual file system (VFS) that is backed up to a Cap'n Proto message buffer.
@@ -1834,8 +1448,8 @@ var VirtualFileSystem = class _VirtualFileSystem {
1834
1448
  * @returns A promise that resolves to a new virtual file system instance.
1835
1449
  */
1836
1450
  static async create(context) {
1837
- if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1838
- 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"));
1839
1453
  const message2 = new $.Message(buffer, false);
1840
1454
  return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1841
1455
  }
@@ -1849,8 +1463,8 @@ var VirtualFileSystem = class _VirtualFileSystem {
1849
1463
  * @returns A new virtual file system instance.
1850
1464
  */
1851
1465
  static createSync(context) {
1852
- if (!context.config.skipCache && existsSync(joinPaths$1(context.cachePath, "fs.bin"))) {
1853
- 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"));
1854
1468
  const message2 = new $.Message(buffer, false);
1855
1469
  return new _VirtualFileSystem(context, message2.getRoot(FileSystem));
1856
1470
  }
@@ -1861,19 +1475,43 @@ var VirtualFileSystem = class _VirtualFileSystem {
1861
1475
  * A map of file ids to their metadata.
1862
1476
  */
1863
1477
  get metadata() {
1864
- return this.#metadata;
1478
+ return new Proxy(this.#metadata, {
1479
+ get: /* @__PURE__ */ __name((target, prop) => {
1480
+ return target[this.#normalizeId(prop)];
1481
+ }, "get")
1482
+ });
1865
1483
  }
1866
1484
  /**
1867
- * A map of module ids to their file paths.
1485
+ * A map of file paths to their module ids.
1868
1486
  */
1869
1487
  get ids() {
1870
- return this.#ids;
1488
+ return new Proxy(this.#paths, {
1489
+ get: /* @__PURE__ */ __name((target, prop) => {
1490
+ return target[this.#normalizePath(prop)];
1491
+ }, "get")
1492
+ });
1871
1493
  }
1872
1494
  /**
1873
- * A map of virtual file paths to their IDs.
1495
+ * A map of module ids to their file paths.
1874
1496
  */
1875
1497
  get paths() {
1876
- 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;
1877
1515
  }
1878
1516
  /**
1879
1517
  * Creates a new instance of the {@link VirtualFileSystem}.
@@ -1918,17 +1556,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1918
1556
  * Check if a path or id corresponds to a virtual file **(does not actually exists on disk)**.
1919
1557
  *
1920
1558
  * @param pathOrId - The path or id to check.
1921
- * @param options - Optional parameters for resolving the path.
1922
1559
  * @returns Whether the path or id corresponds to a virtual file **(does not actually exists on disk)**.
1923
1560
  */
1924
- isVirtual(pathOrId, options = {}) {
1561
+ isVirtual(pathOrId, importer, options = {}) {
1925
1562
  if (!pathOrId) {
1926
1563
  return false;
1927
1564
  }
1928
- const resolvedPath = this.resolve(pathOrId, {
1929
- ...options,
1930
- pathType: "file"
1931
- });
1565
+ const resolvedPath = this.resolveSync(pathOrId, importer, options);
1932
1566
  if (!resolvedPath) {
1933
1567
  return false;
1934
1568
  }
@@ -1938,17 +1572,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
1938
1572
  * Check if a path or id corresponds to a file written to the file system **(actually exists on disk)**.
1939
1573
  *
1940
1574
  * @param pathOrId - The path or id to check.
1941
- * @param options - Optional parameters for resolving the path.
1942
1575
  * @returns Whether the path or id corresponds to a file written to the file system **(actually exists on disk)**.
1943
1576
  */
1944
- isPhysical(pathOrId, options = {}) {
1577
+ isPhysical(pathOrId, importer, options = {}) {
1945
1578
  if (!pathOrId) {
1946
1579
  return false;
1947
1580
  }
1948
- const resolvedPath = this.resolve(pathOrId, {
1949
- ...options,
1950
- pathType: "file"
1951
- });
1581
+ const resolvedPath = this.resolveSync(pathOrId, importer, options);
1952
1582
  if (!resolvedPath) {
1953
1583
  return false;
1954
1584
  }
@@ -1970,16 +1600,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
1970
1600
  * @param path - The path to create the directory at.
1971
1601
  */
1972
1602
  unlinkSync(path, options) {
1973
- const formattedPath = toFilePath(path);
1974
- if (!this.isFile(formattedPath)) {
1603
+ if (!this.isFile(this.#normalizePath(path))) {
1975
1604
  return;
1976
1605
  }
1977
- this.#log(LogLevelLabel.TRACE, `Synchronously removing file: ${formattedPath}`);
1978
- this.#unifiedFS.resolveFS(path, options).unlinkSync(formattedPath);
1979
- if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1980
- 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));
1981
1613
  }
1982
- this.#clearResolverCache(formattedPath);
1983
1614
  }
1984
1615
  /**
1985
1616
  * Removes a file in the virtual file system (VFS).
@@ -1987,19 +1618,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
1987
1618
  * @param path - The path to create the directory at.
1988
1619
  */
1989
1620
  async unlink(path, options) {
1990
- const formattedPath = toFilePath(path);
1991
- if (!this.isFile(formattedPath)) {
1621
+ if (!this.isFile(this.#normalizePath(path))) {
1992
1622
  return;
1993
1623
  }
1994
- this.#log(LogLevelLabel.TRACE, `Removing file: ${formattedPath}`);
1624
+ this.#log(LogLevelLabel.TRACE, `Removing file: ${this.#normalizePath(path)}`);
1995
1625
  if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.unlink)) {
1996
- await this.#unifiedFS.resolveFS(path, options).promises.unlink(formattedPath);
1997
- if (this.paths[formattedPath] && this.metadata[this.paths[formattedPath]]) {
1998
- 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)]];
1999
1629
  }
2000
- this.#clearResolverCache(formattedPath);
2001
1630
  } else {
2002
- this.unlinkSync(formattedPath, options);
1631
+ this.unlinkSync(this.#normalizePath(path), options);
2003
1632
  }
2004
1633
  }
2005
1634
  /**
@@ -2009,15 +1638,13 @@ var VirtualFileSystem = class _VirtualFileSystem {
2009
1638
  * @param options - Options for creating the directory.
2010
1639
  */
2011
1640
  rmdirSync(path, options = {}) {
2012
- const formattedPath = toFilePath(path);
2013
- if (!this.isDirectory(formattedPath)) {
1641
+ if (!this.isDirectory(this.#normalizePath(path))) {
2014
1642
  return;
2015
1643
  }
2016
- this.#log(LogLevelLabel.TRACE, `Synchronously removing directory: ${formattedPath}`);
2017
- 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, {
2018
1646
  recursive: true
2019
1647
  }));
2020
- this.#clearResolverCache(formattedPath);
2021
1648
  }
2022
1649
  /**
2023
1650
  * Removes a directory in the virtual file system (VFS).
@@ -2027,19 +1654,17 @@ var VirtualFileSystem = class _VirtualFileSystem {
2027
1654
  * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
2028
1655
  */
2029
1656
  async rmdir(path, options = {}) {
2030
- const formattedPath = toFilePath(path);
2031
- if (!this.isDirectory(formattedPath)) {
1657
+ if (!this.isDirectory(this.#normalizePath(path))) {
2032
1658
  return;
2033
1659
  }
2034
- this.#log(LogLevelLabel.TRACE, `Removing directory: ${formattedPath}`);
1660
+ this.#log(LogLevelLabel.TRACE, `Removing directory: ${this.#normalizePath(path)}`);
2035
1661
  if (isFunction(this.#unifiedFS.resolveFS(path, options).promises.rm)) {
2036
- 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, {
2037
1663
  force: true,
2038
1664
  recursive: true
2039
1665
  }));
2040
- this.#clearResolverCache(formattedPath);
2041
1666
  } else {
2042
- this.rmdirSync(formattedPath, defu5(options ?? {}, {
1667
+ this.rmdirSync(this.#normalizePath(path), defu5(options ?? {}, {
2043
1668
  force: true,
2044
1669
  recursive: true
2045
1670
  }));
@@ -2053,11 +1678,11 @@ var VirtualFileSystem = class _VirtualFileSystem {
2053
1678
  * @returns A promise that resolves when the file is removed.
2054
1679
  */
2055
1680
  async rm(path, options = {}) {
2056
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
2057
- if (this.isDirectory(path)) {
2058
- 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);
2059
1684
  }
2060
- return this.unlink(path, options);
1685
+ return this.unlink(this.#normalizePath(path), options);
2061
1686
  }
2062
1687
  /**
2063
1688
  * Synchronously removes a file or directory in the virtual file system (VFS).
@@ -2066,11 +1691,11 @@ var VirtualFileSystem = class _VirtualFileSystem {
2066
1691
  * @param options - Options for removing the file or directory.
2067
1692
  */
2068
1693
  rmSync(path, options = {}) {
2069
- this.#log(LogLevelLabel.TRACE, `Removing: ${toFilePath(path)}`);
2070
- if (this.isDirectory(path)) {
2071
- 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);
2072
1697
  }
2073
- return this.unlinkSync(path, options);
1698
+ return this.unlinkSync(this.#normalizePath(path), options);
2074
1699
  }
2075
1700
  /**
2076
1701
  * Creates a directory in the virtual file system (VFS).
@@ -2080,9 +1705,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2080
1705
  * @returns A promise that resolves to the path of the created directory, or undefined if the directory could not be created.
2081
1706
  */
2082
1707
  mkdirSync(path, options = {}) {
2083
- const filePath = toFilePath(path);
2084
- this.#clearResolverCache(filePath);
2085
- 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
+ ]), {
2086
1711
  recursive: true
2087
1712
  }));
2088
1713
  }
@@ -2095,17 +1720,19 @@ var VirtualFileSystem = class _VirtualFileSystem {
2095
1720
  */
2096
1721
  async mkdir(path, options = {}) {
2097
1722
  let result;
2098
- const filePath = toFilePath(path);
2099
- if (isFunction(this.#unifiedFS.resolveFS(filePath, options).promises.mkdir)) {
2100
- 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
+ ]), {
2101
1727
  recursive: true
2102
1728
  }));
2103
1729
  } else {
2104
- 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
+ ]), {
2105
1733
  recursive: true
2106
1734
  }));
2107
1735
  }
2108
- this.#clearResolverCache(filePath);
2109
1736
  return result;
2110
1737
  }
2111
1738
  /**
@@ -2117,17 +1744,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2117
1744
  async glob(patterns) {
2118
1745
  const results = [];
2119
1746
  for (const pattern of toArray(patterns)) {
2120
- const normalized = this.formatPath(pattern);
1747
+ const normalized = this.#normalizePath(pattern);
2121
1748
  if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
2122
- const resolved = this.resolve(normalized, {
2123
- pathType: "file"
2124
- });
1749
+ const resolved = this.resolveSync(normalized);
2125
1750
  if (resolved && !results.includes(resolved)) {
2126
1751
  results.push(resolved);
2127
1752
  }
2128
1753
  continue;
2129
1754
  }
2130
- 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));
2131
1756
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
2132
1757
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
2133
1758
  const stack = [
@@ -2142,7 +1767,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2142
1767
  continue;
2143
1768
  }
2144
1769
  for (const entry of entries) {
2145
- const full = this.formatPath(joinPaths$1(dir, entry));
1770
+ const full = this.#normalizePath(joinPaths$1(dir, entry));
2146
1771
  let stats;
2147
1772
  try {
2148
1773
  stats = this.#unifiedFS.lstatSync(full);
@@ -2154,9 +1779,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2154
1779
  stack.push(full);
2155
1780
  } else if (stats.isFile()) {
2156
1781
  if (this.#buildRegex(absPattern).test(full)) {
2157
- const resolved = this.resolve(full, {
2158
- pathType: "file"
2159
- });
1782
+ const resolved = this.resolveSync(full);
2160
1783
  if (resolved && !results.includes(resolved)) {
2161
1784
  results.push(resolved);
2162
1785
  }
@@ -2176,17 +1799,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2176
1799
  globSync(patterns) {
2177
1800
  const results = [];
2178
1801
  for (const pattern of toArray(patterns)) {
2179
- const normalized = this.formatPath(pattern);
1802
+ const normalized = this.#normalizePath(pattern);
2180
1803
  if (!/[*?[\]{}]/.test(normalized) && !normalized.includes("**")) {
2181
- const resolved = this.resolve(normalized, {
2182
- pathType: "file"
2183
- });
1804
+ const resolved = this.resolveSync(normalized);
2184
1805
  if (resolved && !results.includes(resolved)) {
2185
1806
  results.push(resolved);
2186
1807
  }
2187
1808
  continue;
2188
1809
  }
2189
- 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));
2190
1811
  const firstGlobIdx = absPattern.search(/[*?[\]{}]/);
2191
1812
  const baseDir = firstGlobIdx === -1 ? findFilePath(absPattern) : absPattern.slice(0, Math.max(0, absPattern.lastIndexOf("/", firstGlobIdx)));
2192
1813
  const stack = [
@@ -2201,7 +1822,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2201
1822
  continue;
2202
1823
  }
2203
1824
  for (const entry of entries) {
2204
- const full = this.formatPath(joinPaths$1(dir, entry));
1825
+ const full = this.#normalizePath(joinPaths$1(dir, entry));
2205
1826
  let stats;
2206
1827
  try {
2207
1828
  stats = this.#unifiedFS.lstatSync(full);
@@ -2213,9 +1834,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2213
1834
  stack.push(full);
2214
1835
  } else if (stats.isFile()) {
2215
1836
  if (this.#buildRegex(absPattern).test(full)) {
2216
- const resolved = this.resolve(full, {
2217
- pathType: "file"
2218
- });
1837
+ const resolved = this.resolveSync(full);
2219
1838
  if (resolved && !results.includes(resolved)) {
2220
1839
  results.push(resolved);
2221
1840
  }
@@ -2285,21 +1904,15 @@ var VirtualFileSystem = class _VirtualFileSystem {
2285
1904
  * @returns A promise that resolves to the contents of the file as a string, or undefined if the file does not exist.
2286
1905
  */
2287
1906
  async readFile(pathOrId, options = "utf8") {
2288
- if (!pathOrId) {
2289
- return void 0;
2290
- }
2291
- const filePath = this.resolve(toFilePath(pathOrId), {
2292
- pathType: "file"
2293
- });
2294
- if (filePath) {
1907
+ const filePath = await this.resolve(pathOrId);
1908
+ if (filePath && this.isFile(filePath)) {
2295
1909
  let result;
2296
1910
  if (isFunction(this.#unifiedFS.resolveFS(filePath).promises.readFile)) {
2297
1911
  result = (await this.#unifiedFS.resolveFS(filePath).promises.readFile(filePath, options))?.toString("utf8");
2298
1912
  } else {
2299
1913
  result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
2300
1914
  }
2301
- const content = isBuffer(result) ? bufferToString(result) : result;
2302
- return content;
1915
+ return isBuffer(result) ? bufferToString(result) : result;
2303
1916
  }
2304
1917
  return void 0;
2305
1918
  }
@@ -2310,16 +1923,10 @@ var VirtualFileSystem = class _VirtualFileSystem {
2310
1923
  * @returns The contents of the file as a string, or undefined if the file does not exist.
2311
1924
  */
2312
1925
  readFileSync(pathOrId, options = "utf8") {
2313
- if (!pathOrId) {
2314
- return void 0;
2315
- }
2316
- const filePath = this.resolve(toFilePath(pathOrId), {
2317
- pathType: "file"
2318
- });
2319
- if (filePath) {
1926
+ const filePath = this.resolveSync(pathOrId);
1927
+ if (filePath && this.isFile(filePath)) {
2320
1928
  const result = this.#unifiedFS.resolveFS(filePath).readFileSync(filePath, options);
2321
- const content = isBuffer(result) ? bufferToString(result) : result;
2322
- return content;
1929
+ return isBuffer(result) ? bufferToString(result) : result;
2323
1930
  }
2324
1931
  return void 0;
2325
1932
  }
@@ -2332,34 +1939,40 @@ var VirtualFileSystem = class _VirtualFileSystem {
2332
1939
  * @returns A promise that resolves when the file is written.
2333
1940
  */
2334
1941
  async writeFile(path, data = "", options = "utf8") {
2335
- const formattedPath = this.formatPath(path);
2336
- if (!this.isDirectory(findFilePath(formattedPath))) {
2337
- 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);
2338
1944
  }
2339
- 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;
2340
1948
  if ((!isPowerlinesWriteFileOptions(options) || !options.skipFormat) && isSetString(code)) {
2341
- const resolvedConfig = await resolveConfig(formattedPath);
1949
+ const resolvedConfig = await resolveConfig(this.#normalizePath(path));
2342
1950
  if (resolvedConfig) {
2343
1951
  code = await format(code, {
2344
- absolutePath: formattedPath,
1952
+ absolutePath: this.#normalizePath(path),
2345
1953
  ...resolvedConfig
2346
1954
  });
2347
1955
  }
2348
1956
  }
2349
- const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
2350
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
2351
- 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] = {
2352
1960
  mode: outputMode,
2353
1961
  variant: "normal",
2354
1962
  timestamp: Date.now(),
2355
- ...isVirtualFileData(data) ? data : {}
1963
+ ...metadata
2356
1964
  };
2357
- this.#clearResolverCache(formattedPath);
2358
- 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);
2359
1968
  if (isFunction(ifs.promises.writeFile)) {
2360
- 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");
2361
1972
  }
2362
- 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");
2363
1976
  }
2364
1977
  /**
2365
1978
  * Synchronously writes a file to the virtual file system (VFS).
@@ -2369,21 +1982,23 @@ var VirtualFileSystem = class _VirtualFileSystem {
2369
1982
  * @param options - Optional parameters for writing the file.
2370
1983
  */
2371
1984
  writeFileSync(path, data = "", options = "utf8") {
2372
- const formattedPath = this.formatPath(path);
2373
- if (!this.isDirectory(findFilePath(formattedPath))) {
2374
- this.mkdirSync(findFilePath(formattedPath), isPowerlinesWriteFileOptions(options) ? options : void 0);
2375
- }
2376
- const code = isVirtualFileData(data) ? data.code : data;
2377
- const outputMode = this.#unifiedFS.resolveMode(formattedPath, isPowerlinesWriteFileOptions(options) ? options : void 0);
2378
- this.#log(LogLevelLabel.TRACE, `Writing ${formattedPath} file to the ${outputMode === "fs" ? "" : "virtual "}file system (size: ${prettyBytes(new Blob(toArray(code)).size)})`);
2379
- 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] = {
2380
1994
  mode: outputMode,
2381
1995
  variant: "normal",
2382
1996
  timestamp: Date.now(),
2383
- ...isVirtualFileData(data) ? data : {}
1997
+ ...metadata
2384
1998
  };
2385
- this.#clearResolverCache(formattedPath);
2386
- 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));
2387
2002
  try {
2388
2003
  writeStream.write(code);
2389
2004
  } finally {
@@ -2397,7 +2012,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2397
2012
  * @returns `true` if the file exists, otherwise `false`.
2398
2013
  */
2399
2014
  existsSync(pathOrId) {
2400
- return this.resolve(pathOrId) !== false;
2015
+ return !!this.resolveSync(pathOrId);
2401
2016
  }
2402
2017
  /**
2403
2018
  * Retrieves the metadata of a file in the virtual file system (VFS).
@@ -2406,7 +2021,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2406
2021
  * @returns The metadata of the file, or undefined if the file does not exist.
2407
2022
  */
2408
2023
  getMetadata(pathOrId) {
2409
- const resolved = this.resolve(pathOrId);
2024
+ const resolved = this.resolveSync(pathOrId);
2410
2025
  if (resolved && this.metadata[resolved]) {
2411
2026
  return this.metadata[resolved];
2412
2027
  }
@@ -2422,7 +2037,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2422
2037
  * @returns `true` if the file exists, otherwise `false`.
2423
2038
  */
2424
2039
  isFile(pathOrId) {
2425
- const resolved = this.resolve(pathOrId);
2040
+ const resolved = this.resolveSync(pathOrId);
2426
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()));
2427
2042
  }
2428
2043
  /**
@@ -2432,7 +2047,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2432
2047
  * @returns `true` if the directory exists, otherwise `false`.
2433
2048
  */
2434
2049
  isDirectory(pathOrId) {
2435
- const resolved = this.resolve(pathOrId);
2050
+ const resolved = this.resolveSync(pathOrId);
2436
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()));
2437
2052
  }
2438
2053
  /**
@@ -2442,7 +2057,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2442
2057
  * @returns A promise that resolves to the file's status information, or false if the file does not exist.
2443
2058
  */
2444
2059
  async stat(pathOrId, options) {
2445
- 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);
2446
2061
  }
2447
2062
  /**
2448
2063
  * Synchronously retrieves the status of a file in the virtual file system (VFS).
@@ -2451,7 +2066,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2451
2066
  * @returns The file's status information, or false if the file does not exist.
2452
2067
  */
2453
2068
  statSync(pathOrId) {
2454
- return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolve(toFilePath(pathOrId)) || toFilePath(pathOrId));
2069
+ return this.#unifiedFS.resolveFS(pathOrId).statSync(this.resolveSync(pathOrId) || pathOrId);
2455
2070
  }
2456
2071
  /**
2457
2072
  * Retrieves the status of a symbolic link in the virtual file system (VFS).
@@ -2460,7 +2075,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2460
2075
  * @returns A promise that resolves to the symbolic link's status information, or false if the link does not exist.
2461
2076
  */
2462
2077
  async lstat(pathOrId, options) {
2463
- 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);
2464
2079
  }
2465
2080
  /**
2466
2081
  * Synchronously retrieves the status of a symbolic link in the virtual file system (VFS).
@@ -2469,7 +2084,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2469
2084
  * @returns The symbolic link's status information, or false if the link does not exist.
2470
2085
  */
2471
2086
  lstatSync(pathOrId, options) {
2472
- 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);
2473
2088
  }
2474
2089
  /**
2475
2090
  * Resolves a path or ID to its real path in the virtual file system (VFS).
@@ -2478,52 +2093,113 @@ var VirtualFileSystem = class _VirtualFileSystem {
2478
2093
  * @returns The resolved real path if it exists, otherwise undefined.
2479
2094
  */
2480
2095
  realpathSync(pathOrId) {
2481
- const filePath = this.resolve(toFilePath(pathOrId));
2096
+ const filePath = this.resolveSync(pathOrId);
2482
2097
  if (!filePath) {
2483
- throw new Error(`File not found: ${toFilePath(pathOrId)}`);
2098
+ throw new Error(`File not found: ${pathOrId}`);
2484
2099
  }
2485
2100
  return filePath;
2486
2101
  }
2487
2102
  /**
2488
- * 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).
2489
2104
  *
2490
- * @param pathOrId - The path or ID to resolve.
2491
- * @param options - Optional parameters for resolving the path, such as whether to include the file extension.
2492
- * @returns The resolved file path if it exists, otherwise undefined.
2493
- */
2494
- resolve(pathOrId, options = {}) {
2495
- const formattedPathOrId = toFilePath(pathOrId);
2496
- const resolverKey = `${formattedPathOrId}${options.withExtension ? "-ext" : ""}${options.paths ? `-${murmurhash(options.paths)}` : ""}${options.pathType ? `-${options.pathType}` : ""}`;
2497
- if (this.#cachedResolver.has(resolverKey)) {
2498
- return this.#cachedResolver.get(resolverKey);
2499
- }
2500
- let result = this.#resolveId(formattedPathOrId);
2501
- if (!result) {
2502
- 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;
2503
2122
  }
2123
+ result = this.paths[this.#normalizeId(id)];
2504
2124
  if (!result) {
2505
- 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
+ }
2506
2146
  }
2507
- if (result && options.withExtension === false) {
2508
- 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);
2509
2150
  }
2510
- this.#cachedResolver.set(resolverKey, result);
2511
2151
  return result;
2512
2152
  }
2513
2153
  /**
2514
- * 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.
2515
2158
  *
2516
- * @param path - The relative path to convert.
2517
- * @returns The absolute path.
2518
- */
2519
- formatPath(path) {
2520
- const formattedPath = toFilePath(path);
2521
- if (isAbsolutePath(formattedPath) || formattedPath.startsWith(this.#context.workspaceConfig.workspaceRoot)) {
2522
- return formattedPath;
2523
- } else if (formattedPath.startsWith(this.#context.config.projectRoot)) {
2524
- 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
+ }
2525
2197
  }
2526
- 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;
2527
2203
  }
2528
2204
  /**
2529
2205
  * Disposes of the virtual file system (VFS) by saving its state to disk.
@@ -2532,7 +2208,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2532
2208
  if (!this.#isDisposed) {
2533
2209
  this.#isDisposed = true;
2534
2210
  this.#log(LogLevelLabel.DEBUG, "Disposing virtual file system...");
2535
- await this.unlink(joinPaths$1(this.#context.cachePath, "fs.bin"));
2211
+ await this.unlink(joinPaths$1(this.#context.dataPath, "fs.bin"));
2536
2212
  const message = new $.Message();
2537
2213
  const fs2 = message.initRoot(FileSystem);
2538
2214
  const virtualFS = this.#unifiedFS.toJSON();
@@ -2541,7 +2217,7 @@ var VirtualFileSystem = class _VirtualFileSystem {
2541
2217
  virtualFiles.forEach(([path, code], index) => {
2542
2218
  const fd = files.get(index);
2543
2219
  fd.path = path;
2544
- fd.code = code;
2220
+ fd.code = code || "";
2545
2221
  });
2546
2222
  const ids = fs2._initIds(Object.keys(this.ids).length);
2547
2223
  Object.entries(this.ids).forEach(([id, path], index) => {
@@ -2565,7 +2241,9 @@ var VirtualFileSystem = class _VirtualFileSystem {
2565
2241
  });
2566
2242
  }
2567
2243
  });
2568
- 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.");
2569
2247
  }
2570
2248
  }
2571
2249
  /**
@@ -2593,6 +2271,105 @@ var VirtualFileSystem = class _VirtualFileSystem {
2593
2271
  return this.dispose();
2594
2272
  }
2595
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");
2596
2373
 
2597
2374
  // ../powerlines/src/lib/contexts/context.ts
2598
2375
  var configCache = /* @__PURE__ */ new WeakMap();
@@ -2614,6 +2391,8 @@ var PowerlinesContext = class _PowerlinesContext {
2614
2391
  #envPaths;
2615
2392
  #fs;
2616
2393
  #tsconfig;
2394
+ #program;
2395
+ #resolvePatterns = [];
2617
2396
  #getConfigProps(config = {}) {
2618
2397
  return {
2619
2398
  variant: config.build?.variant,
@@ -2705,7 +2484,7 @@ var PowerlinesContext = class _PowerlinesContext {
2705
2484
  */
2706
2485
  get tsconfig() {
2707
2486
  if (!this.#tsconfig) {
2708
- this.#tsconfig = {
2487
+ this.tsconfig = {
2709
2488
  tsconfigFilePath: this.config.tsconfig
2710
2489
  };
2711
2490
  }
@@ -2716,6 +2495,7 @@ var PowerlinesContext = class _PowerlinesContext {
2716
2495
  */
2717
2496
  set tsconfig(value) {
2718
2497
  this.#tsconfig = value;
2498
+ this.#resolvePatterns = tsconfigPathsToRegExp(value?.options?.paths ?? {});
2719
2499
  }
2720
2500
  /**
2721
2501
  * The virtual file system interface for the project
@@ -2840,6 +2620,106 @@ var PowerlinesContext = class _PowerlinesContext {
2840
2620
  return Object.values(this.fs.metadata).filter((meta) => meta && meta.type === "builtin").map((meta) => meta?.id).filter(Boolean);
2841
2621
  }
2842
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
+ /**
2843
2723
  * Get the builtin virtual files that exist in the Powerlines virtual file system
2844
2724
  */
2845
2725
  async getBuiltins() {
@@ -3176,6 +3056,24 @@ var PowerlinesContext = class _PowerlinesContext {
3176
3056
  ret.push(plugin);
3177
3057
  return ret;
3178
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
+ }
3179
3077
  this.#fs ??= await VirtualFileSystem.create(this);
3180
3078
  }
3181
3079
  mergeUserConfig(from = {}, into = this.config.userConfig ?? {}) {
@@ -3605,13 +3503,9 @@ ${context.entry.map((entry) => `- ${entry.input.file || entry.file}${entry.outpu
3605
3503
  await resolveTsconfig(context);
3606
3504
  await installDependencies(context);
3607
3505
  await this.callPostHook(context, "configResolved");
3608
- if (context.config.build.polyfill) {
3609
- context.config.build.polyfill = context.config.build.polyfill.map((polyfill) => replacePathTokens(context, polyfill));
3610
- }
3611
3506
  context.log(LogLevelLabel.TRACE, `Powerlines configuration has been resolved:
3612
3507
 
3613
3508
  ${formatLogMessage(context.config)}`);
3614
- context.fs[__VFS_PATCH__]();
3615
3509
  await writeMetaFile(context);
3616
3510
  context.persistedMeta = context.meta;
3617
3511
  if (!existsSync(context.cachePath)) {
@@ -3661,35 +3555,19 @@ ${formatLogMessage(context.config)}`);
3661
3555
  if (!typescriptPath) {
3662
3556
  throw new Error("Could not resolve TypeScript package location. Please ensure TypeScript is installed.");
3663
3557
  }
3664
- const files = builtinFilePaths.reduce((ret, fileName) => {
3665
- const formatted = replacePath(fileName, context.workspaceConfig.workspaceRoot);
3666
- if (!ret.includes(formatted)) {
3667
- ret.push(formatted);
3668
- }
3669
- return ret;
3670
- }, [
3671
- joinPaths$1(typescriptPath, "lib", "lib.esnext.full.d.ts")
3672
- ]);
3673
- context.log(LogLevelLabel.TRACE, "Parsing TypeScript configuration for the Powerlines project.");
3674
- const resolvedTsconfig = getParsedTypeScriptConfig(context.workspaceConfig.workspaceRoot, context.config.projectRoot, context.tsconfig.tsconfigFilePath, defu5({
3675
- compilerOptions: {
3676
- strict: false,
3677
- noEmit: false,
3678
- declaration: true,
3679
- declarationMap: false,
3680
- emitDeclarationOnly: true,
3681
- 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;
3682
3565
  },
3683
- exclude: [
3684
- "node_modules",
3685
- "dist"
3686
- ],
3687
- include: files
3688
- }, context.config.tsconfigRaw ?? {}));
3689
- resolvedTsconfig.options.configFilePath = joinPaths$1(context.workspaceConfig.workspaceRoot, context.tsconfig.tsconfigFilePath);
3690
- resolvedTsconfig.options.pathsBasePath = context.workspaceConfig.workspaceRoot;
3691
- resolvedTsconfig.options.suppressOutputPathCheck = true;
3692
- 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);
3693
3571
  context.log(LogLevelLabel.TRACE, `Generating TypeScript declaration file in ${context.config.output.dts}.`);
3694
3572
  const directives = [];
3695
3573
  let result = await this.callPreHook(context, "generateTypes", generatedTypes);
@@ -3743,7 +3621,6 @@ ${formatTypes(generatedTypes)}
3743
3621
  }
3744
3622
  await this.callPostHook(context, "prepare");
3745
3623
  await writeMetaFile(context);
3746
- context.fs[__VFS_REVERT__]();
3747
3624
  });
3748
3625
  this.context.log(LogLevelLabel.INFO, "Powerlines API has been prepared successfully");
3749
3626
  }