@shapeshift-labs/frontier-lang-compiler 0.2.116 → 0.2.117

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.
package/README.md CHANGED
@@ -238,6 +238,29 @@ console.log(project.outputProjectSymbolGraph.importEdges[0].packageName); // "@p
238
238
  console.log(project.outputProjectSymbolGraph.importEdges[0].packageExportCondition); // "import"
239
239
  ```
240
240
 
241
+ Package `imports` maps are also modeled for `#internal` specifiers. Top-level
242
+ `moduleResolution.imports` applies from `packageRoot`/`root`, while
243
+ `packages[name].imports` applies to the nearest configured package root. Graph
244
+ edges record `packageImportKey`, `packageImportCondition`, and
245
+ `packageImportTarget` so merge admission can distinguish private aliases from
246
+ external or unresolved imports:
247
+
248
+ ```js
249
+ const project = safeMergeJsTsProject({
250
+ includeOutputProjectSymbolGraph: true,
251
+ moduleResolution: {
252
+ imports: { '#internal/*': { import: './src/internal/*.ts', default: './src/internal/*.js' } },
253
+ packageExportConditions: ['import', 'default']
254
+ },
255
+ baseFiles,
256
+ workerFiles,
257
+ headFiles
258
+ });
259
+
260
+ console.log(project.outputProjectSymbolGraph.importEdges[0].resolutionKind); // "package-import-source"
261
+ console.log(project.outputProjectSymbolGraph.importEdges[0].packageImportKey); // "#internal/*"
262
+ ```
263
+
241
264
  Named re-export identities also include symbol links when the project graph has
242
265
  enough evidence. For `export { thing as renamedThing } from './thing.js'`,
243
266
  `reExportIdentities[]` records the source module, imported/exported names,
@@ -1,6 +1,7 @@
1
1
  export type NativeProjectModuleResolutionPaths = Readonly<Record<string, readonly string[] | string>>;
2
2
  export type NativeProjectPackageExportTarget = string | readonly string[] | NativeProjectPackageConditionalExports;
3
3
  export type NativeProjectPackageExports = NativeProjectPackageExportTarget | Readonly<Record<string, NativeProjectPackageExportTarget>>;
4
+ export type NativeProjectPackageImports = Readonly<Record<string, NativeProjectPackageExportTarget>>;
4
5
 
