@shapeshift-labs/frontier-lang-compiler 0.2.161 → 0.2.163

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/dist/internal/index-impl/moduleHostResourceImportMetadata.js +47 -0
  2. package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +215 -1
  3. package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +1 -1
  4. package/dist/internal/index-impl/projectSymbolGraphCssModuleUtils.js +56 -1
  5. package/dist/internal/index-impl/projectSymbolGraphCssModules.js +48 -4
  6. package/dist/internal/index-impl/projectSymbolGraphJsxPropRecordFields.js +91 -0
  7. package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +35 -7
  8. package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +4 -31
  9. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollectionHelpers.js +201 -0
  10. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollections.js +210 -0
  11. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +12 -5
  12. package/dist/internal/index-impl/projectSymbolGraphJsxSpreadPropValues.js +196 -0
  13. package/dist/internal/index-impl/projectSymbolGraphJsxStaticLiterals.js +207 -0
  14. package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +12 -14
  15. package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +33 -31
  16. package/dist/internal/index-impl/projectSymbolGraphPackageRuntimeConditions.js +22 -0
  17. package/dist/internal/index-impl/projectSymbolGraphScopeUseDefLexical.js +11 -19
  18. package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +27 -1
  19. package/dist/js-ts-safe-project-merge-admission.js +10 -0
  20. package/dist/js-ts-safe-project-merge-evidence-routing.js +30 -2
  21. package/dist/js-ts-safe-project-merge-graph-delta-compiler-conflicts.js +7 -0
  22. package/dist/js-ts-safe-project-merge-html-css-matrix.js +7 -2
  23. package/dist/js-ts-safe-project-merge-html-css-summary.js +110 -2
  24. package/dist/js-ts-safe-project-merge-html-css.js +137 -3
  25. package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +9 -0
  26. package/dist/js-ts-safe-project-merge.js +3 -0
  27. package/dist/native-source-preservation-scanner.js +10 -0
  28. package/dist/semantic-import-runtime-dynamic-import-evidence.js +141 -0
  29. package/dist/semantic-import-runtime-order-evidence.js +5 -4
  30. package/package.json +1 -1
