@shapeshift-labs/frontier-lang-compiler 0.2.162 → 0.2.164
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/dist/internal/index-impl/moduleHostResourceImportMetadata.js +47 -0
- package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +84 -12
- package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +1 -1
- package/dist/internal/index-impl/projectSymbolGraphCssModules.js +48 -4
- package/dist/internal/index-impl/projectSymbolGraphJsxPropRecordFields.js +91 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +26 -135
- package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +4 -31
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollectionHelpers.js +201 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollections.js +210 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +12 -5
- package/dist/internal/index-impl/projectSymbolGraphJsxSpreadPropValues.js +196 -0
- package/dist/internal/index-impl/projectSymbolGraphJsxStaticLiterals.js +207 -0
- package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +12 -14
- package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +22 -17
- package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +27 -1
- package/dist/js-ts-safe-project-merge-html-css-matrix.js +7 -2
- package/dist/js-ts-safe-project-merge-html-css-summary.js +90 -8
- package/dist/js-ts-safe-project-merge-html-css.js +137 -3
- package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +9 -0
- package/dist/js-ts-safe-project-merge-missing-evidence.js +12 -12
- package/dist/js-ts-safe-project-merge-source-text-candidate.js +68 -0
- package/dist/js-ts-safe-project-merge-summary.js +8 -11
- package/dist/js-ts-safe-project-merge.js +3 -0
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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, packageRuntimeConditionExcludedConditions: candidate.packageRuntimeConditionExcludedConditions, 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,4 +1,5 @@
|
|
|
1
1
|
import { runtimeAdmittedConditions, runtimeConditionRecord } from './projectSymbolGraphPackageRuntimeConditions.js';
|
|
2
|
+
import { hostResourceImportDependencyKind } from './moduleHostResourceImportMetadata.js';
|
|
2
3
|
|
|
3
4
|
const EnvironmentPackageConditions = Object.freeze([
|
|
4
5
|
'browser',
|
|
@@ -11,6 +12,7 @@ const EnvironmentPackageConditions = Object.freeze([
|
|
|
11
12
|
'bun',
|
|
12
13
|
'react-native'
|
|
13
14
|
]);
|
|
15
|
+
const PACKAGE_RUNTIME_CONDITION_HOST_RESOURCE_IMPORT_AMBIGUOUS_MISSING = 'package-runtime-condition-host-resource-import-ambiguous-missing';
|
|
14
16
|
|
|
15
17
|
function exportTargetsForValue(value, conditions, condition) {
|
|
16
18
|
if (!value) return [];
|
|
@@ -62,9 +64,11 @@ function packageEnvironmentConditionAmbiguity(value, moduleResolution, sourcePat
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
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;
|
|
65
70
|
const edgeCondition = packageRuntimeConditionFromEdge(edgeMetadata);
|
|
66
71
|
const extensionCondition = packageRuntimeConditionFromExtension(sourcePath);
|
|
67
|
-
const packageType = packageTypeForSource(moduleResolution, sourcePath, packageContext);
|
|
68
72
|
const packageTypeCondition = packageType === 'module' ? 'import' : packageType === 'commonjs' ? 'require' : undefined;
|
|
69
73
|
if (edgeCondition) {
|
|
70
74
|
const conflict = edgeCondition.conflictsWithSource && (
|
|
@@ -182,6 +186,19 @@ function packageRuntimeHostConditionAmbiguity(edgeMetadata = {}, packageType) {
|
|
|
182
186
|
});
|
|
183
187
|
}
|
|
184
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
|
+
|
|
185
202
|
function edgeCondition(packageRuntimeCondition, packageRuntimeConditionEdgeKind, packageRuntimeConditionReasonCode, preferred, conflictsWithSource) {
|
|
186
203
|
return runtimeConditionRecord({
|
|
187
204
|
packageRuntimeCondition,
|
|
@@ -245,10 +262,7 @@ function packageTypeByRoot(typeMap, sourcePath) {
|
|
|
245
262
|
.sort((left, right) => right.root.length - left.root.length)[0]?.value;
|
|
246
263
|
}
|
|
247
264
|
|
|
248
|
-
function normalizePackageType(value) {
|
|
249
|
-
const type = typeof value === 'string' ? value : value?.type ?? value?.packageType;
|
|
250
|
-
return type === 'module' || type === 'commonjs' ? type : undefined;
|
|
251
|
-
}
|
|
265
|
+
function normalizePackageType(value) { const type = typeof value === 'string' ? value : value?.type ?? value?.packageType; return type === 'module' || type === 'commonjs' ? type : undefined; }
|
|
252
266
|
|
|
253
267
|
function sameSet(left, right) {
|
|
254
268
|
if (left.size !== right.size) return false;
|
|
@@ -256,13 +270,8 @@ function sameSet(left, right) {
|
|
|
256
270
|
return true;
|
|
257
271
|
}
|
|
258
272
|
|
|
259
|
-
function uniqueStrings(values) {
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
function stringValue(value) {
|
|
264
|
-
return typeof value === 'string' && value.length ? value : undefined;
|
|
265
|
-
}
|
|
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; }
|
|
266
275
|
|
|
267
276
|
function prioritizeConditions(conditions, preferred) {
|
|
268
277
|
const entries = Array.isArray(conditions) ? conditions : [conditions];
|
|
@@ -276,7 +285,6 @@ function prioritizeConditions(conditions, preferred) {
|
|
|
276
285
|
}
|
|
277
286
|
|
|
278
287
|
function isRecord(value) { return value && typeof value === 'object' && !Array.isArray(value); }
|
|
279
|
-
|
|
280
288
|
function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
|
|
281
289
|
|
|
282
290
|
function replaceTargetCapture(target, capture) {
|
|
@@ -303,9 +311,6 @@ function patternCapture(value, pattern) {
|
|
|
303
311
|
return String(value).slice(prefix.length, String(value).length - suffix.length);
|
|
304
312
|
}
|
|
305
313
|
|
|
306
|
-
function pathInsideRoot(sourcePath, root) {
|
|
307
|
-
if (!root) return true;
|
|
308
|
-
return sourcePath === root || sourcePath.startsWith(`${root}/`);
|
|
309
|
-
}
|
|
314
|
+
function pathInsideRoot(sourcePath, root) { return !root || sourcePath === root || sourcePath.startsWith(`${root}/`); }
|
|
310
315
|
|
|
311
316
|
export { exportMapMatch, exportTargetsForValue, packageConditions, packageEnvironmentConditionAmbiguity, packageEnvironmentConditionEvidence, packageRuntimeConditionAmbiguity, packageRuntimeConditionEvidence };
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from './syntaxCommonJsModuleDeclarationEntries.js';
|
|
6
6
|
import { dynamicImportExpressionMetadata } from './dynamicImportExpressionMetadata.js';
|
|
7
7
|
import { hostModuleDependencyMetadata } from './importMetaUrlDependencyMetadata.js';
|
|
8
|
+
import { moduleHostResourceImportMetadata } from './moduleHostResourceImportMetadata.js';
|
|
8
9
|
import { moduleImportAttributeMetadata } from './moduleImportAttributeMetadata.js';
|
|
9
10
|
import {
|
|
10
11
|
declarationName,
|
|
@@ -38,10 +39,15 @@ function importDeclarationEntries(node, nativeNodeId, input) {
|
|
|
38
39
|
if (!moduleSpecifier) return [];
|
|
39
40
|
const typeOnly = node.importKind === 'type';
|
|
40
41
|
const bindings = (node.specifiers ?? []).map((specifier) => importSpecifierBinding(specifier, typeOnly)).filter(Boolean);
|
|
42
|
+
const importKind = bindings.length === 0 ? 'side-effect' : 'module';
|
|
41
43
|
return importModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
|
|
42
44
|
typeOnly,
|
|
43
45
|
sideEffectOnly: bindings.length === 0,
|
|
44
|
-
importKind
|
|
46
|
+
importKind,
|
|
47
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
48
|
+
hostDependencyBase: 'module-import',
|
|
49
|
+
expressionText: `import ${JSON.stringify(moduleSpecifier)}`
|
|
50
|
+
}),
|
|
45
51
|
...moduleImportAttributeMetadata(node)
|
|
46
52
|
});
|
|
47
53
|
}
|
|
@@ -54,6 +60,10 @@ function dynamicImportExpressionEntries(node, nativeNodeId, input) {
|
|
|
54
60
|
importKind: 'dynamic-import',
|
|
55
61
|
dynamicImport: true,
|
|
56
62
|
...dynamicImportExpressionMetadata(importArgument, moduleSpecifier),
|
|
63
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
64
|
+
hostDependencyBase: 'dynamic-import',
|
|
65
|
+
expressionText: `import(${JSON.stringify(moduleSpecifier)})`
|
|
66
|
+
}),
|
|
57
67
|
...moduleImportAttributeMetadata(node)
|
|
58
68
|
});
|
|
59
69
|
}
|
|
@@ -75,12 +85,20 @@ function exportNamedDeclarationEntries(node, nativeNodeId, input) {
|
|
|
75
85
|
typeOnly,
|
|
76
86
|
reexport: true,
|
|
77
87
|
importKind: 'reexport',
|
|
88
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
89
|
+
hostDependencyBase: 'module-reexport',
|
|
90
|
+
expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
|
|
91
|
+
}),
|
|
78
92
|
...moduleImportAttributeMetadata(node)
|
|
79
93
|
}) : []),
|
|
80
94
|
...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
|
|
81
95
|
typeOnly,
|
|
82
96
|
reExport: Boolean(moduleSpecifier),
|
|
83
97
|
exportKind: typeOnly ? 'type-named' : 'named',
|
|
98
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
99
|
+
hostDependencyBase: 'module-reexport',
|
|
100
|
+
expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
|
|
101
|
+
}),
|
|
84
102
|
...moduleImportAttributeMetadata(node)
|
|
85
103
|
})
|
|
86
104
|
];
|
|
@@ -107,6 +125,10 @@ function exportAllDeclarationEntries(node, nativeNodeId, input) {
|
|
|
107
125
|
reexport: true,
|
|
108
126
|
exportStar: !exportedName,
|
|
109
127
|
importKind: exportedName ? 'namespace-reexport' : 'reexport',
|
|
128
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
129
|
+
hostDependencyBase: 'module-reexport',
|
|
130
|
+
expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
|
|
131
|
+
}),
|
|
110
132
|
...moduleImportAttributeMetadata(node)
|
|
111
133
|
}),
|
|
112
134
|
...exportModuleEntries(input, nativeNodeId, moduleSpecifier, bindings, {
|
|
@@ -114,6 +136,10 @@ function exportAllDeclarationEntries(node, nativeNodeId, input) {
|
|
|
114
136
|
reExport: true,
|
|
115
137
|
exportStar: !exportedName,
|
|
116
138
|
exportKind: exportedName ? 'namespace-reexport' : 'export-star',
|
|
139
|
+
...moduleHostResourceImportMetadata(moduleSpecifier, {
|
|
140
|
+
hostDependencyBase: 'module-reexport',
|
|
141
|
+
expressionText: `export from ${JSON.stringify(moduleSpecifier)}`
|
|
142
|
+
}),
|
|
117
143
|
...moduleImportAttributeMetadata(node)
|
|
118
144
|
})
|
|
119
145
|
];
|
|
@@ -5,6 +5,7 @@ const HtmlCssProjectMergeMissingSignals = Object.freeze({
|
|
|
5
5
|
cssSelectorTargetEvidence: 'css-selector-target-evidence-missing',
|
|
6
6
|
htmlStructuralMerge: 'html-structural-merge-proof-blocked',
|
|
7
7
|
cssCascadeMerge: 'css-cascade-merge-proof-blocked',
|
|
8
|
+
cssDependencyGraphEvidence: 'css-dependency-graph-evidence-missing',
|
|
8
9
|
htmlCssBrowserRuntimeProof: 'html-css-browser-runtime-proof-not-available'
|
|
9
10
|
});
|
|
10
11
|
|
|
@@ -16,6 +17,7 @@ function htmlCssProjectMergeMissingEvidenceRoutes(route, signals) {
|
|
|
16
17
|
[signals.cssSelectorTargetEvidence]: route('prove-css-selector-target-evidence', 'layout-style-targets', 'supply-selector-target-graph-and-rebase-evidence'),
|
|
17
18
|
[signals.htmlStructuralMerge]: route('admit-html-structural-merge', 'layout-markup-graph', 'supply-html-parser-reference-and-boundary-evidence'),
|
|
18
19
|
[signals.cssCascadeMerge]: route('admit-css-cascade-merge', 'layout-style-graph', 'supply-css-parser-cascade-and-scope-evidence'),
|
|
20
|
+
[signals.cssDependencyGraphEvidence]: route('prove-css-dependency-graph', 'layout-style-graph', 'supply-css-custom-property-animation-font-and-asset-dependency-graph'),
|
|
19
21
|
[signals.htmlCssBrowserRuntimeProof]: route('prove-html-css-browser-runtime', 'browser-proof', 'attach-browser-runtime-proof-bundle')
|
|
20
22
|
};
|
|
21
23
|
}
|
|
@@ -28,6 +30,7 @@ function htmlCssProjectMergeAdmissionMatrixRows(matrixRow, signals) {
|
|
|
28
30
|
matrixRow('css-selector-target-evidence', 'bounded-evidence', ['css-selector-target-evidence'], [signals.cssSelectorTargetEvidence]),
|
|
29
31
|
matrixRow('html-structural-merge-admission', 'partial', ['html-structural-merge'], [signals.htmlStructuralMerge]),
|
|
30
32
|
matrixRow('css-cascade-merge-admission', 'partial', ['css-cascade-merge'], [signals.cssCascadeMerge]),
|
|
33
|
+
matrixRow('css-dependency-graph-evidence', 'bounded-evidence', ['css-dependency-graph'], [signals.cssDependencyGraphEvidence]),
|
|
31
34
|
matrixRow('html-css-browser-runtime-proof', 'bounded-evidence', ['browser-runtime-proof'], [signals.htmlCssBrowserRuntimeProof])
|
|
32
35
|
];
|
|
33
36
|
}
|
|
@@ -36,10 +39,11 @@ function htmlCssProjectMergeMissingEvidenceItems(summary, signals, missingEviden
|
|
|
36
39
|
const items = [];
|
|
37
40
|
if (summary.htmlFiles && summary.htmlParserEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlParserEvidence, scope: 'layout-markup-parser', kind: 'html-parser-source-evidence', proofLevel: 'html-parser-source-evidence', action: 'review', summary: `HTML project merge has parser/source evidence for ${summary.htmlParserEvidenceFiles}/${summary.htmlFiles} file(s); require parse5 source spans, zero parse errors, and attribute/trivia spans when those surfaces are present before parser evidence admission.` }));
|
|
38
41
|
if (summary.cssFiles && summary.cssParserEvidenceFiles !== summary.cssFiles) items.push(missingEvidenceItem({ code: signals.cssParserEvidence, scope: 'layout-style-parser', kind: 'css-parser-source-evidence', proofLevel: 'css-parser-source-evidence', action: 'review', summary: `CSS project merge has parser/source evidence for ${summary.cssParserEvidenceFiles}/${summary.cssFiles} file(s); require PostCSS rule/declaration spans, raw trivia hashes, and zero parse errors before parser evidence admission.` }));
|
|
39
|
-
if (summary.htmlFiles && summary.htmlIdentityEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlIdentityEvidence, scope: 'layout-markup-identity', kind: 'html-identity-evidence', proofLevel: 'html-identity-evidence', action: 'review', summary: `HTML project merge has structural identity evidence for ${summary.htmlIdentityEvidenceFiles}/${summary.htmlFiles} file(s); require parser-backed structural spans and stable explicit/path identity accounting before structural admission.` }));
|
|
42
|
+
if (summary.htmlFiles && summary.htmlIdentityEvidenceFiles !== summary.htmlFiles) items.push(missingEvidenceItem({ code: signals.htmlIdentityEvidence, scope: 'layout-markup-identity', kind: 'html-identity-evidence', proofLevel: 'html-identity-evidence', action: 'review', summary: `HTML project merge has structural identity evidence for ${summary.htmlIdentityEvidenceFiles}/${summary.htmlFiles} file(s) with ${summary.htmlDuplicateIdentityEvidenceFiles ?? 0} duplicate identity evidence file(s); require parser-backed structural spans, unique explicit identity keys, and stable explicit/path identity accounting before structural admission.` }));
|
|
40
43
|
if (summary.cssFiles && (summary.cssSelectorTargetEvidenceFiles !== summary.cssFiles || summary.cssSelectorTargetConflictFiles)) items.push(missingEvidenceItem({ code: signals.cssSelectorTargetEvidence, scope: 'layout-style-targets', kind: 'css-selector-target-evidence', proofLevel: 'css-selector-target-evidence', action: 'review', summary: `CSS project merge has selector-target evidence for ${summary.cssSelectorTargetEvidenceFiles}/${summary.cssFiles} file(s) with ${summary.cssSelectorTargetConflictFiles} selector target conflict(s); require selector target graph and proven rebase before target-moving merges.` }));
|
|
41
44
|
if (summary.htmlBlockedFiles) items.push(missingEvidenceItem({ code: signals.htmlStructuralMerge, scope: 'layout-markup-graph', kind: 'html-structural-merge-proof', proofLevel: 'html-structural-merge', action: 'review', summary: `HTML project merge has ${summary.htmlBlockedFiles} blocked file(s); supply parser/source-span evidence, stable element identity, and runtime-boundary proof before admission.` }));
|
|
42
|
-
if (summary.cssBlockedFiles) items.push(missingEvidenceItem({ code: signals.cssCascadeMerge, scope: 'layout-style-graph', kind: 'css-cascade-merge-proof', proofLevel: 'css-cascade-merge', action: 'review', summary: `CSS project merge has ${summary.cssBlockedFiles} blocked file(s); supply parser/cascade/scope evidence and keep browser claims false until runtime proof passes.` }));
|
|
45
|
+
if (summary.cssBlockedFiles) items.push(missingEvidenceItem({ code: signals.cssCascadeMerge, scope: 'layout-style-graph', kind: 'css-cascade-merge-proof', proofLevel: 'css-cascade-merge', action: 'review', summary: `CSS project merge has ${summary.cssBlockedFiles} blocked file(s), including ${summary.cssScopedCascadeBlockedFiles} scoped cascade proof block(s); supply parser/cascade/scope evidence, require scopedCascadeGraphHash for changed declarations under @media/@supports/@container/@layer/@scope or nested scopes, and keep browser claims false until runtime proof passes.` }));
|
|
46
|
+
if (summary.cssDependencySurfaceFiles && (summary.cssDependencyGraphEvidenceFiles !== summary.cssDependencySurfaceFiles || summary.cssDependencyGraphMissingProofFiles || summary.cssDependencyGraphBlockedFiles)) items.push(missingEvidenceItem({ code: signals.cssDependencyGraphEvidence, scope: 'layout-style-graph', kind: 'css-dependency-graph-evidence', proofLevel: 'css-dependency-graph', action: 'review', summary: `CSS project merge has dependency graph evidence for ${summary.cssDependencyGraphEvidenceFiles}/${summary.cssDependencySurfaceFiles} dependency-surface file(s), ${summary.cssDependencyGraphMissingProofFiles} missing dependency graph proof(s), and ${summary.cssDependencyGraphBlockedFiles} dependency blocker(s); require custom property, var() fallback, @keyframes/animation-name, @font-face, and url() asset graph evidence before cascade/browser equivalence claims.`, suggestedInput: { cssDependencyGraphEvidence: true } }));
|
|
43
47
|
if (summary.htmlCssMergedFiles && !summary.htmlCssBrowserRuntimeProofs) items.push(missingEvidenceItem({ code: signals.htmlCssBrowserRuntimeProof, scope: 'browser-proof', kind: 'browser-runtime-proof', proofLevel: 'browser-runtime-proof', action: 'review', summary: 'HTML/CSS structural source merge was available, but browser DOM/cascade/layout/runtime proof was not attached; keep browser equivalence claims false.', suggestedInput: { browserRuntimeProof: true } }));
|
|
44
48
|
return items;
|
|
45
49
|
}
|
|
@@ -51,6 +55,7 @@ function htmlCssProjectMergeMatrixProofStatus(level, summary) {
|
|
|
51
55
|
if (level === 'css-selector-target-evidence') return summary.cssFiles ? (summary.cssSelectorTargetConflictFiles ? 'failed' : summary.cssSelectorTargetEvidenceFiles === summary.cssFiles ? 'passed' : 'missing') : 'absent';
|
|
52
56
|
if (level === 'html-structural-merge') return summary.htmlFiles ? (summary.htmlBlockedFiles ? 'failed' : summary.htmlMergedFiles ? 'passed' : 'missing') : 'absent';
|
|
53
57
|
if (level === 'css-cascade-merge') return summary.cssFiles ? (summary.cssBlockedFiles ? 'failed' : summary.cssMergedFiles ? 'passed' : 'missing') : 'absent';
|
|
58
|
+
if (level === 'css-dependency-graph') return summary.cssDependencySurfaceFiles ? (summary.cssDependencyGraphBlockedFiles ? 'failed' : summary.cssDependencyGraphEvidenceFiles === summary.cssDependencySurfaceFiles ? 'passed' : 'missing') : 'absent';
|
|
54
59
|
if (level === 'browser-runtime-proof') return summary.htmlCssFiles ? (summary.htmlCssBrowserRuntimeProofs ? 'passed' : 'missing') : 'absent';
|
|
55
60
|
return undefined;
|
|
56
61
|
}
|