5
6
  export interface NativeProjectPackageConditionalExports {
6
7
  readonly [condition: string]: NativeProjectPackageExportTarget;
@@ -12,12 +13,17 @@ export interface NativeProjectPackageResolutionOptions {
12
13
  readonly main?: string;
13
14
  readonly types?: string;
14
15
  readonly exports?: NativeProjectPackageExports;
16
+ readonly imports?: NativeProjectPackageImports;
15
17
  }
16
18
 
17
19
  export interface NativeProjectModuleResolutionOptions {
20
+ readonly root?: string;
21
+ readonly packageRoot?: string;
18
22
  readonly baseUrl?: string;
19
23
  readonly paths?: NativeProjectModuleResolutionPaths;
20
24
  readonly aliases?: NativeProjectModuleResolutionPaths;
25
+ readonly imports?: NativeProjectPackageImports;
26
+ readonly packageImports?: NativeProjectPackageImports;
21
27
  readonly packages?: Readonly<Record<string, NativeProjectPackageResolutionOptions>>;
22
28
  readonly conditions?: readonly string[];
23
29
  readonly packageExportConditions?: readonly string[];
@@ -107,10 +107,9 @@ export interface NativeProjectSymbolGraphModuleEdgeRecord {
107
107
  readonly resolvedModulePath?: string;
108
108
  readonly targetDocumentId?: string;
109
109
  readonly resolvedTargetSymbolId?: string;
110
- readonly resolutionKind?: 'relative-source' | 'relative-missing' | 'alias-source' | 'alias-missing' | 'path-alias-source' | 'path-alias-missing' | 'base-url-source' | 'base-url-missing' | 'package-source' | 'package-missing' | 'package-external' | string;
111
- readonly packageName?: string;
112
- readonly packageSubpath?: string;
113
- readonly packageExportCondition?: string;
110
+ readonly resolutionKind?: 'relative-source' | 'relative-missing' | 'alias-source' | 'alias-missing' | 'path-alias-source' | 'path-alias-missing' | 'base-url-source' | 'base-url-missing' | 'package-source' | 'package-missing' | 'package-external' | 'package-import-source' | 'package-import-missing' | 'package-import-external' | string;
111
+ readonly packageName?: string; readonly packageSubpath?: string; readonly packageExportCondition?: string;
112
+ readonly packageImportKey?: string; readonly packageImportCondition?: string; readonly packageImportTarget?: string;
114
113
  readonly importKind?: string;
115
114
  readonly exportKind?: string;
116
115
  readonly importedName?: string;
@@ -243,6 +243,9 @@ function moduleEdgeRecord(relation, moduleEdgeByRelation, symbolsById, documents
243
243
  packageName: resolution?.packageName,
244
244
  packageSubpath: resolution?.packageSubpath,
245
245
  packageExportCondition: resolution?.packageExportCondition,
246
+ packageImportKey: resolution?.packageImportKey,
247
+ packageImportCondition: resolution?.packageImportCondition,
248
+ packageImportTarget: resolution?.packageImportTarget,
246
249
  importKind: firstString(moduleEdge.importKind, value.importKind, symbolMetadata.importKind),
247
250
  exportKind: firstString(moduleEdge.exportKind, value.exportKind, symbolMetadata.exportKind),
248
251
  importedName: firstString(moduleEdge.importedName, value.importedName, symbolMetadata.importedName),
@@ -13,6 +13,7 @@ export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, docume
13
13
  export function resolveProjectModule(sourcePath, moduleSpecifier, documentsByPath, moduleResolution) {
14
14
  if (!sourcePath || !moduleSpecifier) return undefined;
15
15
  if (String(moduleSpecifier).startsWith('.')) return resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath);
16
+ if (String(moduleSpecifier).startsWith('#')) return resolvePackageImportProjectModule(sourcePath, moduleSpecifier, documentsByPath, moduleResolution);
16
17
  return resolveConfiguredProjectModule(moduleSpecifier, documentsByPath, moduleResolution);
17
18
  }
18
19
 
@@ -74,6 +75,32 @@ function resolveConfiguredProjectModule(moduleSpecifier, documentsByPath, module
74
75
  return firstMissing ?? (packageInfo ? { kind: 'package-external', ...packageInfo } : undefined);
75
76
  }
76
77
 
78
+ function resolvePackageImportProjectModule(sourcePath, moduleSpecifier, documentsByPath, moduleResolution = {}) {
79
+ const packageContext = packageImportContext(sourcePath, moduleResolution);
80
+ const importsValue = packageContext.imports;
81
+ if (!importsValue) return { kind: 'package-import-external', packageImportKey: moduleSpecifier };
82
+ const match = packageImportMapValue(importsValue, moduleSpecifier);
83
+ if (!match) return { kind: 'package-import-external', packageImportKey: moduleSpecifier };
84
+ let firstMissing;
85
+ for (const target of exportTargetsForValue(match.value, packageConditions(moduleResolution))) {
86
+ const packageImportTarget = target.path;
87
+ if (!packageImportTarget || !String(packageImportTarget).startsWith('.')) {
88
+ return { kind: 'package-import-external', packageImportKey: match.key, packageImportCondition: target.condition, packageImportTarget };
89
+ }
90
+ const candidatePath = normalizeProjectPath(joinProjectPath(packageContext.root, packageImportTarget));
91
+ const resolved = moduleTargetDocument(candidatePath, documentsByPath);
92
+ const record = {
93
+ packageImportKey: match.key,
94
+ packageImportCondition: target.condition,
95
+ packageImportTarget,
96
+ packageName: packageContext.packageName
97
+ };
98
+ if (resolved) return { path: resolved.path, documentId: resolved.id, kind: 'package-import-source', ...record };
99
+ firstMissing ??= { path: candidatePath, kind: 'package-import-missing', ...record };
100
+ }
101
+ return firstMissing ?? { kind: 'package-import-external', packageImportKey: match.key };
102
+ }
103
+
77
104
  function configuredModuleCandidates(moduleSpecifier, moduleResolution = {}, packageInfo) {
78
105
  const compilerOptions = moduleResolution.compilerOptions ?? {};
79
106
  const baseUrl = normalizeProjectPath(moduleResolution.baseUrl ?? compilerOptions.baseUrl ?? '');
@@ -136,6 +163,31 @@ function packageExportTargets(exportsValue, subpath, conditions) {
136
163
  return exportTargetsForValue(exportMapValue(exportsValue, subpath), conditions);
137
164
  }
138
165
 
166
+ function packageImportMapValue(importsValue, moduleSpecifier) {
167
+ if (!isRecord(importsValue)) return undefined;
168
+ if (Object.prototype.hasOwnProperty.call(importsValue, moduleSpecifier)) return { key: moduleSpecifier, value: importsValue[moduleSpecifier] };
169
+ for (const [pattern, value] of Object.entries(importsValue)) {
170
+ const capture = patternCapture(moduleSpecifier, pattern);
171
+ if (capture !== undefined) return { key: pattern, value: replaceExportTargetCapture(value, capture) };
172
+ }
173
+ return undefined;
174
+ }
175
+
176
+ function packageImportContext(sourcePath, moduleResolution = {}) {
177
+ const packages = Object.entries(moduleResolution.packages ?? {})
178
+ .map(([packageName, options]) => ({
179
+ packageName,
180
+ root: normalizeProjectPath(options.root ?? ''),
181
+ imports: options.imports
182
+ }))
183
+ .filter((entry) => entry.imports && pathInsideRoot(sourcePath, entry.root))
184
+ .sort((left, right) => right.root.length - left.root.length);
185
+ return packages[0] ?? {
186
+ root: normalizeProjectPath(moduleResolution.packageRoot ?? moduleResolution.root ?? ''),
187
+ imports: moduleResolution.imports ?? moduleResolution.packageImports
188
+ };
189
+ }
190
+
139
191
  function exportMapValue(exportsValue, subpath) {
140
192
  if (!isRecord(exportsValue) || !Object.keys(exportsValue).some((key) => key.startsWith('.'))) return subpath === '.' ? exportsValue : undefined;
141
193
  return exportsValue[subpath] ?? patternExportMapValue(exportsValue, subpath);
@@ -229,7 +281,10 @@ function packageResolutionFields(candidate, packageInfo) {
229
281
  return {
230
282
  packageName: candidate.packageName ?? packageInfo?.packageName,
231
283
  packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath,
232
- packageExportCondition: candidate.packageExportCondition
284
+ packageExportCondition: candidate.packageExportCondition,
285
+ packageImportKey: candidate.packageImportKey,
286
+ packageImportCondition: candidate.packageImportCondition,
287
+ packageImportTarget: candidate.packageImportTarget
233
288
  };
234
289
  }
235
290
 
@@ -250,3 +305,9 @@ function normalizeProjectPath(path) {
250
305
  }
251
306
  return parts.join('/');
252
307
  }
308
+
309
+ function pathInsideRoot(sourcePath, root) {
310
+ if (!root) return true;
311
+ const normalized = normalizeProjectPath(sourcePath);
312
+ return normalized === root || normalized.startsWith(`${root}/`);
313
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.116",
3
+ "version": "0.2.117",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",