@loj-lang/rdsl-compiler 0.5.0 → 0.6.0
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/codegen.d.ts.map +1 -1
- package/dist/codegen.js +3952 -1171
- package/dist/codegen.js.map +1 -1
- package/dist/dependency-graph.js +2 -2
- package/dist/dependency-graph.js.map +1 -1
- package/dist/expr.d.ts +24 -3
- package/dist/expr.d.ts.map +1 -1
- package/dist/expr.js +211 -8
- package/dist/expr.js.map +1 -1
- package/dist/flow-proof.d.ts +23 -3
- package/dist/flow-proof.d.ts.map +1 -1
- package/dist/flow-proof.js +179 -26
- package/dist/flow-proof.js.map +1 -1
- package/dist/formula-proof.d.ts +30 -0
- package/dist/formula-proof.d.ts.map +1 -0
- package/dist/formula-proof.js +596 -0
- package/dist/formula-proof.js.map +1 -0
- package/dist/host-files.d.ts +34 -0
- package/dist/host-files.d.ts.map +1 -1
- package/dist/host-files.js +418 -20
- package/dist/host-files.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +147 -9
- package/dist/index.js.map +1 -1
- package/dist/ir.d.ts +142 -8
- package/dist/ir.d.ts.map +1 -1
- package/dist/manifest.d.ts +51 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +107 -5
- package/dist/manifest.js.map +1 -1
- package/dist/model-display-field.d.ts +3 -0
- package/dist/model-display-field.d.ts.map +1 -0
- package/dist/model-display-field.js +5 -0
- package/dist/model-display-field.js.map +1 -0
- package/dist/model-field-type.d.ts +10 -0
- package/dist/model-field-type.d.ts.map +1 -0
- package/dist/model-field-type.js +25 -0
- package/dist/model-field-type.js.map +1 -0
- package/dist/node-inspect.js +12 -5
- package/dist/node-inspect.js.map +1 -1
- package/dist/normalize.d.ts +4 -0
- package/dist/normalize.d.ts.map +1 -1
- package/dist/normalize.js +492 -59
- package/dist/normalize.js.map +1 -1
- package/dist/page-table-block.d.ts +11 -2
- package/dist/page-table-block.d.ts.map +1 -1
- package/dist/page-table-block.js +33 -1
- package/dist/page-table-block.js.map +1 -1
- package/dist/parser.d.ts +151 -4
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +798 -40
- package/dist/parser.js.map +1 -1
- package/dist/relation-projection.d.ts +1 -1
- package/dist/relation-projection.d.ts.map +1 -1
- package/dist/rules-proof.d.ts +16 -1
- package/dist/rules-proof.d.ts.map +1 -1
- package/dist/rules-proof.js +522 -28
- package/dist/rules-proof.js.map +1 -1
- package/dist/source-files.d.ts +7 -0
- package/dist/source-files.d.ts.map +1 -1
- package/dist/source-files.js +15 -2
- package/dist/source-files.js.map +1 -1
- package/dist/style-proof.d.ts +16 -2
- package/dist/style-proof.d.ts.map +1 -1
- package/dist/style-proof.js +156 -11
- package/dist/style-proof.js.map +1 -1
- package/dist/validator.d.ts +10 -0
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +939 -86
- package/dist/validator.js.map +1 -1
- package/package.json +31 -10
package/dist/host-files.d.ts
CHANGED
|
@@ -10,11 +10,26 @@ export interface HostFileDependencyEntry {
|
|
|
10
10
|
path: string;
|
|
11
11
|
kind: 'script' | 'style';
|
|
12
12
|
importers: string[];
|
|
13
|
+
declaredIn?: string;
|
|
14
|
+
declaredRole?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface HostFileImportEntry {
|
|
17
|
+
specifier: string;
|
|
18
|
+
packageName: string;
|
|
19
|
+
kind: 'target-runtime' | 'declared-package' | 'undeclared-package' | 'node-builtin';
|
|
20
|
+
importers: string[];
|
|
21
|
+
declaredIn?: string;
|
|
22
|
+
declaredVersion?: string;
|
|
23
|
+
declaredSource?: string;
|
|
24
|
+
declaredScope?: string;
|
|
13
25
|
}
|
|
14
26
|
export interface HostFileEntry {
|
|
15
27
|
path: string;
|
|
16
28
|
references: HostFileReferenceEntry[];
|
|
17
29
|
dependencies?: HostFileDependencyEntry[];
|
|
30
|
+
imports?: HostFileImportEntry[];
|
|
31
|
+
manifestPath?: string;
|
|
32
|
+
manifestWarnings?: string[];
|
|
18
33
|
}
|
|
19
34
|
export interface HostFileCollectionOptions {
|
|
20
35
|
readFile?: (filePath: string) => string | undefined;
|
|
@@ -23,5 +38,24 @@ export declare function collectHostFileSegments(ir: IRApp | undefined, options?:
|
|
|
23
38
|
export declare function collectHostFiles(ir: IRApp | undefined, options?: HostFileCollectionOptions): HostFileEntry[];
|
|
24
39
|
export declare function listHostFilesForNode(hostFiles: HostFileEntry[], nodeId: string): HostFileEntry[];
|
|
25
40
|
export declare function listMaterializedHostFiles(hostFiles: HostFileEntry[]): string[];
|
|
41
|
+
export declare function listUndeclaredHostImports(hostFiles: HostFileEntry[]): Array<{
|
|
42
|
+
path: string;
|
|
43
|
+
specifier: string;
|
|
44
|
+
packageName: string;
|
|
45
|
+
}>;
|
|
46
|
+
export declare function listDeclaredHostImports(hostFiles: HostFileEntry[]): Array<{
|
|
47
|
+
path: string;
|
|
48
|
+
specifier: string;
|
|
49
|
+
packageName: string;
|
|
50
|
+
declaredIn: string;
|
|
51
|
+
declaredVersion?: string;
|
|
52
|
+
declaredSource?: string;
|
|
53
|
+
declaredScope?: string;
|
|
54
|
+
importers: string[];
|
|
55
|
+
}>;
|
|
56
|
+
export declare function listHostManifestWarnings(hostFiles: HostFileEntry[]): Array<{
|
|
57
|
+
path: string;
|
|
58
|
+
message: string;
|
|
59
|
+
}>;
|
|
26
60
|
export declare function mergeHostFileSegments(segments: Record<string, HostFileEntry[]>): HostFileEntry[];
|
|
27
61
|
//# sourceMappingURL=host-files.d.ts.map
|
package/dist/host-files.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-files.d.ts","sourceRoot":"","sources":["../src/host-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EAWN,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"host-files.d.ts","sourceRoot":"","sources":["../src/host-files.ts"],"names":[],"mappings":"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"}
|
package/dist/host-files.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildNativeUnitManifestPath, parseNativeUnitManifestJson, } from '@loj-lang/shared-contracts';
|
|
1
2
|
import { analyzePageTableBlockData } from './page-table-block.js';
|
|
2
3
|
import { dirnameProjectPath, resolveProjectPath, toProjectRelativePath, } from './project-paths.js';
|
|
3
4
|
export function collectHostFileSegments(ir, options = {}) {
|
|
@@ -5,6 +6,8 @@ export function collectHostFileSegments(ir, options = {}) {
|
|
|
5
6
|
return {};
|
|
6
7
|
const segments = new Map();
|
|
7
8
|
const dependencyCache = new Map();
|
|
9
|
+
const importCache = new Map();
|
|
10
|
+
const manifestCache = new Map();
|
|
8
11
|
const addReference = (rootId, path, owner, role, metadata = {}) => {
|
|
9
12
|
if (!path)
|
|
10
13
|
return;
|
|
@@ -118,15 +121,20 @@ export function collectHostFileSegments(ir, options = {}) {
|
|
|
118
121
|
.map(([rootId, entries]) => [
|
|
119
122
|
rootId,
|
|
120
123
|
Array.from(entries.values())
|
|
121
|
-
.map((entry) =>
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
.map((entry) => {
|
|
125
|
+
const manifestState = options.readFile
|
|
126
|
+
? loadFrontendNativeUnitManifestState(entry.path, options.readFile, manifestCache)
|
|
127
|
+
: undefined;
|
|
128
|
+
return {
|
|
129
|
+
path: entry.path,
|
|
130
|
+
references: [...entry.references].sort(compareHostFileReference),
|
|
131
|
+
dependencies: getHostDependencies(entry.path, options.readFile, dependencyCache, manifestCache),
|
|
132
|
+
imports: getHostImports(entry.path, options.readFile, importCache, manifestCache),
|
|
133
|
+
manifestPath: manifestState?.exists ? manifestState.path : undefined,
|
|
134
|
+
manifestWarnings: manifestState?.warnings.length ? [...manifestState.warnings].sort((left, right) => left.localeCompare(right)) : undefined,
|
|
135
|
+
};
|
|
129
136
|
})
|
|
137
|
+
.map((entry) => stripEmptyHostMetadata(entry))
|
|
130
138
|
.sort((left, right) => left.path.localeCompare(right.path)),
|
|
131
139
|
]));
|
|
132
140
|
}
|
|
@@ -139,6 +147,7 @@ export function listHostFilesForNode(hostFiles, nodeId) {
|
|
|
139
147
|
path: entry.path,
|
|
140
148
|
references: entry.references.filter((reference) => reference.nodeId === nodeId),
|
|
141
149
|
dependencies: entry.dependencies ? [...entry.dependencies] : undefined,
|
|
150
|
+
imports: entry.imports ? [...entry.imports] : undefined,
|
|
142
151
|
}))
|
|
143
152
|
.filter((entry) => entry.references.length > 0)
|
|
144
153
|
.sort((left, right) => left.path.localeCompare(right.path));
|
|
@@ -147,12 +156,91 @@ export function listMaterializedHostFiles(hostFiles) {
|
|
|
147
156
|
const paths = new Set();
|
|
148
157
|
for (const entry of hostFiles) {
|
|
149
158
|
paths.add(entry.path);
|
|
159
|
+
if (entry.manifestPath) {
|
|
160
|
+
paths.add(entry.manifestPath);
|
|
161
|
+
}
|
|
150
162
|
for (const dependency of entry.dependencies ?? []) {
|
|
151
163
|
paths.add(dependency.path);
|
|
152
164
|
}
|
|
153
165
|
}
|
|
154
166
|
return Array.from(paths).sort((left, right) => left.localeCompare(right));
|
|
155
167
|
}
|
|
168
|
+
export function listUndeclaredHostImports(hostFiles) {
|
|
169
|
+
const findings = [];
|
|
170
|
+
for (const entry of hostFiles) {
|
|
171
|
+
for (const importEntry of entry.imports ?? []) {
|
|
172
|
+
if (importEntry.kind !== 'undeclared-package') {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
findings.push({
|
|
176
|
+
path: entry.path,
|
|
177
|
+
specifier: importEntry.specifier,
|
|
178
|
+
packageName: importEntry.packageName,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return findings.sort((left, right) => {
|
|
183
|
+
if (left.path !== right.path) {
|
|
184
|
+
return left.path.localeCompare(right.path);
|
|
185
|
+
}
|
|
186
|
+
return left.specifier.localeCompare(right.specifier);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
export function listDeclaredHostImports(hostFiles) {
|
|
190
|
+
const findings = new Map();
|
|
191
|
+
for (const entry of hostFiles) {
|
|
192
|
+
for (const importEntry of entry.imports ?? []) {
|
|
193
|
+
if (importEntry.kind !== 'declared-package' || !importEntry.declaredIn) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const key = [
|
|
197
|
+
entry.path,
|
|
198
|
+
importEntry.specifier,
|
|
199
|
+
importEntry.declaredIn,
|
|
200
|
+
importEntry.declaredVersion ?? '',
|
|
201
|
+
importEntry.declaredSource ?? '',
|
|
202
|
+
importEntry.declaredScope ?? '',
|
|
203
|
+
importEntry.importers.join('\u0000'),
|
|
204
|
+
].join('::');
|
|
205
|
+
findings.set(key, {
|
|
206
|
+
path: entry.path,
|
|
207
|
+
specifier: importEntry.specifier,
|
|
208
|
+
packageName: importEntry.packageName,
|
|
209
|
+
declaredIn: importEntry.declaredIn,
|
|
210
|
+
declaredVersion: importEntry.declaredVersion,
|
|
211
|
+
declaredSource: importEntry.declaredSource,
|
|
212
|
+
declaredScope: importEntry.declaredScope,
|
|
213
|
+
importers: [...importEntry.importers].sort((left, right) => left.localeCompare(right)),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return Array.from(findings.values()).sort((left, right) => {
|
|
218
|
+
if (left.path !== right.path) {
|
|
219
|
+
return left.path.localeCompare(right.path);
|
|
220
|
+
}
|
|
221
|
+
if (left.packageName !== right.packageName) {
|
|
222
|
+
return left.packageName.localeCompare(right.packageName);
|
|
223
|
+
}
|
|
224
|
+
return left.specifier.localeCompare(right.specifier);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
export function listHostManifestWarnings(hostFiles) {
|
|
228
|
+
const warnings = [];
|
|
229
|
+
for (const entry of hostFiles) {
|
|
230
|
+
for (const message of entry.manifestWarnings ?? []) {
|
|
231
|
+
warnings.push({
|
|
232
|
+
path: entry.manifestPath ?? entry.path,
|
|
233
|
+
message,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return warnings.sort((left, right) => {
|
|
238
|
+
if (left.path !== right.path) {
|
|
239
|
+
return left.path.localeCompare(right.path);
|
|
240
|
+
}
|
|
241
|
+
return left.message.localeCompare(right.message);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
156
244
|
function collectRuleFiles(rootId, rules, owner, addRuleReference) {
|
|
157
245
|
if (!rules)
|
|
158
246
|
return;
|
|
@@ -169,8 +257,8 @@ function collectColumnFiles(rootId, column, addReference) {
|
|
|
169
257
|
addReference(rootId, column.customRenderer, column, 'column.customRenderer');
|
|
170
258
|
}
|
|
171
259
|
function collectFormFieldFiles(rootId, field, addReference, addRuleReference) {
|
|
172
|
-
addRuleReference(rootId, field.
|
|
173
|
-
addRuleReference(rootId, field.
|
|
260
|
+
addRuleReference(rootId, field.visibleIf, field, 'field.visibleIf');
|
|
261
|
+
addRuleReference(rootId, field.enabledIf, field, 'field.enabledIf');
|
|
174
262
|
addReference(rootId, field.validateFn?.path, field, 'field.validateFn', {
|
|
175
263
|
logicalPath: field.validateFn?.logicalPath,
|
|
176
264
|
lockIn: field.validateFn?.lockIn,
|
|
@@ -243,6 +331,9 @@ export function mergeHostFileSegments(segments) {
|
|
|
243
331
|
if (!target.dependencies) {
|
|
244
332
|
target.dependencies = [];
|
|
245
333
|
}
|
|
334
|
+
if (!target.imports) {
|
|
335
|
+
target.imports = [];
|
|
336
|
+
}
|
|
246
337
|
for (const reference of entry.references) {
|
|
247
338
|
if (!target.references.some((existing) => (existing.nodeId === reference.nodeId &&
|
|
248
339
|
existing.role === reference.role &&
|
|
@@ -270,6 +361,28 @@ export function mergeHostFileSegments(segments) {
|
|
|
270
361
|
});
|
|
271
362
|
}
|
|
272
363
|
}
|
|
364
|
+
for (const importEntry of entry.imports ?? []) {
|
|
365
|
+
const existingImport = target.imports?.find((candidate) => (candidate.specifier === importEntry.specifier &&
|
|
366
|
+
candidate.kind === importEntry.kind &&
|
|
367
|
+
candidate.packageName === importEntry.packageName &&
|
|
368
|
+
candidate.declaredIn === importEntry.declaredIn));
|
|
369
|
+
if (existingImport) {
|
|
370
|
+
for (const importer of importEntry.importers) {
|
|
371
|
+
if (!existingImport.importers.includes(importer)) {
|
|
372
|
+
existingImport.importers.push(importer);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
target.imports?.push({
|
|
378
|
+
specifier: importEntry.specifier,
|
|
379
|
+
packageName: importEntry.packageName,
|
|
380
|
+
kind: importEntry.kind,
|
|
381
|
+
importers: [...importEntry.importers],
|
|
382
|
+
declaredIn: importEntry.declaredIn,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
273
386
|
merged.set(entry.path, target);
|
|
274
387
|
}
|
|
275
388
|
}
|
|
@@ -278,11 +391,9 @@ export function mergeHostFileSegments(segments) {
|
|
|
278
391
|
path: entry.path,
|
|
279
392
|
references: [...entry.references].sort(compareHostFileReference),
|
|
280
393
|
dependencies: normalizeDependencies(entry.dependencies),
|
|
394
|
+
imports: normalizeImports(entry.imports),
|
|
281
395
|
}))
|
|
282
|
-
.map((entry) => entry
|
|
283
|
-
path: entry.path,
|
|
284
|
-
references: entry.references,
|
|
285
|
-
})
|
|
396
|
+
.map((entry) => stripEmptyHostMetadata(entry))
|
|
286
397
|
.sort((left, right) => left.path.localeCompare(right.path));
|
|
287
398
|
}
|
|
288
399
|
function normalizeDependencies(dependencies) {
|
|
@@ -306,7 +417,62 @@ function compareHostFileDependency(left, right) {
|
|
|
306
417
|
}
|
|
307
418
|
return left.importers.join(',').localeCompare(right.importers.join(','));
|
|
308
419
|
}
|
|
309
|
-
function
|
|
420
|
+
function normalizeImports(imports) {
|
|
421
|
+
if (!imports || imports.length === 0) {
|
|
422
|
+
return undefined;
|
|
423
|
+
}
|
|
424
|
+
return [...imports]
|
|
425
|
+
.map((entry) => ({
|
|
426
|
+
specifier: entry.specifier,
|
|
427
|
+
packageName: entry.packageName,
|
|
428
|
+
kind: entry.kind,
|
|
429
|
+
importers: [...entry.importers].sort((left, right) => left.localeCompare(right)),
|
|
430
|
+
declaredIn: entry.declaredIn,
|
|
431
|
+
declaredVersion: entry.declaredVersion,
|
|
432
|
+
declaredSource: entry.declaredSource,
|
|
433
|
+
declaredScope: entry.declaredScope,
|
|
434
|
+
}))
|
|
435
|
+
.sort(compareHostFileImport);
|
|
436
|
+
}
|
|
437
|
+
function compareHostFileImport(left, right) {
|
|
438
|
+
if (left.specifier !== right.specifier) {
|
|
439
|
+
return left.specifier.localeCompare(right.specifier);
|
|
440
|
+
}
|
|
441
|
+
if (left.kind !== right.kind) {
|
|
442
|
+
return left.kind.localeCompare(right.kind);
|
|
443
|
+
}
|
|
444
|
+
if ((left.declaredIn ?? '') !== (right.declaredIn ?? '')) {
|
|
445
|
+
return (left.declaredIn ?? '').localeCompare(right.declaredIn ?? '');
|
|
446
|
+
}
|
|
447
|
+
return left.importers.join(',').localeCompare(right.importers.join(','));
|
|
448
|
+
}
|
|
449
|
+
function stripEmptyHostMetadata(entry) {
|
|
450
|
+
if ((!entry.dependencies || entry.dependencies.length === 0) &&
|
|
451
|
+
(!entry.imports || entry.imports.length === 0) &&
|
|
452
|
+
!entry.manifestPath &&
|
|
453
|
+
(!entry.manifestWarnings || entry.manifestWarnings.length === 0)) {
|
|
454
|
+
return {
|
|
455
|
+
path: entry.path,
|
|
456
|
+
references: entry.references,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
if ((!entry.dependencies || entry.dependencies.length === 0) && !entry.manifestPath && (!entry.manifestWarnings || entry.manifestWarnings.length === 0)) {
|
|
460
|
+
return {
|
|
461
|
+
path: entry.path,
|
|
462
|
+
references: entry.references,
|
|
463
|
+
imports: entry.imports,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
if ((!entry.imports || entry.imports.length === 0) && !entry.manifestPath && (!entry.manifestWarnings || entry.manifestWarnings.length === 0)) {
|
|
467
|
+
return {
|
|
468
|
+
path: entry.path,
|
|
469
|
+
references: entry.references,
|
|
470
|
+
dependencies: entry.dependencies,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
return entry;
|
|
474
|
+
}
|
|
475
|
+
function getHostDependencies(hostFilePath, readFile, cache, manifestCache) {
|
|
310
476
|
if (!readFile) {
|
|
311
477
|
return undefined;
|
|
312
478
|
}
|
|
@@ -314,11 +480,25 @@ function getHostDependencies(hostFilePath, readFile, cache) {
|
|
|
314
480
|
if (cached) {
|
|
315
481
|
return cached;
|
|
316
482
|
}
|
|
317
|
-
const
|
|
483
|
+
const manifestState = loadFrontendNativeUnitManifestState(hostFilePath, readFile, manifestCache);
|
|
484
|
+
const dependencies = scanHostDependencies(hostFilePath, readFile, manifestState.manifest);
|
|
318
485
|
cache.set(hostFilePath, dependencies);
|
|
319
486
|
return dependencies.length > 0 ? dependencies : undefined;
|
|
320
487
|
}
|
|
321
|
-
function
|
|
488
|
+
function getHostImports(hostFilePath, readFile, cache, manifestCache) {
|
|
489
|
+
if (!readFile) {
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
const cached = cache.get(hostFilePath);
|
|
493
|
+
if (cached) {
|
|
494
|
+
return cached;
|
|
495
|
+
}
|
|
496
|
+
const manifestState = loadFrontendNativeUnitManifestState(hostFilePath, readFile, manifestCache);
|
|
497
|
+
const imports = scanHostImports(hostFilePath, readFile, manifestState.manifest);
|
|
498
|
+
cache.set(hostFilePath, imports);
|
|
499
|
+
return imports.length > 0 ? imports : undefined;
|
|
500
|
+
}
|
|
501
|
+
function scanHostDependencies(rootHostFilePath, readFile, manifest) {
|
|
322
502
|
const dependencies = new Map();
|
|
323
503
|
const visitedScripts = new Set();
|
|
324
504
|
const pendingScripts = [rootHostFilePath];
|
|
@@ -358,27 +538,138 @@ function scanHostDependencies(rootHostFilePath, readFile) {
|
|
|
358
538
|
}
|
|
359
539
|
}
|
|
360
540
|
}
|
|
541
|
+
for (const localFile of manifest?.localFiles ?? []) {
|
|
542
|
+
const resolved = resolveHostDependencyPath(rootHostFilePath, localFile.path, readFile);
|
|
543
|
+
if (!resolved || resolved.path === rootHostFilePath) {
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
const manifestPath = manifest?.path;
|
|
547
|
+
const existing = dependencies.get(resolved.path) ?? {
|
|
548
|
+
path: resolved.path,
|
|
549
|
+
kind: resolved.kind,
|
|
550
|
+
importers: [],
|
|
551
|
+
declaredIn: manifestPath,
|
|
552
|
+
declaredRole: localFile.role,
|
|
553
|
+
};
|
|
554
|
+
if (!existing.importers.includes(rootHostFilePath)) {
|
|
555
|
+
existing.importers.push(rootHostFilePath);
|
|
556
|
+
}
|
|
557
|
+
existing.declaredIn = existing.declaredIn ?? manifestPath;
|
|
558
|
+
existing.declaredRole = existing.declaredRole ?? localFile.role;
|
|
559
|
+
dependencies.set(resolved.path, existing);
|
|
560
|
+
if (resolved.kind === 'script') {
|
|
561
|
+
pendingScripts.push(resolved.path);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
361
564
|
return Array.from(dependencies.values())
|
|
362
565
|
.map((dependency) => ({
|
|
363
566
|
path: dependency.path,
|
|
364
567
|
kind: dependency.kind,
|
|
365
568
|
importers: [...dependency.importers].sort((left, right) => left.localeCompare(right)),
|
|
569
|
+
declaredIn: dependency.declaredIn,
|
|
570
|
+
declaredRole: dependency.declaredRole,
|
|
366
571
|
}))
|
|
367
572
|
.sort(compareHostFileDependency);
|
|
368
573
|
}
|
|
574
|
+
const NODE_BUILTIN_MODULES = new Set([
|
|
575
|
+
'assert',
|
|
576
|
+
'buffer',
|
|
577
|
+
'child_process',
|
|
578
|
+
'console',
|
|
579
|
+
'crypto',
|
|
580
|
+
'events',
|
|
581
|
+
'fs',
|
|
582
|
+
'http',
|
|
583
|
+
'https',
|
|
584
|
+
'module',
|
|
585
|
+
'os',
|
|
586
|
+
'path',
|
|
587
|
+
'process',
|
|
588
|
+
'stream',
|
|
589
|
+
'timers',
|
|
590
|
+
'tty',
|
|
591
|
+
'url',
|
|
592
|
+
'util',
|
|
593
|
+
'zlib',
|
|
594
|
+
]);
|
|
595
|
+
const REACT_TARGET_RUNTIME_PACKAGES = new Set([
|
|
596
|
+
'react',
|
|
597
|
+
'react-dom',
|
|
598
|
+
'@loj-lang/rdsl-runtime',
|
|
599
|
+
'@loj-lang/rdsl-host-react',
|
|
600
|
+
]);
|
|
601
|
+
function scanHostImports(rootHostFilePath, readFile, manifest) {
|
|
602
|
+
const imports = new Map();
|
|
603
|
+
const packageCache = new Map();
|
|
604
|
+
const sourceText = readFile(rootHostFilePath);
|
|
605
|
+
if (sourceText === undefined) {
|
|
606
|
+
return [];
|
|
607
|
+
}
|
|
608
|
+
for (const specifier of extractStaticPackageImports(sourceText)) {
|
|
609
|
+
const packageName = extractPackageName(specifier);
|
|
610
|
+
if (!packageName) {
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
const classification = classifyHostImport(rootHostFilePath, specifier, packageName, readFile, packageCache, manifest);
|
|
614
|
+
const key = `${specifier}:${classification.kind}:${classification.declaredIn ?? ''}`;
|
|
615
|
+
const existing = imports.get(key) ?? {
|
|
616
|
+
specifier,
|
|
617
|
+
packageName,
|
|
618
|
+
kind: classification.kind,
|
|
619
|
+
importers: [],
|
|
620
|
+
declaredIn: classification.declaredIn,
|
|
621
|
+
declaredVersion: classification.declaredVersion,
|
|
622
|
+
declaredSource: classification.declaredSource,
|
|
623
|
+
declaredScope: classification.declaredScope,
|
|
624
|
+
};
|
|
625
|
+
if (!existing.importers.includes(rootHostFilePath)) {
|
|
626
|
+
existing.importers.push(rootHostFilePath);
|
|
627
|
+
}
|
|
628
|
+
imports.set(key, existing);
|
|
629
|
+
}
|
|
630
|
+
return Array.from(imports.values())
|
|
631
|
+
.map((entry) => ({
|
|
632
|
+
specifier: entry.specifier,
|
|
633
|
+
packageName: entry.packageName,
|
|
634
|
+
kind: entry.kind,
|
|
635
|
+
importers: [...entry.importers].sort((left, right) => left.localeCompare(right)),
|
|
636
|
+
declaredIn: entry.declaredIn,
|
|
637
|
+
declaredVersion: entry.declaredVersion,
|
|
638
|
+
declaredSource: entry.declaredSource,
|
|
639
|
+
declaredScope: entry.declaredScope,
|
|
640
|
+
}))
|
|
641
|
+
.sort(compareHostFileImport);
|
|
642
|
+
}
|
|
369
643
|
function extractStaticRelativeImports(sourceText) {
|
|
370
644
|
const specifiers = new Set();
|
|
371
|
-
|
|
372
|
-
let match =
|
|
645
|
+
STATIC_IMPORT_PATTERN.lastIndex = 0;
|
|
646
|
+
let match = STATIC_IMPORT_PATTERN.exec(sourceText);
|
|
373
647
|
while (match) {
|
|
374
648
|
const specifier = match[1];
|
|
375
649
|
if (specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
376
650
|
specifiers.add(specifier);
|
|
377
651
|
}
|
|
378
|
-
match =
|
|
652
|
+
match = STATIC_IMPORT_PATTERN.exec(sourceText);
|
|
653
|
+
}
|
|
654
|
+
return Array.from(specifiers).sort((left, right) => left.localeCompare(right));
|
|
655
|
+
}
|
|
656
|
+
function extractStaticPackageImports(sourceText) {
|
|
657
|
+
const specifiers = new Set();
|
|
658
|
+
STATIC_IMPORT_PATTERN.lastIndex = 0;
|
|
659
|
+
let match = STATIC_IMPORT_PATTERN.exec(sourceText);
|
|
660
|
+
while (match) {
|
|
661
|
+
const specifier = match[1];
|
|
662
|
+
if (!specifier.startsWith('./') && !specifier.startsWith('../') && !specifier.startsWith('/') && !isUrlLikeSpecifier(specifier)) {
|
|
663
|
+
specifiers.add(specifier);
|
|
664
|
+
}
|
|
665
|
+
match = STATIC_IMPORT_PATTERN.exec(sourceText);
|
|
379
666
|
}
|
|
380
667
|
return Array.from(specifiers).sort((left, right) => left.localeCompare(right));
|
|
381
668
|
}
|
|
669
|
+
const STATIC_IMPORT_PATTERN = /\b(?:import|export)\s+(?:type\s+)?(?:[^'";]+?\s+from\s+)?["']([^"']+)["']/g;
|
|
670
|
+
function isUrlLikeSpecifier(specifier) {
|
|
671
|
+
return /^[a-z]+:\/\//i.test(specifier);
|
|
672
|
+
}
|
|
382
673
|
function classifyHostDependency(path) {
|
|
383
674
|
const normalizedPath = path.toLowerCase();
|
|
384
675
|
if (normalizedPath.endsWith('.css')) {
|
|
@@ -438,4 +729,111 @@ function isReadableHostDependency(filePath, readFile) {
|
|
|
438
729
|
return false;
|
|
439
730
|
}
|
|
440
731
|
}
|
|
732
|
+
function extractPackageName(specifier) {
|
|
733
|
+
if (specifier.startsWith('node:')) {
|
|
734
|
+
return specifier.slice(5);
|
|
735
|
+
}
|
|
736
|
+
if (specifier.startsWith('@')) {
|
|
737
|
+
const [scope, name] = specifier.split('/');
|
|
738
|
+
if (!scope || !name) {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
return `${scope}/${name}`;
|
|
742
|
+
}
|
|
743
|
+
const [name] = specifier.split('/');
|
|
744
|
+
return name || undefined;
|
|
745
|
+
}
|
|
746
|
+
function classifyHostImport(importerPath, specifier, packageName, readFile, packageCache, manifest) {
|
|
747
|
+
if (specifier.startsWith('node:') || NODE_BUILTIN_MODULES.has(packageName)) {
|
|
748
|
+
return { kind: 'node-builtin' };
|
|
749
|
+
}
|
|
750
|
+
if (REACT_TARGET_RUNTIME_PACKAGES.has(packageName)) {
|
|
751
|
+
return { kind: 'target-runtime' };
|
|
752
|
+
}
|
|
753
|
+
const declaredPackage = manifest?.packages.get(packageName);
|
|
754
|
+
if (declaredPackage) {
|
|
755
|
+
return {
|
|
756
|
+
kind: 'declared-package',
|
|
757
|
+
declaredIn: manifest?.path,
|
|
758
|
+
declaredVersion: declaredPackage.version,
|
|
759
|
+
declaredSource: declaredPackage.source,
|
|
760
|
+
declaredScope: declaredPackage.scope,
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
const packageManifest = findNearestPackageManifest(importerPath, packageName, readFile, packageCache);
|
|
764
|
+
if (packageManifest) {
|
|
765
|
+
return {
|
|
766
|
+
kind: 'declared-package',
|
|
767
|
+
declaredIn: packageManifest.path,
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
return { kind: 'undeclared-package' };
|
|
771
|
+
}
|
|
772
|
+
function loadFrontendNativeUnitManifestState(hostFilePath, readFile, cache) {
|
|
773
|
+
const manifestPath = buildNativeUnitManifestPath(hostFilePath);
|
|
774
|
+
const cached = cache.get(manifestPath);
|
|
775
|
+
if (cached) {
|
|
776
|
+
return cached;
|
|
777
|
+
}
|
|
778
|
+
const warnings = [];
|
|
779
|
+
const raw = readFile(manifestPath);
|
|
780
|
+
if (raw === undefined) {
|
|
781
|
+
const state = { path: manifestPath, exists: false, warnings };
|
|
782
|
+
cache.set(manifestPath, state);
|
|
783
|
+
return state;
|
|
784
|
+
}
|
|
785
|
+
const parsed = parseNativeUnitManifestJson(raw, manifestPath, { label: 'native manifest' });
|
|
786
|
+
warnings.push(...parsed.warnings);
|
|
787
|
+
const state = {
|
|
788
|
+
path: manifestPath,
|
|
789
|
+
exists: true,
|
|
790
|
+
manifest: parsed.manifest,
|
|
791
|
+
warnings,
|
|
792
|
+
};
|
|
793
|
+
cache.set(manifestPath, state);
|
|
794
|
+
return state;
|
|
795
|
+
}
|
|
796
|
+
function findNearestPackageManifest(importerPath, packageName, readFile, packageCache) {
|
|
797
|
+
let currentDir = dirnameProjectPath(importerPath);
|
|
798
|
+
while (true) {
|
|
799
|
+
const packagePath = currentDir === '.' ? 'package.json' : `${currentDir}/package.json`;
|
|
800
|
+
const summary = loadPackageManifestSummary(packagePath, readFile, packageCache);
|
|
801
|
+
if (summary?.dependencies.has(packageName)) {
|
|
802
|
+
return summary;
|
|
803
|
+
}
|
|
804
|
+
if (currentDir === '.') {
|
|
805
|
+
return null;
|
|
806
|
+
}
|
|
807
|
+
currentDir = dirnameProjectPath(currentDir);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function loadPackageManifestSummary(packagePath, readFile, packageCache) {
|
|
811
|
+
if (packageCache.has(packagePath)) {
|
|
812
|
+
return packageCache.get(packagePath) ?? null;
|
|
813
|
+
}
|
|
814
|
+
try {
|
|
815
|
+
const raw = readFile(packagePath);
|
|
816
|
+
if (raw === undefined) {
|
|
817
|
+
packageCache.set(packagePath, null);
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
const parsed = JSON.parse(raw);
|
|
821
|
+
const dependencies = new Set([
|
|
822
|
+
...Object.keys(parsed.dependencies ?? {}),
|
|
823
|
+
...Object.keys(parsed.devDependencies ?? {}),
|
|
824
|
+
...Object.keys(parsed.peerDependencies ?? {}),
|
|
825
|
+
...Object.keys(parsed.optionalDependencies ?? {}),
|
|
826
|
+
]);
|
|
827
|
+
const summary = {
|
|
828
|
+
path: packagePath,
|
|
829
|
+
dependencies,
|
|
830
|
+
};
|
|
831
|
+
packageCache.set(packagePath, summary);
|
|
832
|
+
return summary;
|
|
833
|
+
}
|
|
834
|
+
catch {
|
|
835
|
+
packageCache.set(packagePath, null);
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
441
839
|
//# sourceMappingURL=host-files.js.map
|