@typespec/compiler 0.61.0-dev.18 → 0.61.0-dev.19

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 (41) hide show
  1. package/dist/manifest.js +2 -2
  2. package/dist/src/core/messages.d.ts +5 -10
  3. package/dist/src/core/messages.d.ts.map +1 -1
  4. package/dist/src/core/messages.js +1 -2
  5. package/dist/src/core/messages.js.map +1 -1
  6. package/dist/src/core/program.d.ts.map +1 -1
  7. package/dist/src/core/program.js +7 -29
  8. package/dist/src/core/program.js.map +1 -1
  9. package/dist/src/core/source-loader.d.ts +2 -0
  10. package/dist/src/core/source-loader.d.ts.map +1 -1
  11. package/dist/src/core/source-loader.js +26 -12
  12. package/dist/src/core/source-loader.js.map +1 -1
  13. package/dist/src/module-resolver/esm/resolve-package-exports.d.ts +9 -0
  14. package/dist/src/module-resolver/esm/resolve-package-exports.d.ts.map +1 -0
  15. package/dist/src/module-resolver/esm/resolve-package-exports.js +58 -0
  16. package/dist/src/module-resolver/esm/resolve-package-exports.js.map +1 -0
  17. package/dist/src/module-resolver/esm/resolve-package-imports-exports.d.ts +11 -0
  18. package/dist/src/module-resolver/esm/resolve-package-imports-exports.d.ts.map +1 -0
  19. package/dist/src/module-resolver/esm/resolve-package-imports-exports.js +72 -0
  20. package/dist/src/module-resolver/esm/resolve-package-imports-exports.js.map +1 -0
  21. package/dist/src/module-resolver/esm/resolve-package-target.d.ts +10 -0
  22. package/dist/src/module-resolver/esm/resolve-package-target.d.ts.map +1 -0
  23. package/dist/src/module-resolver/esm/resolve-package-target.js +133 -0
  24. package/dist/src/module-resolver/esm/resolve-package-target.js.map +1 -0
  25. package/dist/src/module-resolver/esm/utils.d.ts +35 -0
  26. package/dist/src/module-resolver/esm/utils.d.ts.map +1 -0
  27. package/dist/src/module-resolver/esm/utils.js +40 -0
  28. package/dist/src/module-resolver/esm/utils.js.map +1 -0
  29. package/dist/src/module-resolver/module-resolver.d.ts +15 -5
  30. package/dist/src/module-resolver/module-resolver.d.ts.map +1 -1
  31. package/dist/src/module-resolver/module-resolver.js +147 -44
  32. package/dist/src/module-resolver/module-resolver.js.map +1 -1
  33. package/dist/src/module-resolver/utils.d.ts +6 -0
  34. package/dist/src/module-resolver/utils.d.ts.map +1 -0
  35. package/dist/src/module-resolver/utils.js +16 -0
  36. package/dist/src/module-resolver/utils.js.map +1 -0
  37. package/dist/src/testing/test-host.js +1 -1
  38. package/dist/src/testing/test-host.js.map +1 -1
  39. package/dist/src/types/package-json.d.ts +2 -2
  40. package/dist/src/types/package-json.d.ts.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,72 @@