@@ -0,0 +1,196 @@
1
+ import { isJsxSpreadAttribute } from '../../js-ts-safe-merge-jsx-attribute-parser.js';
2
+ import { parseStaticObjectLiteralExpression } from './projectSymbolGraphJsxStaticLiterals.js';
3
+
4
+ function jsxSpreadPropValueEvidence(tag, attribute, context = {}) {
5
+ const expressionText = jsxSpreadExpressionText(attribute);
6
+ const source = staticObjectSpreadSource(expressionText, attribute, context);
7
+ if (!source?.status) return dynamicSpreadPropValueEvidence(expressionText, source?.reasonCode);
8
+ const precedence = staticSpreadPrecedenceEvidence(tag, attribute, source.entries);
9
+ const propNames = uniqueStrings(source.entries.map((entry) => entry.propName));
10
+ return compactRecord({
11
+ proofStatus: 'static-object-spread-jsx-prop-value-evidence',
12
+ reasonCode: 'jsx-render-prop-spread-static-object-evidence',
13
+ valueKind: 'object-spread',
14
+ valueText: source.valueText,
15
+ expressionText,
16
+ staticSpreadSourceKind: source.sourceKind,
17
+ staticSpreadSourceName: source.sourceName,
18
+ staticSpreadPropEntries: source.entries,
19
+ staticSpreadPropNames: propNames,
20
+ staticSpreadPropCount: propNames.length,
21
+ staticSpreadEffectivePropEntries: precedence.effectiveEntries,
22
+ staticSpreadEffectivePropNames: uniqueStrings(precedence.effectiveEntries.map((entry) => entry.propName)),
23
+ staticSpreadExplicitOverridePropNames: precedence.explicitOverridePropNames,
24
+ staticSpreadOverridesExplicitPropNames: precedence.overridesExplicitPropNames,
25
+ staticSpreadDuplicatePropNames: duplicatePropNames(source.entries),
26
+ staticSpreadPrecedenceStatus: precedence.status,
27
+ claimScope: 'static-object-spread-props-only',
28
+ renderEquivalenceClaim: false
29
+ });
30
+ }
31
+
32
+ function dynamicSpreadPropValueEvidence(expressionText, reasonCode) {
33
+ return {
34
+ proofStatus: 'dynamic-jsx-prop-spread-unsupported',
35
+ reasonCode: 'jsx-render-prop-spread-unsupported',
36
+ valueKind: 'spread-expression',
37
+ expressionText,
38
+ dynamicText: expressionText,
39
+ dynamicBlockerReasonCode: reasonCode ?? jsxPropSpreadDynamicBlockerReasonCode(expressionText),
40
+ claimScope: 'static-object-spread-props-only',
41
+ renderEquivalenceClaim: false
42
+ };
43
+ }
44
+
45
+ function staticObjectSpreadSource(expressionText, attribute, context = {}) {
46
+ const text = normalizedText(expressionText);
47
+ if (!text) return { reasonCode: 'jsx-render-prop-spread-expression-unsupported' };
48
+ if (text.startsWith('{')) {
49
+ const parsed = parseStaticObjectLiteralExpression(text);
50
+ return parsed.value
51
+ ? { status: 'static', sourceKind: 'inline-object-literal', valueText: text, entries: parsed.value.entries }
52
+ : { reasonCode: parsed.reasonCode ?? jsxPropSpreadDynamicBlockerReasonCode(text) };
53
+ }
54
+ if (simpleIdentifierExpression(text)) {
55
+ const resolved = sameFileConstObjectSpreadSource(text, attribute, context);
56
+ return resolved.status ? resolved : { reasonCode: resolved.reasonCode ?? 'jsx-render-prop-spread-reference-unsupported' };
57
+ }
58
+ return { reasonCode: jsxPropSpreadDynamicBlockerReasonCode(text) };
59
+ }
60
+
61
+ function sameFileConstObjectSpreadSource(name, attribute, context = {}) {
62
+ const sourceText = String(context.sourceText ?? '');
63
+ if (!sourceText) return { reasonCode: 'jsx-render-prop-spread-reference-unsupported' };
64
+ const beforeOffset = Number.isFinite(attribute?.start) ? attribute.start : sourceText.length;
65
+ const declarations = constObjectInitializers(sourceText, name).filter((declaration) => declaration.start < beforeOffset);
66
+ if (declarations.length !== 1) return {
67
+ reasonCode: declarations.length > 1 ? 'jsx-render-prop-spread-ambiguous-const-object-unsupported' : 'jsx-render-prop-spread-reference-unsupported'
68
+ };
69
+ const parsed = parseStaticObjectLiteralExpression(declarations[0].initializerText);
70
+ return parsed.value
71
+ ? {
72
+ status: 'static',
73
+ sourceKind: 'same-file-const-object',
74
+ sourceName: name,
75
+ valueText: normalizedText(declarations[0].initializerText),
76
+ entries: parsed.value.entries
77
+ }
78
+ : { reasonCode: parsed.reasonCode ?? 'jsx-render-prop-spread-const-object-dynamic-unsupported' };
79
+ }
80
+
81
+ function constObjectInitializers(sourceText, name) {
82
+ const result = [];
83
+ const pattern = new RegExp(`\\bconst\\s+${escapeRegExp(name)}\\s*=\\s*`, 'g');
84
+ let match;
85
+ while ((match = pattern.exec(sourceText))) {
86
+ const start = match.index;
87
+ const initializerText = readConstInitializerText(sourceText, pattern.lastIndex);
88
+ if (initializerText) result.push({ start, initializerText });
89
+ }
90
+ return result;
91
+ }
92
+
93
+ function readConstInitializerText(sourceText, start) {
94
+ let quote;
95
+ let depth = 0;
96
+ for (let index = start; index < sourceText.length; index += 1) {
97
+ const char = sourceText[index];
98
+ if (quote) {
99
+ if (char === '\\') index += 1;
100
+ else if (char === quote) quote = undefined;
101
+ continue;
102
+ }
103
+ if (char === '"' || char === "'" || char === '`') quote = char;
104
+ else if (char === '(' || char === '[' || char === '{') depth += 1;
105
+ else if (char === ')' || char === ']' || char === '}') depth = Math.max(0, depth - 1);
106
+ else if (depth === 0 && (char === ';' || char === '\n')) return sourceText.slice(start, index).trim();
107
+ }
108
+ return sourceText.slice(start).trim();
109
+ }
110
+
111
+ function staticSpreadPrecedenceEvidence(tag, attribute, entries) {
112
+ const index = attributeIndexInTag(tag, attribute);
113
+ const before = namedAttributesBefore(tag, index);
114
+ const after = namedAttributesAfter(tag, index);
115
+ const lastEntries = lastStaticEntriesByProp(entries);
116
+ const explicitOverridePropNames = uniqueStrings(lastEntries.filter((entry) => after.has(entry.propName)).map((entry) => entry.propName));
117
+ const overridesExplicitPropNames = uniqueStrings(lastEntries.filter((entry) => before.has(entry.propName)).map((entry) => entry.propName));
118
+ const effectiveEntries = lastEntries.filter((entry) => !after.has(entry.propName));
119
+ return {
120
+ effectiveEntries,
121
+ explicitOverridePropNames,
122
+ overridesExplicitPropNames,
123
+ status: staticSpreadPrecedenceStatus(explicitOverridePropNames, overridesExplicitPropNames, duplicatePropNames(entries))
124
+ };
125
+ }
126
+
127
+ function namedAttributesBefore(tag, index) {
128
+ return new Set((tag.attributes ?? []).slice(0, Math.max(0, index)).filter((candidate) => !isJsxSpreadAttribute(candidate)).map((candidate) => candidate.name));
129
+ }
130
+
131
+ function namedAttributesAfter(tag, index) {
132
+ return new Set((tag.attributes ?? []).slice(index + 1).filter((candidate) => !isJsxSpreadAttribute(candidate)).map((candidate) => candidate.name));
133
+ }
134
+
135
+ function staticSpreadPrecedenceStatus(explicitOverridePropNames, overridesExplicitPropNames, duplicateNames) {
136
+ if (explicitOverridePropNames.length && overridesExplicitPropNames.length) return 'static-spread-between-explicit-props';
137
+ if (explicitOverridePropNames.length) return 'static-spread-overridden-by-later-explicit-prop';
138
+ if (overridesExplicitPropNames.length) return 'static-spread-overrides-earlier-explicit-prop';
139
+ if (duplicateNames.length) return 'static-spread-duplicate-prop-last-write-wins';
140
+ return 'static-spread-props-preserved';
141
+ }
142
+
143
+ function attributeIndexInTag(tag, attribute) {
144
+ const attributes = tag.attributes ?? [];
145
+ const direct = attributes.indexOf(attribute);
146
+ if (direct >= 0) return direct;
147
+ return attributes.findIndex((candidate) => candidate.start === attribute?.start && candidate.end === attribute?.end && candidate.name === attribute?.name);
148
+ }
149
+
150
+ function lastStaticEntriesByProp(entries) {
151
+ const byProp = new Map();
152
+ for (const entry of entries) byProp.set(entry.propName, entry);
153
+ return [...byProp.values()].sort((left, right) => left.ordinal - right.ordinal);
154
+ }
155
+
156
+ function duplicatePropNames(entries) {
157
+ const counts = new Map();
158
+ for (const entry of entries) counts.set(entry.propName, (counts.get(entry.propName) ?? 0) + 1);
159
+ return [...counts.entries()].filter(([, count]) => count > 1).map(([name]) => name);
160
+ }
161
+
162
+ function jsxSpreadExpressionText(attribute) {
163
+ const expressionText = normalizedText(attribute?.expressionText);
164
+ if (expressionText) return expressionText;
165
+ const text = String(attribute?.text ?? '').trim();
166
+ const braced = /^\{\s*\.\.\.\s*([\s\S]*?)\s*\}$/.exec(text);
167
+ if (braced) return normalizedText(braced[1]);
168
+ const unbraced = /^\.\.\.\s*([\s\S]*)$/.exec(text);
169
+ return unbraced ? normalizedText(unbraced[1]) : undefined;
170
+ }
171
+
172
+ function jsxPropSpreadDynamicBlockerReasonCode(text) {
173
+ const value = normalizedText(text);
174
+ if (/\[[\s\S]*\]/.test(value)) return 'jsx-render-prop-spread-computed-reference-unsupported';
175
+ if (/^`[\s\S]*\$\{[\s\S]*`$/.test(value)) return 'jsx-render-prop-spread-template-interpolation-unsupported';
176
+ if (/\?\.\s*\(/.test(value) || /\b[A-Za-z_$][\w$]*(?:\s*(?:\.|\?\.)\s*[A-Za-z_$][\w$]*)*\s*\(/.test(value)) return 'jsx-render-prop-spread-call-expression-unsupported';
177
+ if (/^\{/.test(value)) return 'jsx-render-prop-spread-dynamic-object-unsupported';
178
+ if (staticPropReference(value)) return 'jsx-render-prop-spread-reference-unsupported';
179
+ return 'jsx-render-prop-spread-expression-unsupported';
180
+ }
181
+
182
+ function staticPropReference(text) {
183
+ const value = normalizedText(text);
184
+ if (!/^(?:this|[A-Za-z_$][\w$]*)(?:\s*\.\s*[A-Za-z_$][\w$]*)*$/.test(value)) return undefined;
185
+ const normalized = value.replace(/\s+/g, '');
186
+ const path = normalized.split('.');
187
+ return { text: normalized, root: path[0], path };
188
+ }
189
+
190
+ function simpleIdentifierExpression(text) { return /^[A-Za-z_$][\w$]*$/.test(String(text ?? '').trim()); }
191
+ function escapeRegExp(text) { return String(text ?? '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
192
+ function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value.length > 0))]; }
193
+ function normalizedText(text) { return String(text ?? '').trim().replace(/\s+/g, ' '); }
194
+ function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
195
+
196
+ export { jsxSpreadPropValueEvidence };
@@ -0,0 +1,207 @@
1
+ import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ function parseStaticLiteralExpression(text) {
4
+ return parseStaticLiteralExpressionResult(text).value;
5
+ }
6
+
7
+ function parseStaticObjectLiteralExpression(text) {
8
+ const result = parseStaticLiteralExpressionResult(text);
9
+ return result.value?.kind === 'object-literal' ? result : { reasonCode: result.reasonCode };
10
+ }
11
+
12
+ function parseStaticLiteralExpressionResult(text) {
13
+ const state = { text: String(text ?? ''), index: 0 };
14
+ const parsed = parseStaticLiteralValue(state);
15
+ skipWhitespace(state);
16
+ return parsed && state.index === state.text.length
17
+ ? { value: parsed }
18
+ : { reasonCode: state.errorReason };
19
+ }
20
+
21
+ function parseStaticLiteralValue(state) {
22
+ skipWhitespace(state);
23
+ const char = state.text[state.index];
24
+ if (char === '"' || char === "'") return parseQuotedStaticString(state) ? { kind: 'string' } : undefined;
25
+ if (char === '`') return parseStaticTemplateString(state) ? { kind: 'template-string' } : undefined;
26
+ if (char === '{') {
27
+ const parsed = parseStaticObjectLiteral(state);
28
+ return parsed ? { kind: 'object-literal', entries: parsed.entries } : undefined;
29
+ }
30
+ if (char === '[') return parseStaticArrayLiteral(state) ? { kind: 'array-literal' } : undefined;
31
+ if (looksLikeCallExpression(state.text.slice(state.index))) state.errorReason ??= 'jsx-render-prop-spread-call-expression-unsupported';
32
+ const primitive = parseStaticPrimitiveToken(state);
33
+ return primitive ? { kind: primitive } : undefined;
34
+ }
35
+
36
+ function parseStaticObjectLiteral(state) {
37
+ state.index += 1;
38
+ skipWhitespace(state);
39
+ const entries = [];
40
+ if (consumeChar(state, '}')) return { entries };
41
+ while (state.index < state.text.length) {
42
+ if (state.text.startsWith('...', state.index)) {
43
+ state.errorReason ??= 'jsx-render-prop-spread-nested-spread-unsupported';
44
+ return undefined;
45
+ }
46
+ if (state.text[state.index] === '[') {
47
+ state.errorReason ??= 'jsx-render-prop-spread-computed-key-unsupported';
48
+ return undefined;
49
+ }
50
+ const key = parseStaticObjectKey(state);
51
+ if (!key) return undefined;
52
+ skipWhitespace(state);
53
+ if (!consumeChar(state, ':')) {
54
+ if (key.propName === 'get' || key.propName === 'set') state.errorReason ??= 'jsx-render-prop-spread-getter-unsupported';
55
+ else if (state.text[state.index] === '(') state.errorReason ??= 'jsx-render-prop-spread-method-unsupported';
56
+ else state.errorReason ??= 'jsx-render-prop-spread-dynamic-object-unsupported';
57
+ return undefined;
58
+ }
59
+ skipWhitespace(state);
60
+ const valueStart = state.index;
61
+ const value = parseStaticLiteralValue(state);
62
+ if (!value) return undefined;
63
+ const valueText = normalizedText(state.text.slice(valueStart, state.index));
64
+ entries.push(staticSpreadPropEntry(key, value, valueText, entries.length + 1));
65
+ skipWhitespace(state);
66
+ if (consumeChar(state, '}')) return { entries };
67
+ if (!consumeChar(state, ',')) return undefined;
68
+ skipWhitespace(state);
69
+ if (consumeChar(state, '}')) return { entries };
70
+ }
71
+ return undefined;
72
+ }
73
+
74
+ function parseStaticArrayLiteral(state) {
75
+ state.index += 1;
76
+ skipWhitespace(state);
77
+ if (consumeChar(state, ']')) return true;
78
+ while (state.index < state.text.length) {
79
+ if (state.text.startsWith('...', state.index) || state.text[state.index] === ',') {
80
+ state.errorReason ??= 'jsx-render-prop-spread-dynamic-object-unsupported';
81
+ return false;
82
+ }
83
+ if (!parseStaticLiteralValue(state)) return false;
84
+ skipWhitespace(state);
85
+ if (consumeChar(state, ']')) return true;
86
+ if (!consumeChar(state, ',')) return false;
87
+ skipWhitespace(state);
88
+ if (consumeChar(state, ']')) return true;
89
+ }
90
+ return false;
91
+ }
92
+
93
+ function parseStaticObjectKey(state) {
94
+ skipWhitespace(state);
95
+ const char = state.text[state.index];
96
+ const start = state.index;
97
+ if (char === '"' || char === "'") {
98
+ if (!parseQuotedStaticString(state)) return undefined;
99
+ const keyText = state.text.slice(start, state.index);
100
+ return { propName: staticStringLiteralValue(keyText), keyText };
101
+ }
102
+ const numberStart = state.index;
103
+ const number = parseStaticNumberToken(state);
104
+ if (number) return { propName: number, keyText: number };
105
+ state.index = numberStart;
106
+ const identifier = parseIdentifierToken(state);
107
+ return identifier ? { propName: identifier, keyText: identifier } : undefined;
108
+ }
109
+
110
+ function staticSpreadPropEntry(key, value, valueText, ordinal) {
111
+ return {
112
+ propName: key.propName,
113
+ keyText: key.keyText,
114
+ valueKind: value.kind,
115
+ valueText,
116
+ ordinal,
117
+ entryHash: hashSemanticValue({
118
+ kind: 'frontier.lang.projectJsxStaticObjectSpreadPropEntry',
119
+ propName: key.propName,
120
+ keyText: key.keyText,
121
+ valueKind: value.kind,
122
+ valueText,
123
+ ordinal
124
+ })
125
+ };
126
+ }
127
+
128
+ function parseQuotedStaticString(state) {
129
+ const quote = state.text[state.index];
130
+ if (quote !== '"' && quote !== "'") return false;
131
+ state.index += 1;
132
+ while (state.index < state.text.length) {
133
+ const char = state.text[state.index];
134
+ if (char === '\\') {
135
+ state.index += 2;
136
+ continue;
137
+ }
138
+ state.index += 1;
139
+ if (char === quote) return true;
140
+ }
141
+ return false;
142
+ }
143
+
144
+ function parseStaticTemplateString(state) {
145
+ if (state.text[state.index] !== '`') return false;
146
+ state.index += 1;
147
+ while (state.index < state.text.length) {
148
+ const char = state.text[state.index];
149
+ if (char === '\\') {
150
+ state.index += 2;
151
+ continue;
152
+ }
153
+ if (char === '$' && state.text[state.index + 1] === '{') return false;
154
+ state.index += 1;
155
+ if (char === '`') return true;
156
+ }
157
+ return false;
158
+ }
159
+
160
+ function parseStaticPrimitiveToken(state) {
161
+ const number = parseStaticNumberToken(state);
162
+ if (number) return 'number';
163
+ const identifierStart = state.index;
164
+ const identifier = parseIdentifierToken(state);
165
+ if (['true', 'false'].includes(identifier)) return 'boolean';
166
+ if (identifier === 'null') return 'null';
167
+ if (identifier === 'undefined') return 'undefined';
168
+ state.index = identifierStart;
169
+ return undefined;
170
+ }
171
+
172
+ function parseStaticNumberToken(state) {
173
+ const match = /^[-]?(?:0|[1-9]\d*)(?:\.\d+)?/.exec(state.text.slice(state.index));
174
+ if (!match) return undefined;
175
+ state.index += match[0].length;
176
+ return match[0];
177
+ }
178
+
179
+ function parseIdentifierToken(state) {
180
+ const match = /^[A-Za-z_$][\w$]*/.exec(state.text.slice(state.index));
181
+ if (!match) return undefined;
182
+ state.index += match[0].length;
183
+ return match[0];
184
+ }
185
+
186
+ function consumeChar(state, char) {
187
+ if (state.text[state.index] !== char) return false;
188
+ state.index += 1;
189
+ return true;
190
+ }
191
+
192
+ function skipWhitespace(state) {
193
+ while (/\s/.test(state.text[state.index] ?? '')) state.index += 1;
194
+ }
195
+
196
+ function staticStringLiteralValue(text) {
197
+ const value = String(text ?? '');
198
+ return value.slice(1, -1).replace(/\\([\s\S])/g, '$1');
199
+ }
200
+
201
+ function looksLikeCallExpression(text) {
202
+ return /^\s*[A-Za-z_$][\w$]*(?:\s*(?:\.|\?\.)\s*[A-Za-z_$][\w$]*)*\s*\(/.test(String(text ?? ''));
203
+ }
204
+
205
+ function normalizedText(text) { return String(text ?? '').trim().replace(/\s+/g, ' '); }
206
+
207
+ export { parseStaticLiteralExpression, parseStaticObjectLiteralExpression };
@@ -3,6 +3,7 @@ import { exportMapMatch, exportTargetsForValue, packageEnvironmentConditionAmbig
3
3
 
4
4
  const UNKNOWN_DYNAMIC_IMPORT_MODULE_SPECIFIER = '<dynamic-import>';
5
5
  const UNKNOWN_HOST_DEPENDENCY_MODULE_SPECIFIER = '<host-dependency>';
6
+ const PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING = 'package-runtime-condition-host-resource-import-ambiguous-missing';
6
7
 
7
8
  export function resolveRelativeProjectModule(sourcePath, moduleSpecifier, documentsByPath) {
8
9
  if (!sourcePath || !moduleSpecifier || !moduleSpecifier.startsWith('.')) return undefined;
@@ -115,6 +116,12 @@ function resolvePackageImportProjectModule(sourcePath, moduleSpecifier, document
115
116
  ...runtimeEvidence
116
117
  };
117
118
  if (match.value === null) return { kind: 'package-import-null-target-missing', packageImportKey: match.key, packageName: packageContext.packageName, ...runtimeEvidence };
119
+ if (runtimeEvidence.packageRuntimeConditionReasonCode === PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING) return {
120
+ kind: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING,
121
+ packageImportKey: match.key,
122
+ packageName: packageContext.packageName,
123
+ ...runtimeEvidence
124
+ };
118
125
  const runtimeAmbiguity = packageRuntimeConditionAmbiguity(match.value, moduleResolution, sourcePath, packageContext, edgeMetadata);
119
126
  if (runtimeAmbiguity) return { kind: 'package-import-runtime-ambiguous-missing', packageImportKey: match.key, packageImportCondition: runtimeAmbiguity, packageName: packageContext.packageName, ...runtimeEvidence };
120
127
  const environmentEvidence = packageEnvironmentConditionEvidence(moduleResolution, edgeMetadata);
@@ -188,6 +195,7 @@ function packageCandidates(sourcePath, packageInfo, moduleResolution = {}, edgeM
188
195
  const fallbackPath = normalizeProjectPath(joinProjectPath(root, subpath || '.'));
189
196
  if (runtimeEvidence.packageRuntimeConditionConflict) return [{ kind: 'package', failClosedKind: 'package-runtime-condition-conflict-missing', path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
190
197
  if (exportValue === undefined || exportValue === null) return [{ kind: 'package', failClosedKind: exportValue === null ? 'package-export-null-target-missing' : 'package-subpath-not-exported-missing', path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
198
+ if (runtimeEvidence.packageRuntimeConditionReasonCode === PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING) return [{ kind: 'package', failClosedKind: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING, path: fallbackPath, packageExportKey: exportMatch?.key, ...runtimeEvidence, ...packageInfo }];
191
199
  const runtimeAmbiguity = packageRuntimeConditionAmbiguity(exportValue, moduleResolution, sourcePath, undefined, edgeMetadata);
192
200
  if (runtimeAmbiguity) return [{ kind: 'package', failClosedKind: 'package-export-runtime-ambiguous-missing', path: fallbackPath, packageExportKey: exportMatch?.key, packageExportCondition: runtimeAmbiguity, ...runtimeEvidence, ...packageInfo }];
193
201
  const environmentAmbiguity = packageEnvironmentConditionAmbiguity(exportValue, moduleResolution, sourcePath, undefined, edgeMetadata);
@@ -251,15 +259,8 @@ function moduleTargetDocument(path, documentsByPath) {
251
259
  return undefined;
252
260
  }
253
261
 
254
- function targetExportName(edge) {
255
- const name = edge.importedName ?? edge.localName ?? edge.exportedName;
256
- if (!name || name === '*') return undefined;
257
- return String(name);
258
- }
259
-
260
- function symbolKey(documentId, name) {
261
- return `${documentId}\u0000${name}`;
262
- }
262
+ function targetExportName(edge) { const name = edge.importedName ?? edge.localName ?? edge.exportedName; return name && name !== '*' ? String(name) : undefined; }
263
+ function symbolKey(documentId, name) { return `${documentId}\u0000${name}`; }
263
264
 
264
265
  function patternCapture(value, pattern) {
265
266
  if (pattern === value) return '';
@@ -278,9 +279,7 @@ function uniquePaths(candidates) {
278
279
  });
279
280
  }
280
281
 
281
- function joinProjectPath(left, right) {
282
- return left ? `${left}/${right}` : String(right);
283
- }
282
+ function joinProjectPath(left, right) { return left ? `${left}/${right}` : String(right); }
284
283
 
285
284
  function packageSpecifierInfo(moduleSpecifier) {
286
285
  if (!moduleSpecifier || String(moduleSpecifier).startsWith('#')) return undefined;
@@ -295,11 +294,10 @@ function packageSpecifierInfo(moduleSpecifier) {
295
294
 
296
295
  function packageResolutionFields(candidate, packageInfo) {
297
296
  if (!candidate.packageName && candidate.kind !== 'package') return {};
298
- return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
297
+ return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionExcludedConditions: candidate.packageRuntimeConditionExcludedConditions, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageRuntimeConditionHostResourceKind: candidate.packageRuntimeConditionHostResourceKind, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
299
298
  }
300
299
 
301
300
  function environmentAmbiguityFields(ambiguity) { return { packageEnvironmentConditionCandidates: ambiguity.split('|'), packageEnvironmentConditionReasonCode: 'package-environment-condition-ambiguous-missing' }; }
302
-
303
301
  function isRecord(value) { return value && typeof value === 'object' && !Array.isArray(value); }
304
302
 
305
303
  function normalizeProjectPath(path) {
@@ -1,3 +1,6 @@
1
+ import { runtimeAdmittedConditions, runtimeConditionRecord } from './projectSymbolGraphPackageRuntimeConditions.js';
2
+ import { hostResourceImportDependencyKind } from './moduleHostResourceImportMetadata.js';
3
+
1
4
  const EnvironmentPackageConditions = Object.freeze([
2
5
  'browser',
3
6
  'node',
@@ -9,6 +12,7 @@ const EnvironmentPackageConditions = Object.freeze([
9
12
  'bun',
10
13
  'react-native'
11
14
  ]);
15
+ const PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING = 'package-runtime-condition-host-resource-import-ambiguous-missing';
12
16
 
13
17
  function exportTargetsForValue(value, conditions, condition) {
14
18
  if (!value) return [];
@@ -30,7 +34,10 @@ function exportMapMatch(exportsValue, subpath) {
30
34
 
31
35
  function packageConditions(moduleResolution = {}, sourcePath, packageContext, edgeMetadata) {
32
36
  return prioritizeConditions(
33
- moduleResolution.packageExportConditions ?? moduleResolution.conditions ?? ['types', 'import', 'module', 'require', 'default'],
37
+ runtimeAdmittedConditions(
38
+ moduleResolution.packageExportConditions ?? moduleResolution.conditions ?? ['types', 'import', 'module', 'require', 'default'],
39
+ packageRuntimeConditionEvidence(moduleResolution, sourcePath, packageContext, edgeMetadata).packageRuntimeCondition
40
+ ),
34
41
  packageConditionPreferences(sourcePath, moduleResolution, packageContext, edgeMetadata)
35
42
  );
36
43
  }
@@ -57,9 +64,11 @@ function packageEnvironmentConditionAmbiguity(value, moduleResolution, sourcePat
57
64
  }
58
65
 
59
66
  function packageRuntimeConditionEvidence(moduleResolution = {}, sourcePath, packageContext, edgeMetadata) {
67
+ const packageType = packageTypeForSource(moduleResolution, sourcePath, packageContext);
68
+ const hostResourceAmbiguity = packageRuntimeHostResourceConditionAmbiguity(edgeMetadata, packageType);
69
+ if (hostResourceAmbiguity) return hostResourceAmbiguity;
60
70
  const edgeCondition = packageRuntimeConditionFromEdge(edgeMetadata);
61
71
  const extensionCondition = packageRuntimeConditionFromExtension(sourcePath);
62
- const packageType = packageTypeForSource(moduleResolution, sourcePath, packageContext);
63
72
  const packageTypeCondition = packageType === 'module' ? 'import' : packageType === 'commonjs' ? 'require' : undefined;
64
73
  if (edgeCondition) {
65
74
  const conflict = edgeCondition.conflictsWithSource && (
@@ -78,8 +87,8 @@ function packageRuntimeConditionEvidence(moduleResolution = {}, sourcePath, pack
78
87
  }
79
88
  const hostAmbiguity = edgeCondition ? undefined : packageRuntimeHostConditionAmbiguity(edgeMetadata, packageType);
80
89
  if (hostAmbiguity) return hostAmbiguity;
81
- if (extensionCondition) return { packageRuntimeCondition: extensionCondition, packageRuntimeConditionEvidenceSource: 'source-extension', packageType };
82
- if (packageTypeCondition) return { packageRuntimeCondition: packageTypeCondition, packageRuntimeConditionEvidenceSource: 'package-type', packageType };
90
+ if (extensionCondition) return runtimeConditionRecord({ packageRuntimeCondition: extensionCondition, packageRuntimeConditionEvidenceSource: 'source-extension', packageType });
91
+ if (packageTypeCondition) return runtimeConditionRecord({ packageRuntimeCondition: packageTypeCondition, packageRuntimeConditionEvidenceSource: 'package-type', packageType });
83
92
  return {};
84
93
  }
85
94
 
@@ -177,15 +186,28 @@ function packageRuntimeHostConditionAmbiguity(edgeMetadata = {}, packageType) {
177
186
  });
178
187
  }
179
188
 
189
+ function packageRuntimeHostResourceConditionAmbiguity(edgeMetadata = {}, packageType) {
190
+ const hostKind = edgeMetadata.hostDependencyKind;
191
+ const hostResourceKind = hostResourceImportDependencyKind(hostKind);
192
+ if (!hostResourceKind) return undefined;
193
+ return compactRecord({
194
+ packageRuntimeConditionEvidenceSource: 'host-resource-import-ambiguous',
195
+ packageRuntimeConditionEdgeKind: `host-${hostKind}`,
196
+ packageRuntimeConditionReasonCode: PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING,
197
+ packageRuntimeConditionHostResourceKind: hostResourceKind,
198
+ packageType
199
+ });
200
+ }
201
+
180
202
  function edgeCondition(packageRuntimeCondition, packageRuntimeConditionEdgeKind, packageRuntimeConditionReasonCode, preferred, conflictsWithSource) {
181
- return {
203
+ return runtimeConditionRecord({
182
204
  packageRuntimeCondition,
183
205
  packageRuntimeConditionEvidenceSource: 'edge-kind',
184
206
  packageRuntimeConditionEdgeKind,
185
207
  packageRuntimeConditionReasonCode,
186
208
  preferred,
187
209
  conflictsWithSource
188
- };
210
+ });
189
211
  }
190
212
 
191
213
  function staticImportKind(importKind) {
@@ -240,10 +262,7 @@ function packageTypeByRoot(typeMap, sourcePath) {
240
262
  .sort((left, right) => right.root.length - left.root.length)[0]?.value;
241
263
  }
242
264
 
243
- function normalizePackageType(value) {
244
- const type = typeof value === 'string' ? value : value?.type ?? value?.packageType;
245
- return type === 'module' || type === 'commonjs' ? type : undefined;
246
- }
265
+ function normalizePackageType(value) { const type = typeof value === 'string' ? value : value?.type ?? value?.packageType; return type === 'module' || type === 'commonjs' ? type : undefined; }
247
266
 
248
267
  function sameSet(left, right) {
249
268
  if (left.size !== right.size) return false;
@@ -251,13 +270,8 @@ function sameSet(left, right) {
251
270
  return true;
252
271
  }
253
272
 
254
- function uniqueStrings(values) {
255
- return [...new Set(values.filter((value) => typeof value === 'string' && value))];
256
- }
257
-
258
- function stringValue(value) {
259
- return typeof value === 'string' && value.length ? value : undefined;
260
- }
273
+ function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value))]; }
274
+ function stringValue(value) { return typeof value === 'string' && value.length ? value : undefined; }
261
275
 
262
276
  function prioritizeConditions(conditions, preferred) {
263
277
  const entries = Array.isArray(conditions) ? conditions : [conditions];
@@ -271,7 +285,6 @@ function prioritizeConditions(conditions, preferred) {
271
285
  }
272
286
 
273
287
  function isRecord(value) { return value && typeof value === 'object' && !Array.isArray(value); }
274
-
275
288
  function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
276
289
 
277
290
  function replaceTargetCapture(target, capture) {
@@ -298,17 +311,6 @@ function patternCapture(value, pattern) {
298
311
  return String(value).slice(prefix.length, String(value).length - suffix.length);
299
312
  }
300
313
 
301
- function pathInsideRoot(sourcePath, root) {
302
- if (!root) return true;
303
- return sourcePath === root || sourcePath.startsWith(`${root}/`);
304
- }
314
+ function pathInsideRoot(sourcePath, root) { return !root || sourcePath === root || sourcePath.startsWith(`${root}/`); }
305
315
 
306
- export {
307
- exportMapMatch,
308
- exportTargetsForValue,
309
- packageConditions,
310
- packageEnvironmentConditionAmbiguity,
311
- packageEnvironmentConditionEvidence,
312
- packageRuntimeConditionAmbiguity,
313
- packageRuntimeConditionEvidence
314
- };
316
+ export { exportMapMatch, exportTargetsForValue, packageConditions, packageEnvironmentConditionAmbiguity, packageEnvironmentConditionEvidence, packageRuntimeConditionAmbiguity, packageRuntimeConditionEvidence };
@@ -0,0 +1,22 @@
1
+ function runtimeAdmittedConditions(conditions, runtimeCondition) {
2
+ const entries = Array.isArray(conditions) ? conditions : [conditions];
3
+ const excluded = new Set(runtimeExcludedConditions(runtimeCondition));
4
+ return excluded.size ? entries.filter((entry) => !excluded.has(String(entry))) : entries;
5
+ }
6
+
7
+ function runtimeConditionRecord(record) {
8
+ return compactRecord({
9
+ ...record,
10
+ packageRuntimeConditionExcludedConditions: runtimeExcludedConditions(record.packageRuntimeCondition)
11
+ });
12
+ }
13
+
14
+ function runtimeExcludedConditions(runtimeCondition) {
15
+ if (runtimeCondition === 'import') return ['require'];
16
+ if (runtimeCondition === 'require') return ['import', 'module'];
17
+ return [];
18
+ }
19
+
20
+ function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
21
+
22
+ export { runtimeAdmittedConditions, runtimeConditionRecord };