1
+ import { resolvePackageTarget } from "./resolve-package-target.js";
2
+ import { InvalidModuleSpecifierError } from "./utils.js";
3
+ /** Implementation of PACKAGE_IMPORTS_EXPORTS_RESOLVE https://github.com/nodejs/node/blob/main/doc/api/esm.md */
4
+ export async function resolvePackageImportsExports(context, { matchKey, matchObj, isImports }) {
5
+ // If matchKey is a key of matchObj and does not contain "*", then
6
+ if (!matchKey.includes("*") && matchKey in matchObj) {
7
+ // Let target be the value of matchObj[matchKey].
8
+ const target = matchObj[matchKey];
9
+ // Return the result of PACKAGE_TARGET_RESOLVE(packageURL, target, null, isImports, conditions).
10
+ const resolved = await resolvePackageTarget(context, { target, patternMatch: "", isImports });
11
+ return resolved;
12
+ }
13
+ // Let expansionKeys be the list of keys of matchObj containing only a single "*"
14
+ const expansionKeys = Object.keys(matchObj)
15
+ // Assert: ends with "/" or contains only a single "*".
16
+ .filter((k) => k.endsWith("/") || k.includes("*"))
17
+ // sorted by the sorting function PATTERN_KEY_COMPARE which orders in descending order of specificity.
18
+ .sort(nodePatternKeyCompare);
19
+ // For each key expansionKey in expansionKeys, do
20
+ for (const expansionKey of expansionKeys) {
21
+ const indexOfAsterisk = expansionKey.indexOf("*");
22
+ // Let patternBase be the substring of expansionKey up to but excluding the first "*" character.
23
+ const patternBase = indexOfAsterisk === -1 ? expansionKey : expansionKey.substring(0, indexOfAsterisk);
24
+ // If matchKey starts with but is not equal to patternBase, then
25
+ if (matchKey.startsWith(patternBase) && matchKey !== patternBase) {
26
+ // Let patternTrailer be the substring of expansionKey from the index after the first "*" character.
27
+ const patternTrailer = indexOfAsterisk !== -1 ? expansionKey.substring(indexOfAsterisk + 1) : "";
28
+ // If patternTrailer has zero length,
29
+ if (patternTrailer.length === 0 ||
30
+ // or if matchKey ends with patternTrailer and the length of matchKey is greater than or equal to the length of expansionKey, then
31
+ (matchKey.endsWith(patternTrailer) && matchKey.length >= expansionKey.length)) {
32
+ // Let target be the value of matchObj[expansionKey].
33
+ const target = matchObj[expansionKey];
34
+ // Let patternMatch be the substring of matchKey starting at the index of the length of patternBase up to the length
35
+ // of matchKey minus the length of patternTrailer.
36
+ const patternMatch = matchKey.substring(patternBase.length, matchKey.length - patternTrailer.length);
37
+ // Return the result of PACKAGE_TARGET_RESOLVE
38
+ const resolved = await resolvePackageTarget(context, {
39
+ target,
40
+ patternMatch,
41
+ isImports,
42
+ });
43
+ return resolved;
44
+ }
45
+ }
46
+ }
47
+ throw new InvalidModuleSpecifierError(context, isImports);
48
+ }
49
+ /**
50
+ * Implementation of Node's `PATTERN_KEY_COMPARE` function
51
+ */
52
+ function nodePatternKeyCompare(keyA, keyB) {
53
+ // Let baseLengthA be the index of "*" in keyA plus one, if keyA contains "*", or the length of keyA otherwise.
54
+ const baseLengthA = keyA.includes("*") ? keyA.indexOf("*") + 1 : keyA.length;
55
+ // Let baseLengthB be the index of "*" in keyB plus one, if keyB contains "*", or the length of keyB otherwise.
56
+ const baseLengthB = keyB.includes("*") ? keyB.indexOf("*") + 1 : keyB.length;
57
+ // if baseLengthA is greater, return -1, if lower 1
58
+ const rval = baseLengthB - baseLengthA;
59
+ if (rval !== 0)
60
+ return rval;
61
+ // If keyA does not contain "*", return 1.
62
+ if (!keyA.includes("*"))
63
+ return 1;
64
+ // If keyB does not contain "*", return -1.
65
+ if (!keyB.includes("*"))
66
+ return -1;
67
+ // If the length of keyA is greater than the length of keyB, return -1.
68
+ // If the length of keyB is greater than the length of keyA, return 1.
69
+ // Else Return 0.
70
+ return keyB.length - keyA.length;
71
+ }
72
+ //# sourceMappingURL=resolve-package-imports-exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-package-imports-exports.js","sourceRoot":"","sources":["../../../../src/module-resolver/esm/resolve-package-imports-exports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Exports } from "../../types/package-json.js";
2
+ import { EsmResolutionContext } from "./utils.js";
3
+ export interface ResolvePackageTargetOptions {
4
+ readonly target: Exports;
5
+ readonly patternMatch?: string;
6
+ readonly isImports?: boolean;
7
+ }
8
+ /** Implementation of PACKAGE_TARGET_RESOLVE https://github.com/nodejs/node/blob/main/doc/api/esm.md */
9
+ export declare function resolvePackageTarget(context: EsmResolutionContext, { target, patternMatch, isImports }: ResolvePackageTargetOptions): Promise<null | undefined | string>;
10
+ //# sourceMappingURL=resolve-package-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-package-target.d.ts","sourceRoot":"","sources":["../../../../src/module-resolver/esm/resolve-package-target.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EACL,oBAAoB,EAIrB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,uGAAuG;AACvG,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,oBAAoB,EAC7B,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,2BAA2B,GAC/D,OAAO,CAAC,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,CAgIpC"}
@@ -0,0 +1,133 @@
1
+ import { resolvePath } from "../../core/path-utils.js";
2
+ import { InvalidModuleSpecifierError, InvalidPackageTargetError, isUrl, } from "./utils.js";
3
+ /** Implementation of PACKAGE_TARGET_RESOLVE https://github.com/nodejs/node/blob/main/doc/api/esm.md */
4
+ export async function resolvePackageTarget(context, { target, patternMatch, isImports }) {
5
+ const { packageUrl } = context;
6
+ const packageUrlWithTrailingSlash = packageUrl.endsWith("/") ? packageUrl : `${packageUrl}/`;
7
+ // 1. If target is a String, then
8
+ if (typeof target === "string") {
9
+ // 1.i If target does not start with "./", then
10
+ if (!target.startsWith("./")) {
11
+ // 1.i.a If isImports is false, or if target starts with "../" or "/", or if target is a valid URL, then
12
+ if (!isImports || target.startsWith("../") || target.startsWith("/") || isUrl(target)) {
13
+ // 1.i.a.a Throw an Invalid Package Target error.
14
+ throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
15
+ }
16
+ // 1.i.b If patternMatch is a String, then
17
+ if (typeof patternMatch === "string") {
18
+ // 1.i.b.a Return PACKAGE_RESOLVE(target with every instance of "*" replaced by patternMatch, packageURL + "/")
19
+ return await context.resolveId(target.replace(/\*/g, patternMatch), packageUrlWithTrailingSlash);
20
+ }
21
+ // 1.i.c Return PACKAGE_RESOLVE(target, packageURL + "/").
22
+ return await context.resolveId(target, packageUrlWithTrailingSlash);
23
+ }
24
+ // 1.ii If target split on "/" or "\"
25
+ checkInvalidSegment(context, target);
26
+ // 1.iii Let resolvedTarget be the URL resolution of the concatenation of packageURL and target.
27
+ const resolvedTarget = resolvePath(packageUrlWithTrailingSlash, target);
28
+ // 1.iv Assert: resolvedTarget is contained in packageURL.
29
+ if (!resolvedTarget.startsWith(packageUrl)) {
30
+ throw new InvalidPackageTargetError(context, `Resolved to ${resolvedTarget} which is outside package ${packageUrl}`);
31
+ }
32
+ // 1.v If patternMatch is null, then
33
+ if (!patternMatch) {
34
+ // Return resolvedTarget.
35
+ return resolvedTarget;
36
+ }
37
+ // 1.vi If patternMatch split on "/" or "\" contains invalid segments
38
+ if (includesInvalidSegments(patternMatch.split(/\/|\\/), context.moduleDirs)) {
39
+ // throw an Invalid Module Specifier error.
40
+ throw new InvalidModuleSpecifierError(context);
41
+ }
42
+ // 1.vii Return the URL resolution of resolvedTarget with every instance of "*" replaced with patternMatch.
43
+ return resolvedTarget.replace(/\*/g, patternMatch);
44
+ }
45
+ // 3. Otherwise, if target is an Array, then
46
+ if (Array.isArray(target)) {
47
+ // 3.i If _target.length is zero, return null.
48
+ if (target.length === 0) {
49
+ return null;
50
+ }
51
+ let lastError = null;
52
+ // 3.ii For each item in target, do
53
+ for (const item of target) {
54
+ // Let resolved be the result of PACKAGE_TARGET_RESOLVE of the item
55
+ // continuing the loop on any Invalid Package Target error.
56
+ try {
57
+ const resolved = await resolvePackageTarget(context, {
58
+ target: item,
59
+ patternMatch,
60
+ isImports,
61
+ });
62
+ // If resolved is undefined, continue the loop.
63
+ // Else Return resolved.
64
+ if (resolved !== undefined) {
65
+ return resolved;
66
+ }
67
+ }
68
+ catch (error) {
69
+ if (!(error instanceof InvalidPackageTargetError)) {
70
+ throw error;
71
+ }
72
+ else {
73
+ lastError = error;
74
+ }
75
+ }
76
+ }
77
+ // Return or throw the last fallback resolution null return or error
78
+ if (lastError) {
79
+ throw lastError;
80
+ }
81
+ return null;
82
+ }
83
+ // 2. Otherwise, if target is a non-null Object, then
84
+ if (target && typeof target === "object") {
85
+ // 2.ii For each property of target
86
+ for (const [key, value] of Object.entries(target)) {
87
+ // 2.ii.a If key equals "default" or conditions contains an entry for the key, then
88
+ if ((key === "default" && !context.ignoreDefaultCondition) ||
89
+ context.conditions.includes(key)) {
90
+ // Let targetValue be the value of the property in target.
91
+ // Let resolved be the result of PACKAGE_TARGET_RESOLVE of the targetValue
92
+ const resolved = await resolvePackageTarget(context, {
93
+ target: value,
94
+ patternMatch,
95
+ isImports,
96
+ });
97
+ // If resolved is equal to undefined, continue the loop.
98
+ // Return resolved.
99
+ if (resolved !== undefined) {
100
+ return resolved;
101
+ }
102
+ }
103
+ }
104
+ // Return undefined.
105
+ return undefined;
106
+ }
107
+ // Otherwise, if target is null, return null.
108
+ if (target === null) {
109
+ return null;
110
+ }
111
+ // Otherwise throw an Invalid Package Target error.
112
+ throw new InvalidPackageTargetError(context, `Invalid exports field.`);
113
+ }
114
+ /**
115
+ * Check for invalid path segments
116
+ */
117
+ function includesInvalidSegments(pathSegments, moduleDirs) {
118
+ const invalidSegments = ["", ".", "..", ...moduleDirs];
119
+ // contains any "", ".", "..", or "node_modules" segments, including percent encoded variants
120
+ return pathSegments.some((v) => invalidSegments.includes(v) || invalidSegments.includes(decodeURI(v)));
121
+ }
122
+ function checkInvalidSegment(context, target) {
123
+ const pathSegments = target.split(/\/|\\/);
124
+ // after the first "." segment
125
+ const firstDot = pathSegments.indexOf(".");
126
+ firstDot !== -1 && pathSegments.slice(firstDot);
127
+ if (firstDot !== -1 &&
128
+ firstDot < pathSegments.length - 1 &&
129
+ includesInvalidSegments(pathSegments.slice(firstDot + 1), context.moduleDirs)) {
130
+ throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
131
+ }
132
+ }
133
+ //# sourceMappingURL=resolve-package-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-package-target.js","sourceRoot":"","sources":["../../../../src/module-resolver/esm/resolve-package-target.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface EsmResolutionContext {
2
+ /** Original import specifier */
3
+ readonly specifier: string;
4
+ /** URL of the current package */
5
+ readonly packageUrl: string;
6
+ /**
7
+ * List of condition to match
8
+ * @example `["import", "require"]`
9
+ */
10
+ readonly conditions: readonly string[];
11
+ /**
12
+ * Folders where modules exist that are banned from being used in exports.
13
+ * @example `["node_modules"]`
14
+ */
15
+ readonly moduleDirs: readonly string[];
16
+ resolveId(id: string, baseDir: string | URL): any;
17
+ /** Non standard option. Do not respect the default condition. */
18
+ readonly ignoreDefaultCondition?: boolean;
19
+ }
20
+ export declare class EsmResolveError extends Error {
21
+ }
22
+ export declare class InvalidConfigurationError extends EsmResolveError {
23
+ constructor(context: EsmResolutionContext, reason?: string);
24
+ }
25
+ export declare class InvalidModuleSpecifierError extends EsmResolveError {
26
+ constructor(context: EsmResolutionContext, isImports?: boolean, reason?: string);
27
+ }
28
+ export declare class InvalidPackageTargetError extends EsmResolveError {
29
+ constructor(context: EsmResolutionContext, reason?: string);
30
+ }
31
+ export declare class NoMatchingConditionsError extends InvalidPackageTargetError {
32
+ constructor(context: EsmResolutionContext);
33
+ }
34
+ export declare function isUrl(str: string): boolean;
35
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/module-resolver/esm/utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,iCAAiC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAEvC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC;IAElD,iEAAiE;IACjE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C;AAaD,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AAE7C,qBAAa,yBAA0B,SAAQ,eAAe;gBAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,MAAM;CAG3D;AAED,qBAAa,2BAA4B,SAAQ,eAAe;gBAClD,OAAO,EAAE,oBAAoB,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM;CAGhF;AAED,qBAAa,yBAA0B,SAAQ,eAAe;gBAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,MAAM;CAG3D;AAED,qBAAa,yBAA0B,SAAQ,yBAAyB;gBAC1D,OAAO,EAAE,oBAAoB;CAG1C;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,WAMhC"}
@@ -0,0 +1,40 @@
1
+ function createBaseErrorMsg(importSpecifier) {
2
+ return `Could not resolve import "${importSpecifier}" `;
3
+ }
4
+ function createErrorMsg(context, reason, isImports) {
5
+ const { specifier, packageUrl } = context;
6
+ const base = createBaseErrorMsg(specifier);
7
+ const field = isImports ? "imports" : "exports";
8
+ return `${base} using ${field} defined in ${packageUrl}.${reason ? ` ${reason}` : ""}`;
9
+ }
10
+ export class EsmResolveError extends Error {
11
+ }
12
+ export class InvalidConfigurationError extends EsmResolveError {
13
+ constructor(context, reason) {
14
+ super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
15
+ }
16
+ }
17
+ export class InvalidModuleSpecifierError extends EsmResolveError {
18
+ constructor(context, isImports, reason) {
19
+ super(createErrorMsg(context, reason, isImports));
20
+ }
21
+ }
22
+ export class InvalidPackageTargetError extends EsmResolveError {
23
+ constructor(context, reason) {
24
+ super(createErrorMsg(context, reason));
25
+ }
26
+ }
27
+ export class NoMatchingConditionsError extends InvalidPackageTargetError {
28
+ constructor(context) {
29
+ super(context, `No conditions matched`);
30
+ }
31
+ }
32
+ export function isUrl(str) {
33
+ try {
34
+ return !!new URL(str);
35
+ }
36
+ catch (_) {
37
+ return false;
38
+ }
39
+ }
40
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/module-resolver/esm/utils.ts"],"names":[],"mappings":"AAyBA,SAAS,kBAAkB,CAAC,eAAuB;IACjD,OAAO,6BAA6B,eAAe,IAAI,CAAC;AAC1D,CAAC;AAED,SAAS,cAAc,CAAC,OAA6B,EAAE,MAAe,EAAE,SAAmB;IACzF,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC1C,MAAM,IAAI,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,OAAO,GAAG,IAAI,UAAU,KAAK,eAAe,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;CAAG;AAE7C,MAAM,OAAO,yBAA0B,SAAQ,eAAe;IAC5D,YAAY,OAA6B,EAAE,MAAe;QACxD,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,4BAA4B,MAAM,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,eAAe;IAC9D,YAAY,OAA6B,EAAE,SAAmB,EAAE,MAAe;QAC7E,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACpD,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,eAAe;IAC5D,YAAY,OAA6B,EAAE,MAAe;QACxD,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,yBAAyB;IACtE,YAAY,OAA6B;QACvC,KAAK,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,CAAC;QACH,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { PackageJson } from "../types/package-json.js";
1
+ import type { PackageJson } from "../types/package-json.js";
2
2
  export interface ResolveModuleOptions {
3
3
  baseDir: string;
4
4
  /**
@@ -8,9 +8,16 @@ export interface ResolveModuleOptions {
8
8
  resolveMain?: (pkg: any) => string;
9
9
  /**
10
10
  * When resolution reach a directory without package.json look for those files to load in order.
11
- * @default ["index.mjs", "index.js"]
11
+ * @default `["index.mjs", "index.js"]`
12
12
  */
13
13
  directoryIndexFiles?: string[];
14
+ /** List of conditions to match in package exports */
15
+ readonly conditions?: string[];
16
+ /**
17
+ * If exports is defined ignore if the none of the given condition is found and fallback to using main field resolution.
18
+ * By default it will throw an error.
19
+ */
20
+ readonly fallbackOnMissingCondition?: boolean;
14
21
  }
15
22
  export interface ResolveModuleHost {
16
23
  /**
@@ -29,7 +36,9 @@ export interface ResolveModuleHost {
29
36
  */
30
37
  readFile(path: string): Promise<string>;
31
38
  }
32
- type ResolveModuleErrorCode = "MODULE_NOT_FOUND" | "INVALID_MAIN";
39
+ type ResolveModuleErrorCode = "MODULE_NOT_FOUND" | "INVALID_MAIN" | "INVALID_MODULE"
40
+ /** When an exports points to an invalid file. */
41
+ | "INVALID_MODULE_EXPORT_TARGET";
33
42
  export declare class ResolveModuleError extends Error {
34
43
  code: ResolveModuleErrorCode;
35
44
  constructor(code: ResolveModuleErrorCode, message: string);
@@ -57,10 +66,11 @@ export interface ResolvedModule {
57
66
  /**
58
67
  * Resolve a module
59
68
  * @param host
60
- * @param name
69
+ * @param specifier
61
70
  * @param options
62
71
  * @returns
72
+ * @throws {ResolveModuleError} When the module cannot be resolved.
63
73
  */
64
- export declare function resolveModule(host: ResolveModuleHost, name: string, options: ResolveModuleOptions): Promise<ModuleResolutionResult>;
74
+ export declare function resolveModule(host: ResolveModuleHost, specifier: string, options: ResolveModuleOptions): Promise<ModuleResolutionResult>;
65
75
  export {};
66
76
  //# sourceMappingURL=module-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module-resolver.d.ts","sourceRoot":"","sources":["../../../src/module-resolver/module-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC;IAEnC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,IAAI,OAAO,CAAC;QAAC,MAAM,IAAI,OAAO,CAAA;KAAE,CAAC,CAAC;IAE3E;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,KAAK,sBAAsB,GAAG,kBAAkB,GAAG,cAAc,CAAC;AAClE,qBAAa,kBAAmB,SAAQ,KAAK;IAElC,IAAI,EAAE,sBAAsB;gBAA5B,IAAI,EAAE,sBAAsB,EACnC,OAAO,EAAE,MAAM;CAIlB;AAID,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,cAAc,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAgKjC"}
1
+ {"version":3,"file":"module-resolver.d.ts","sourceRoot":"","sources":["../../../src/module-resolver/module-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAW5D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC;IAEnC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,IAAI,OAAO,CAAC;QAAC,MAAM,IAAI,OAAO,CAAA;KAAE,CAAC,CAAC;IAE3E;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,KAAK,sBAAsB,GACvB,kBAAkB,GAClB,cAAc,GACd,gBAAgB;AAClB,iDAAiD;GAC/C,8BAA8B,CAAC;AACnC,qBAAa,kBAAmB,SAAQ,KAAK;IAElC,IAAI,EAAE,sBAAsB;gBAA5B,IAAI,EAAE,sBAAsB,EACnC,OAAO,EAAE,MAAM;CAIlB;AAID,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,cAAc,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAoPjC"}
@@ -1,4 +1,7 @@
1
- import { getDirectoryPath, joinPaths, resolvePath } from "../core/path-utils.js";
1
+ import { getDirectoryPath, joinPaths, normalizePath, resolvePath } from "../core/path-utils.js";
2
+ import { resolvePackageExports } from "./esm/resolve-package-exports.js";
3
+ import { EsmResolveError, InvalidPackageTargetError, NoMatchingConditionsError, } from "./esm/utils.js";
4
+ import { parseNodeModuleSpecifier } from "./utils.js";
2
5
  export class ResolveModuleError extends Error {
3
6
  code;
4
7
  constructor(code, message) {
@@ -10,33 +13,39 @@ const defaultDirectoryIndexFiles = ["index.mjs", "index.js"];
10
13
  /**
11
14
  * Resolve a module
12
15
  * @param host
13
- * @param name
16
+ * @param specifier
14
17
  * @param options
15
18
  * @returns
19
+ * @throws {ResolveModuleError} When the module cannot be resolved.
16
20
  */
17
- export async function resolveModule(host, name, options) {
18
- const realpath = async (x) => resolvePath(await host.realpath(x));
21
+ export async function resolveModule(host, specifier, options) {
22
+ const realpath = async (x) => normalizePath(await host.realpath(x));
19
23
  const { baseDir } = options;
20
- const absoluteStart = baseDir === "" ? "." : await realpath(resolvePath(baseDir));
24
+ const absoluteStart = await realpath(resolvePath(baseDir));
21
25
  if (!(await isDirectory(host, absoluteStart))) {
22
26
  throw new TypeError(`Provided basedir '${baseDir}'is not a directory.`);
23
27
  }
24
28
  // Check if the module name is referencing a path(./foo, /foo, file:/foo)
25
- if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(name)) {
26
- const res = resolvePath(absoluteStart, name);
29
+ if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(specifier)) {
30
+ const res = resolvePath(absoluteStart, specifier);
27
31
  const m = (await loadAsFile(res)) || (await loadAsDirectory(res));
28
32
  if (m) {
29
33
  return m;
30
34
  }
31
35
  }
32
- const module = await findAsNodeModule(name, absoluteStart);
36
+ // Try to resolve package itself.
37
+ const self = await resolveSelf(specifier, absoluteStart);
38
+ if (self)
39
+ return self;
40
+ // Try to resolve as a node_module package.
41
+ const module = await resolveAsNodeModule(specifier, absoluteStart);
33
42
  if (module)
34
43
  return module;
35
- throw new ResolveModuleError("MODULE_NOT_FOUND", `Cannot find module '${name}' from '${baseDir}'`);
44
+ throw new ResolveModuleError("MODULE_NOT_FOUND", `Cannot find module '${specifier}' from '${baseDir}'`);
36
45
  /**
37
46
  * Returns a list of all the parent directory and the given one.
38
47
  */
39
- function listAllParentDirs(baseDir) {
48
+ function listDirHierarchy(baseDir) {
40
49
  const paths = [baseDir];
41
50
  let current = getDirectoryPath(baseDir);
42
51
  while (current !== paths[paths.length - 1]) {
@@ -45,45 +54,113 @@ export async function resolveModule(host, name, options) {
45
54
  }
46
55
  return paths;
47
56
  }
48
- function getPackageCandidates(name, baseDir) {
49
- const dirs = listAllParentDirs(baseDir);
50
- return dirs.flatMap((x) => [
51
- { path: x, type: "self" },
52
- { path: joinPaths(x, "node_modules", name), type: "node_modules" },
53
- ]);
54
- }
55
- async function findAsNodeModule(name, baseDir) {
56
- const dirs = getPackageCandidates(name, baseDir);
57
- for (const { type, path } of dirs) {
58
- if (type === "node_modules") {
59
- if (await isDirectory(host, path)) {
60
- const n = await loadAsDirectory(path, true);
61
- if (n)
62
- return n;
63
- }
57
+ /**
58
+ * Equivalent implementation to node LOAD_PACKAGE_SELF
59
+ * Resolve if the import is importing the current package.
60
+ */
61
+ async function resolveSelf(name, baseDir) {
62
+ for (const dir of listDirHierarchy(baseDir)) {
63
+ const pkgFile = resolvePath(dir, "package.json");
64
+ if (!(await isFile(host, pkgFile)))
65
+ continue;
66
+ const pkg = await readPackage(host, pkgFile);
67
+ if (pkg.name === name) {
68
+ return loadPackage(dir, pkg);
64
69
  }
65
- else if (type === "self") {
66
- const pkgFile = resolvePath(path, "package.json");
67
- if (await isFile(host, pkgFile)) {
68
- const pkg = await readPackage(host, pkgFile);
69
- if (pkg.name === name) {
70
- const n = await loadPackage(path, pkg);
71
- if (n)
72
- return n;
73
- }
74
- }
70
+ else {
71
+ return undefined;
75
72
  }
76
73
  }
77
74
  return undefined;
78
75
  }
79
- async function loadAsDirectory(directory, mustBePackage) {
80
- const pkgFile = resolvePath(directory, "package.json");
81
- if (await isFile(host, pkgFile)) {
82
- const pkg = await readPackage(host, pkgFile);
83
- return loadPackage(directory, pkg);
76
+ /**
77
+ * Equivalent implementation to node LOAD_NODE_MODULES with a few non supported features.
78
+ * Cannot load any random file under the load path(only packages).
79
+ */
80
+ async function resolveAsNodeModule(importSpecifier, baseDir) {
81
+ const module = parseNodeModuleSpecifier(importSpecifier);
82
+ if (module === null)
83
+ return undefined;
84
+ const dirs = listDirHierarchy(baseDir);
85
+ for (const dir of dirs) {
86
+ const n = await loadPackageAtPath(joinPaths(dir, "node_modules", module.packageName), module.subPath);
87
+ if (n)
88
+ return n;
84
89
  }
85
- if (mustBePackage) {
90
+ return undefined;
91
+ }
92
+ async function loadPackageAtPath(path, subPath) {
93
+ const pkgFile = resolvePath(path, "package.json");
94
+ if (!(await isFile(host, pkgFile)))
86
95
  return undefined;
96
+ const pkg = await readPackage(host, pkgFile);
97
+ const n = await loadPackage(path, pkg, subPath);
98
+ if (n)
99
+ return n;
100
+ return undefined;
101
+ }
102
+ /**
103
+ * Try to load using package.json exports.
104
+ * @param importSpecifier A combination of the package name and exports entry.
105
+ * @param directory `node_modules` directory.
106
+ */
107
+ async function resolveNodePackageExports(subPath, pkg, pkgDir) {
108
+ if (!pkg.exports)
109
+ return undefined;
110
+ let match;
111
+ try {
112
+ match = await resolvePackageExports({
113
+ packageUrl: pathToFileURL(pkgDir),
114
+ specifier: specifier,
115
+ moduleDirs: ["node_modules"],
116
+ conditions: options.conditions ?? [],
117
+ ignoreDefaultCondition: options.fallbackOnMissingCondition,
118
+ resolveId: (id, baseDir) => {
119
+ throw new ResolveModuleError("INVALID_MODULE", "Not supported");
120
+ },
121
+ }, subPath === "" ? "." : `./${subPath}`, pkg.exports);
122
+ }
123
+ catch (error) {
124
+ if (error instanceof NoMatchingConditionsError) {
125
+ // For back compat we allow to fallback to main field for the `.` entry.
126
+ if (subPath === "") {
127
+ return;
128
+ }
129
+ else {
130
+ throw new ResolveModuleError("INVALID_MODULE", error.message);
131
+ }
132
+ }
133
+ else if (error instanceof InvalidPackageTargetError) {
134
+ throw new ResolveModuleError("INVALID_MODULE_EXPORT_TARGET", error.message);
135
+ }
136
+ else if (error instanceof EsmResolveError) {
137
+ throw new ResolveModuleError("INVALID_MODULE", error.message);
138
+ }
139
+ else {
140
+ throw error;
141
+ }
142
+ }
143
+ if (!match)
144
+ return undefined;
145
+ const resolved = await resolveEsmMatch(match);
146
+ return {
147
+ type: "module",
148
+ mainFile: resolved,
149
+ manifest: pkg,
150
+ path: pkgDir,
151
+ };
152
+ }
153
+ async function resolveEsmMatch(match) {
154
+ const resolved = await realpath(fileURLToPath(match));
155
+ if (await isFile(host, resolved)) {
156
+ return resolved;
157
+ }
158
+ throw new ResolveModuleError("INVALID_MODULE_EXPORT_TARGET", `Import "${specifier}" resolving to "${resolved}" is not a file.`);
159
+ }
160
+ async function loadAsDirectory(directory) {
161
+ const pkg = await loadPackageAtPath(directory);
162
+ if (pkg) {
163
+ return pkg;
87
164
  }
88
165
  for (const file of options.directoryIndexFiles ?? defaultDirectoryIndexFiles) {
89
166
  const resolvedFile = await loadAsFile(joinPaths(directory, file));
@@ -93,7 +170,16 @@ export async function resolveModule(host, name, options) {
93
170
  }
94
171
  return undefined;
95
172
  }
96
- async function loadPackage(directory, pkg) {
173
+ async function loadPackage(directory, pkg, subPath) {
174
+ const e = await resolveNodePackageExports(subPath ?? "", pkg, directory);
175
+ if (e)
176
+ return e;
177
+ if (subPath !== undefined && subPath !== "") {
178
+ return undefined;
179
+ }
180
+ return loadPackageLegacy(directory, pkg);
181
+ }
182
+ async function loadPackageLegacy(directory, pkg) {
97
183
  const mainFile = options.resolveMain ? options.resolveMain(pkg) : pkg.main;
98
184
  if (typeof mainFile !== "string") {
99
185
  throw new TypeError(`package "${pkg.name}" main must be a string but was '${mainFile}'`);
@@ -118,7 +204,7 @@ export async function resolveModule(host, name, options) {
118
204
  };
119
205
  }
120
206
  else {
121
- throw new ResolveModuleError("INVALID_MAIN", `Package ${pkg.name} main file "${mainFile}" is invalid.`);
207
+ throw new ResolveModuleError("INVALID_MAIN", `Package ${pkg.name} main file "${mainFile}" is not pointing to a valid file or directory.`);
122
208
  }
123
209
  }
124
210
  async function loadAsFile(file) {
@@ -166,4 +252,21 @@ async function isFile(host, path) {
166
252
  throw e;
167
253
  }
168
254
  }
255
+ function pathToFileURL(path) {
256
+ return `file://${path}`;
257
+ }
258
+ function fileURLToPath(url) {
259
+ if (!url.startsWith("file://"))
260
+ throw new Error("Cannot convert non file: URL to path");
261
+ const pathname = url.slice("file://".length);
262
+ for (let n = 0; n < pathname.length; n++) {
263
+ if (pathname[n] === "%") {
264
+ const third = pathname.codePointAt(n + 2) | 0x20;
265
+ if (pathname[n + 1] === "2" && third === 102) {
266
+ throw new Error("Invalid url to path: must not include encoded / characters");
267
+ }
268
+ }
269
+ }
270
+ return decodeURIComponent(pathname);
271
+ }
169
272
  //# sourceMappingURL=module-resolver.js.map