@open-mercato/cli 0.6.8-develop.6891.1.4dca3f1ad3 → 0.6.8-develop.6893.1.7af3b3a72d
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/.turbo/turbo-build.log +3 -3
- package/AGENTS.md +6 -1
- package/dist/agentic/guides/module-facts.json +113 -113
- package/dist/agentic/guides/modules/ai_assistant.md +1 -1
- package/dist/agentic/guides/modules/api_docs.md +1 -1
- package/dist/agentic/guides/modules/api_keys.md +1 -1
- package/dist/agentic/guides/modules/attachments.md +1 -1
- package/dist/agentic/guides/modules/audit_logs.md +1 -1
- package/dist/agentic/guides/modules/auth.md +1 -1
- package/dist/agentic/guides/modules/business_rules.md +1 -1
- package/dist/agentic/guides/modules/catalog.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail.md +1 -1
- package/dist/agentic/guides/modules/channel_imap.md +1 -1
- package/dist/agentic/guides/modules/checkout.md +1 -1
- package/dist/agentic/guides/modules/communication_channels.md +3 -3
- package/dist/agentic/guides/modules/configs.md +1 -1
- package/dist/agentic/guides/modules/content.md +1 -1
- package/dist/agentic/guides/modules/currencies.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts.md +1 -1
- package/dist/agentic/guides/modules/customers.md +1 -1
- package/dist/agentic/guides/modules/dashboards.md +1 -1
- package/dist/agentic/guides/modules/data_sync.md +1 -1
- package/dist/agentic/guides/modules/design_system.md +1 -1
- package/dist/agentic/guides/modules/dictionaries.md +1 -1
- package/dist/agentic/guides/modules/directory.md +1 -1
- package/dist/agentic/guides/modules/entities.md +1 -1
- package/dist/agentic/guides/modules/events.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe.md +1 -1
- package/dist/agentic/guides/modules/generators.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops.md +1 -1
- package/dist/agentic/guides/modules/integrations.md +1 -1
- package/dist/agentic/guides/modules/messages.md +1 -1
- package/dist/agentic/guides/modules/notifications.md +1 -1
- package/dist/agentic/guides/modules/onboarding.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways.md +1 -1
- package/dist/agentic/guides/modules/perspectives.md +1 -1
- package/dist/agentic/guides/modules/planner.md +1 -1
- package/dist/agentic/guides/modules/portal.md +1 -1
- package/dist/agentic/guides/modules/progress.md +1 -1
- package/dist/agentic/guides/modules/query_index.md +1 -1
- package/dist/agentic/guides/modules/record_locks.md +1 -1
- package/dist/agentic/guides/modules/resources.md +1 -1
- package/dist/agentic/guides/modules/sales.md +1 -1
- package/dist/agentic/guides/modules/scheduler.md +1 -1
- package/dist/agentic/guides/modules/search.md +1 -1
- package/dist/agentic/guides/modules/security.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers.md +1 -1
- package/dist/agentic/guides/modules/sso.md +1 -1
- package/dist/agentic/guides/modules/staff.md +1 -1
- package/dist/agentic/guides/modules/storage_s3.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo.md +1 -1
- package/dist/agentic/guides/modules/sync_excel.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays.md +1 -1
- package/dist/agentic/guides/modules/translations.md +1 -1
- package/dist/agentic/guides/modules/webhooks.md +1 -1
- package/dist/agentic/guides/modules/wms.md +1 -1
- package/dist/agentic/guides/modules/workflows.md +1 -1
- package/dist/agentic/guides/upstream/AGENTS.md +2 -1
- package/dist/agentic/guides/upstream/manifest.json +2 -2
- package/dist/bin.js +20 -34
- package/dist/bin.js.map +2 -2
- package/dist/lib/cli-bootstrap-mode.js +32 -0
- package/dist/lib/cli-bootstrap-mode.js.map +7 -0
- package/dist/lib/dev-supervisor-manifest.js +105 -0
- package/dist/lib/dev-supervisor-manifest.js.map +7 -0
- package/dist/lib/generators/entity-ids.js +11 -24
- package/dist/lib/generators/entity-ids.js.map +2 -2
- package/dist/lib/generators/module-di.js +10 -23
- package/dist/lib/generators/module-di.js.map +2 -2
- package/dist/lib/generators/module-entities.js +10 -23
- package/dist/lib/generators/module-entities.js.map +2 -2
- package/dist/lib/generators/module-registry.js +394 -31
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/generators/route-manifest-shards.js +170 -0
- package/dist/lib/generators/route-manifest-shards.js.map +7 -0
- package/dist/lib/queue-worker-supervisor.js.map +2 -2
- package/dist/lib/resolver.js +26 -3
- package/dist/lib/resolver.js.map +2 -2
- package/dist/lib/utils.js +15 -8
- package/dist/lib/utils.js.map +2 -2
- package/dist/mercato.js +9 -6
- package/dist/mercato.js.map +2 -2
- package/package.json +6 -6
- package/src/__tests__/mercato.test.ts +144 -0
- package/src/bin.ts +28 -42
- package/src/lib/__tests__/cli-bootstrap-mode.test.ts +22 -0
- package/src/lib/__tests__/content-stable-writes.test.ts +74 -0
- package/src/lib/__tests__/dev-supervisor-manifest.test.ts +131 -0
- package/src/lib/__tests__/queue-worker-supervisor.test.ts +33 -0
- package/src/lib/__tests__/resolver.enterprise.test.ts +50 -0
- package/src/lib/cli-bootstrap-mode.ts +31 -0
- package/src/lib/dev-supervisor-manifest.ts +142 -0
- package/src/lib/generators/__tests__/entity-ids.test.ts +32 -0
- package/src/lib/generators/__tests__/module-subset.test.ts +248 -0
- package/src/lib/generators/__tests__/output-snapshots.test.ts +3 -3
- package/src/lib/generators/__tests__/route-manifest-shards.test.ts +62 -0
- package/src/lib/generators/entity-ids.ts +10 -26
- package/src/lib/generators/module-di.ts +9 -25
- package/src/lib/generators/module-entities.ts +9 -25
- package/src/lib/generators/module-registry.ts +432 -29
- package/src/lib/generators/route-manifest-shards.ts +146 -0
- package/src/lib/queue-worker-supervisor.ts +7 -2
- package/src/lib/resolver.ts +31 -3
- package/src/lib/utils.ts +24 -16
- package/src/mercato.ts +15 -6
|
@@ -3,6 +3,10 @@ import path from "node:path";
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { VariableDeclarationKind } from "ts-morph";
|
|
5
5
|
import ts from "typescript-js";
|
|
6
|
+
import {
|
|
7
|
+
DEV_SUPERVISOR_MANIFEST_FILE,
|
|
8
|
+
DEV_SUPERVISOR_MANIFEST_VERSION
|
|
9
|
+
} from "../dev-supervisor-manifest.js";
|
|
6
10
|
import {
|
|
7
11
|
calculateStructureChecksum,
|
|
8
12
|
toVar,
|
|
@@ -58,6 +62,11 @@ import {
|
|
|
58
62
|
resolveStandaloneSourceMirrorBase
|
|
59
63
|
} from "./scanner.js";
|
|
60
64
|
import { loadGeneratorExtensions } from "./extensions/index.js";
|
|
65
|
+
import {
|
|
66
|
+
renderRouteManifestShardOutputs,
|
|
67
|
+
renderRouteMetadataOutput,
|
|
68
|
+
routeManifestShardFilePattern
|
|
69
|
+
} from "./route-manifest-shards.js";
|
|
61
70
|
function assertUniqueBackendRoutePattern(seen, moduleId, pattern) {
|
|
62
71
|
if (!pattern.startsWith("/backend/")) return;
|
|
63
72
|
const previous = seen.get(pattern);
|
|
@@ -1157,12 +1166,16 @@ function discoverTranslations(roots) {
|
|
|
1157
1166
|
const locales = /* @__PURE__ */ new Set();
|
|
1158
1167
|
if (fs.existsSync(i18nCore)) {
|
|
1159
1168
|
for (const entry of fs.readdirSync(i18nCore, { withFileTypes: true })) {
|
|
1160
|
-
if (entry.isFile() &&
|
|
1169
|
+
if (entry.isFile() && /^[a-zA-Z0-9][a-zA-Z0-9_-]*\.json$/.test(entry.name)) {
|
|
1170
|
+
locales.add(entry.name.replace(/\.json$/, ""));
|
|
1171
|
+
}
|
|
1161
1172
|
}
|
|
1162
1173
|
}
|
|
1163
1174
|
if (fs.existsSync(i18nApp)) {
|
|
1164
1175
|
for (const entry of fs.readdirSync(i18nApp, { withFileTypes: true })) {
|
|
1165
|
-
if (entry.isFile() &&
|
|
1176
|
+
if (entry.isFile() && /^[a-zA-Z0-9][a-zA-Z0-9_-]*\.json$/.test(entry.name)) {
|
|
1177
|
+
locales.add(entry.name.replace(/\.json$/, ""));
|
|
1178
|
+
}
|
|
1166
1179
|
}
|
|
1167
1180
|
}
|
|
1168
1181
|
return Array.from(locales, (locale) => ({
|
|
@@ -1242,6 +1255,8 @@ async function processPageFiles(options) {
|
|
|
1242
1255
|
const eagerRoutes = [];
|
|
1243
1256
|
const runtimeRoutes = [];
|
|
1244
1257
|
const manifestRoutes = [];
|
|
1258
|
+
const manifestShardRoutes = [];
|
|
1259
|
+
const metadataRoutes = [];
|
|
1245
1260
|
const routePatterns = [];
|
|
1246
1261
|
for (const { relPath, fromApp } of files.filter(({ relPath: f }) => isModulePageFile(path.basename(f)))) {
|
|
1247
1262
|
const segs = relPath.split("/");
|
|
@@ -1309,7 +1324,19 @@ async function processPageFiles(options) {
|
|
|
1309
1324
|
const manifestBaseProps = buildPageRouteManifestSpread(manifestMetaExpr, routePath);
|
|
1310
1325
|
eagerRoutes.push(`{ ${baseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1311
1326
|
runtimeRoutes.push(`{ ${runtimeBaseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1312
|
-
|
|
1327
|
+
const metadataDeclaration = `{ moduleId: ${toLiteral(modId)}, ${manifestBaseProps} }`;
|
|
1328
|
+
const manifestDeclaration = `{ moduleId: ${toLiteral(modId)}, ${manifestBaseProps}, load: async () => { const mod = await ${buildDynamicImportExpression(importPath)}; return (mod.default ?? mod) as any } }`;
|
|
1329
|
+
manifestRoutes.push(manifestDeclaration);
|
|
1330
|
+
manifestShardRoutes.push({
|
|
1331
|
+
path: routePath,
|
|
1332
|
+
declaration: manifestDeclaration,
|
|
1333
|
+
imports: manifestImportStatement ? [manifestImportStatement] : []
|
|
1334
|
+
});
|
|
1335
|
+
metadataRoutes.push({
|
|
1336
|
+
path: routePath,
|
|
1337
|
+
declaration: metadataDeclaration,
|
|
1338
|
+
imports: manifestImportStatement ? [manifestImportStatement] : []
|
|
1339
|
+
});
|
|
1313
1340
|
routePatterns.push(routePath);
|
|
1314
1341
|
}
|
|
1315
1342
|
for (const { relPath, fromApp } of files.filter(({ relPath: f }) => !isModulePageFile(path.basename(f)))) {
|
|
@@ -1382,13 +1409,27 @@ async function processPageFiles(options) {
|
|
|
1382
1409
|
const manifestBaseProps = buildPageRouteManifestSpread(manifestMetaExpr, routePath);
|
|
1383
1410
|
eagerRoutes.push(`{ ${baseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1384
1411
|
runtimeRoutes.push(`{ ${runtimeBaseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1385
|
-
|
|
1412
|
+
const metadataDeclaration = `{ moduleId: ${toLiteral(modId)}, ${manifestBaseProps} }`;
|
|
1413
|
+
const manifestDeclaration = `{ moduleId: ${toLiteral(modId)}, ${manifestBaseProps}, load: async () => { const mod = await ${buildDynamicImportExpression(importPath)}; return (mod.default ?? mod) as any } }`;
|
|
1414
|
+
manifestRoutes.push(manifestDeclaration);
|
|
1415
|
+
manifestShardRoutes.push({
|
|
1416
|
+
path: routePath,
|
|
1417
|
+
declaration: manifestDeclaration,
|
|
1418
|
+
imports: manifestImportStatement ? [manifestImportStatement] : []
|
|
1419
|
+
});
|
|
1420
|
+
metadataRoutes.push({
|
|
1421
|
+
path: routePath,
|
|
1422
|
+
declaration: metadataDeclaration,
|
|
1423
|
+
imports: manifestImportStatement ? [manifestImportStatement] : []
|
|
1424
|
+
});
|
|
1386
1425
|
routePatterns.push(routePath);
|
|
1387
1426
|
}
|
|
1388
1427
|
return {
|
|
1389
1428
|
eagerRoutes,
|
|
1390
1429
|
runtimeRoutes,
|
|
1391
1430
|
manifestRoutes,
|
|
1431
|
+
manifestShardRoutes,
|
|
1432
|
+
metadataRoutes,
|
|
1392
1433
|
routePatterns
|
|
1393
1434
|
};
|
|
1394
1435
|
}
|
|
@@ -1397,11 +1438,13 @@ async function processApiRoutes(options) {
|
|
|
1397
1438
|
const apiApp = path.join(roots.appBase, "api");
|
|
1398
1439
|
const apiPkg = path.join(roots.pkgBase, "api");
|
|
1399
1440
|
if (!fs.existsSync(apiApp) && !fs.existsSync(apiPkg)) {
|
|
1400
|
-
return { eagerApis: [], runtimeApis: [], manifestApis: [] };
|
|
1441
|
+
return { eagerApis: [], runtimeApis: [], manifestApis: [], manifestShardApis: [], metadataApis: [] };
|
|
1401
1442
|
}
|
|
1402
1443
|
const eagerApis = [];
|
|
1403
1444
|
const runtimeApis = [];
|
|
1404
1445
|
const manifestApis = [];
|
|
1446
|
+
const manifestShardApis = [];
|
|
1447
|
+
const metadataApis = [];
|
|
1405
1448
|
const routeFiles = scanModuleDir(roots, SCAN_CONFIGS.apiRoutes);
|
|
1406
1449
|
for (const { relPath, fromApp } of routeFiles) {
|
|
1407
1450
|
const segs = relPath.split("/");
|
|
@@ -1430,7 +1473,11 @@ async function processApiRoutes(options) {
|
|
|
1430
1473
|
eagerImports.push(buildImportStatement(`* as ${importName}`, importPath));
|
|
1431
1474
|
eagerApis.push(`{ path: ((${importName} as any).metadata?.path ?? ${toLiteral(routePath)}), metadata: (${importName} as any).metadata, handlers: ${importName} as any${docsPart} }`);
|
|
1432
1475
|
runtimeApis.push(`{ path: ${toLiteral(resolvedPath)}, metadata: ${metadataLiteral}, handlers: { ${exportedMethods.map((method) => `${method}: async (req: Request, ctx?: any) => { const mod = await ${buildDynamicImportExpression(importPath)}; return (mod as any).${method}(req, ctx) }`).join(", ")} } }`);
|
|
1433
|
-
|
|
1476
|
+
const metadataDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("route-file")}, path: ${toLiteral(resolvedPath)}, methods: [${exportedMethods.map((method) => toLiteral(method)).join(", ")}] }`;
|
|
1477
|
+
const manifestDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("route-file")}, path: ${toLiteral(resolvedPath)}, methods: [${exportedMethods.map((method) => toLiteral(method)).join(", ")}], load: async () => ${buildDynamicImportExpression(importPath)} }`;
|
|
1478
|
+
manifestApis.push(manifestDeclaration);
|
|
1479
|
+
manifestShardApis.push({ path: resolvedPath, declaration: manifestDeclaration });
|
|
1480
|
+
metadataApis.push({ path: resolvedPath, declaration: metadataDeclaration });
|
|
1434
1481
|
}
|
|
1435
1482
|
const plainFiles = scanModuleDir(roots, SCAN_CONFIGS.apiPlainFiles);
|
|
1436
1483
|
for (const { relPath, fromApp } of plainFiles) {
|
|
@@ -1460,7 +1507,11 @@ async function processApiRoutes(options) {
|
|
|
1460
1507
|
eagerImports.push(buildImportStatement(`* as ${importName}`, importPath));
|
|
1461
1508
|
eagerApis.push(`{ path: ((${importName} as any).metadata?.path ?? ${toLiteral(routePath)}), metadata: (${importName} as any).metadata, handlers: ${importName} as any${docsPart} }`);
|
|
1462
1509
|
runtimeApis.push(`{ path: ${toLiteral(resolvedPath)}, metadata: ${metadataLiteral}, handlers: { ${exportedMethods.map((entryMethod) => `${entryMethod}: async (req: Request, ctx?: any) => { const mod = await ${buildDynamicImportExpression(importPath)}; return (mod as any).${entryMethod}(req, ctx) }`).join(", ")} } }`);
|
|
1463
|
-
|
|
1510
|
+
const metadataDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("route-file")}, path: ${toLiteral(resolvedPath)}, methods: [${exportedMethods.map((entryMethod) => toLiteral(entryMethod)).join(", ")}] }`;
|
|
1511
|
+
const manifestDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("route-file")}, path: ${toLiteral(resolvedPath)}, methods: [${exportedMethods.map((entryMethod) => toLiteral(entryMethod)).join(", ")}], load: async () => ${buildDynamicImportExpression(importPath)} }`;
|
|
1512
|
+
manifestApis.push(manifestDeclaration);
|
|
1513
|
+
manifestShardApis.push({ path: resolvedPath, declaration: manifestDeclaration });
|
|
1514
|
+
metadataApis.push({ path: resolvedPath, declaration: metadataDeclaration });
|
|
1464
1515
|
}
|
|
1465
1516
|
const methods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
1466
1517
|
for (const method of methods) {
|
|
@@ -1499,13 +1550,19 @@ async function processApiRoutes(options) {
|
|
|
1499
1550
|
eagerImports.push(buildImportStatement(`${importName}, * as ${metaName}`, importPath));
|
|
1500
1551
|
eagerApis.push(`{ method: ${toLiteral(method)}, path: (${metaName}.metadata?.path ?? ${toLiteral(routePath)}), handler: ${importName}, metadata: ${metaName}.metadata${docsPart} }`);
|
|
1501
1552
|
runtimeApis.push(`{ method: ${toLiteral(method)}, path: ${toLiteral(resolvedPath)}, handler: async (req: Request, ctx?: any) => { const mod = await ${buildDynamicImportExpression(importPath)}; const handler = ((mod as any).default ?? (mod as any).${method} ?? (mod as any).handler) as any; return handler(req, ctx) }, metadata: ${metadataLiteral} }`);
|
|
1502
|
-
|
|
1553
|
+
const metadataDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("legacy")}, method: ${toLiteral(method)}, path: ${toLiteral(resolvedPath)}, methods: [${toLiteral(method)}] }`;
|
|
1554
|
+
const manifestDeclaration = `{ moduleId: ${toLiteral(modId)}, kind: ${toLiteral("legacy")}, method: ${toLiteral(method)}, path: ${toLiteral(resolvedPath)}, methods: [${toLiteral(method)}], load: async () => ${buildDynamicImportExpression(importPath)} }`;
|
|
1555
|
+
manifestApis.push(manifestDeclaration);
|
|
1556
|
+
manifestShardApis.push({ path: resolvedPath, declaration: manifestDeclaration });
|
|
1557
|
+
metadataApis.push({ path: resolvedPath, declaration: metadataDeclaration });
|
|
1503
1558
|
}
|
|
1504
1559
|
}
|
|
1505
1560
|
return {
|
|
1506
1561
|
eagerApis,
|
|
1507
1562
|
runtimeApis,
|
|
1508
|
-
manifestApis
|
|
1563
|
+
manifestApis,
|
|
1564
|
+
manifestShardApis,
|
|
1565
|
+
metadataApis
|
|
1509
1566
|
};
|
|
1510
1567
|
}
|
|
1511
1568
|
function processSubscribers(discovered) {
|
|
@@ -2101,48 +2158,229 @@ function processWorkersAst(discovered) {
|
|
|
2101
2158
|
}
|
|
2102
2159
|
return workers;
|
|
2103
2160
|
}
|
|
2161
|
+
function collectWorkerGenerationEntries(discovered, moduleId) {
|
|
2162
|
+
const workers = [];
|
|
2163
|
+
for (const { id, importPath, metadata } of discovered) {
|
|
2164
|
+
if (!metadata.queue) continue;
|
|
2165
|
+
workers.push({
|
|
2166
|
+
id: metadata.id ?? id,
|
|
2167
|
+
moduleId,
|
|
2168
|
+
queue: metadata.queue,
|
|
2169
|
+
concurrency: metadata.concurrency ?? 1,
|
|
2170
|
+
importPath
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
return workers;
|
|
2174
|
+
}
|
|
2104
2175
|
function processTranslationsAst(options) {
|
|
2105
|
-
const { discovered, modId, appImportBase, pkgImportBase, imports, extraImports } = options;
|
|
2176
|
+
const { discovered, modId, appImportBase, pkgImportBase, imports, extraImports, localeOutputs } = options;
|
|
2106
2177
|
const translations = [];
|
|
2107
2178
|
for (const { locale, coreHas, appHas } of discovered) {
|
|
2108
2179
|
if (coreHas && appHas) {
|
|
2109
2180
|
const coreName = `T_${toVar(modId)}_${toVar(locale)}_C`;
|
|
2110
2181
|
const appName = `T_${toVar(modId)}_${toVar(locale)}_A`;
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2182
|
+
const localeImports = [
|
|
2183
|
+
buildImportStatement(coreName, `${pkgImportBase}/i18n/${locale}.json`),
|
|
2184
|
+
buildImportStatement(appName, `${appImportBase}/i18n/${locale}.json`)
|
|
2185
|
+
];
|
|
2186
|
+
imports.push(...localeImports);
|
|
2187
|
+
extraImports?.push(...localeImports);
|
|
2188
|
+
const value = objectLiteral([
|
|
2189
|
+
{ kind: "spread", value: asExpression(identifier(coreName), "unknown as Record<string, string>") },
|
|
2190
|
+
{ kind: "spread", value: asExpression(identifier(appName), "unknown as Record<string, string>") }
|
|
2191
|
+
]);
|
|
2115
2192
|
translations.push({
|
|
2116
2193
|
name: JSON.stringify(locale),
|
|
2117
|
-
value
|
|
2118
|
-
{ kind: "spread", value: asExpression(identifier(coreName), "unknown as Record<string, string>") },
|
|
2119
|
-
{ kind: "spread", value: asExpression(identifier(appName), "unknown as Record<string, string>") }
|
|
2120
|
-
])
|
|
2194
|
+
value
|
|
2121
2195
|
});
|
|
2196
|
+
localeOutputs?.set(locale, { imports: localeImports, value });
|
|
2122
2197
|
continue;
|
|
2123
2198
|
}
|
|
2124
2199
|
if (appHas) {
|
|
2125
2200
|
const appName = `T_${toVar(modId)}_${toVar(locale)}_A`;
|
|
2126
|
-
|
|
2127
|
-
|
|
2201
|
+
const localeImports = [buildImportStatement(appName, `${appImportBase}/i18n/${locale}.json`)];
|
|
2202
|
+
imports.push(...localeImports);
|
|
2203
|
+
extraImports?.push(...localeImports);
|
|
2204
|
+
const value = asExpression(identifier(appName), "unknown as Record<string, string>");
|
|
2128
2205
|
translations.push({
|
|
2129
2206
|
name: JSON.stringify(locale),
|
|
2130
|
-
value
|
|
2207
|
+
value
|
|
2131
2208
|
});
|
|
2209
|
+
localeOutputs?.set(locale, { imports: localeImports, value });
|
|
2132
2210
|
continue;
|
|
2133
2211
|
}
|
|
2134
2212
|
if (coreHas) {
|
|
2135
2213
|
const coreName = `T_${toVar(modId)}_${toVar(locale)}_C`;
|
|
2136
|
-
|
|
2137
|
-
|
|
2214
|
+
const localeImports = [buildImportStatement(coreName, `${pkgImportBase}/i18n/${locale}.json`)];
|
|
2215
|
+
imports.push(...localeImports);
|
|
2216
|
+
extraImports?.push(...localeImports);
|
|
2217
|
+
const value = asExpression(identifier(coreName), "unknown as Record<string, string>");
|
|
2138
2218
|
translations.push({
|
|
2139
2219
|
name: JSON.stringify(locale),
|
|
2140
|
-
value
|
|
2220
|
+
value
|
|
2141
2221
|
});
|
|
2222
|
+
localeOutputs?.set(locale, { imports: localeImports, value });
|
|
2142
2223
|
}
|
|
2143
2224
|
}
|
|
2144
2225
|
return translations;
|
|
2145
2226
|
}
|
|
2227
|
+
function sourceDeclaresCliCommand(filePath, commandName) {
|
|
2228
|
+
let sourceText;
|
|
2229
|
+
try {
|
|
2230
|
+
sourceText = fs.readFileSync(filePath, "utf8");
|
|
2231
|
+
} catch {
|
|
2232
|
+
return false;
|
|
2233
|
+
}
|
|
2234
|
+
const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true);
|
|
2235
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
2236
|
+
for (const statement of sourceFile.statements) {
|
|
2237
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
2238
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
2239
|
+
if (ts.isIdentifier(declaration.name) && declaration.initializer) {
|
|
2240
|
+
declarations.set(declaration.name.text, declaration.initializer);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
const expressionDeclaresCommand = (expression, seen = /* @__PURE__ */ new Set()) => {
|
|
2245
|
+
if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression) || ts.isSatisfiesExpression(expression)) {
|
|
2246
|
+
return expressionDeclaresCommand(expression.expression, seen);
|
|
2247
|
+
}
|
|
2248
|
+
if (ts.isIdentifier(expression)) {
|
|
2249
|
+
if (seen.has(expression.text)) return false;
|
|
2250
|
+
const initializer = declarations.get(expression.text);
|
|
2251
|
+
if (!initializer) return false;
|
|
2252
|
+
const nextSeen = new Set(seen);
|
|
2253
|
+
nextSeen.add(expression.text);
|
|
2254
|
+
return expressionDeclaresCommand(initializer, nextSeen);
|
|
2255
|
+
}
|
|
2256
|
+
if (ts.isArrayLiteralExpression(expression)) {
|
|
2257
|
+
return expression.elements.some((element) => ts.isSpreadElement(element) ? expressionDeclaresCommand(element.expression, seen) : expressionDeclaresCommand(element, seen));
|
|
2258
|
+
}
|
|
2259
|
+
if (!ts.isObjectLiteralExpression(expression)) return false;
|
|
2260
|
+
return expression.properties.some((property) => {
|
|
2261
|
+
if (!ts.isPropertyAssignment(property)) return false;
|
|
2262
|
+
const propertyName = ts.isIdentifier(property.name) || ts.isStringLiteralLike(property.name) ? property.name.text : null;
|
|
2263
|
+
return propertyName === "command" && (ts.isStringLiteralLike(property.initializer) || ts.isNoSubstitutionTemplateLiteral(property.initializer)) && property.initializer.text === commandName;
|
|
2264
|
+
});
|
|
2265
|
+
};
|
|
2266
|
+
return sourceFile.statements.some((statement) => ts.isExportAssignment(statement) && !statement.isExportEquals && expressionDeclaresCommand(statement.expression));
|
|
2267
|
+
}
|
|
2268
|
+
function appDeclaresProgrammaticDevSupervisorOverrides(appDir) {
|
|
2269
|
+
const srcDir = path.join(appDir, "src");
|
|
2270
|
+
const pending = [srcDir];
|
|
2271
|
+
while (pending.length > 0) {
|
|
2272
|
+
const current = pending.pop();
|
|
2273
|
+
let entries;
|
|
2274
|
+
try {
|
|
2275
|
+
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
2276
|
+
} catch {
|
|
2277
|
+
continue;
|
|
2278
|
+
}
|
|
2279
|
+
for (const entry of entries) {
|
|
2280
|
+
const entryPath = path.join(current, entry.name);
|
|
2281
|
+
if (entry.isDirectory()) {
|
|
2282
|
+
if (entry.name !== "__tests__" && entry.name !== "node_modules") pending.push(entryPath);
|
|
2283
|
+
continue;
|
|
2284
|
+
}
|
|
2285
|
+
if (!/\.[cm]?tsx?$/.test(entry.name) || /(?:^|\.)test\.[cm]?tsx?$/.test(entry.name)) continue;
|
|
2286
|
+
let sourceText;
|
|
2287
|
+
try {
|
|
2288
|
+
sourceText = fs.readFileSync(entryPath, "utf8");
|
|
2289
|
+
} catch {
|
|
2290
|
+
continue;
|
|
2291
|
+
}
|
|
2292
|
+
const sourceFile = ts.createSourceFile(entryPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
2293
|
+
const directImports = /* @__PURE__ */ new Set();
|
|
2294
|
+
const namespaceImports = /* @__PURE__ */ new Set();
|
|
2295
|
+
for (const statement of sourceFile.statements) {
|
|
2296
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteralLike(statement.moduleSpecifier) || statement.moduleSpecifier.text !== "@open-mercato/shared/modules/overrides") continue;
|
|
2297
|
+
const bindings = statement.importClause?.namedBindings;
|
|
2298
|
+
if (bindings && ts.isNamespaceImport(bindings)) namespaceImports.add(bindings.name.text);
|
|
2299
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
2300
|
+
for (const element of bindings.elements) {
|
|
2301
|
+
const importedName = element.propertyName?.text ?? element.name.text;
|
|
2302
|
+
if (importedName === "applyWorkerOverrides" || importedName === "applyCliOverrides") {
|
|
2303
|
+
directImports.add(element.name.text);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
let found = false;
|
|
2309
|
+
const visit = (node) => {
|
|
2310
|
+
if (found) return;
|
|
2311
|
+
if (ts.isCallExpression(node)) {
|
|
2312
|
+
if (ts.isIdentifier(node.expression) && directImports.has(node.expression.text)) {
|
|
2313
|
+
found = true;
|
|
2314
|
+
return;
|
|
2315
|
+
}
|
|
2316
|
+
if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression) && namespaceImports.has(node.expression.expression.text) && ["applyWorkerOverrides", "applyCliOverrides"].includes(node.expression.name.text)) {
|
|
2317
|
+
found = true;
|
|
2318
|
+
return;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
ts.forEachChild(node, visit);
|
|
2322
|
+
};
|
|
2323
|
+
visit(sourceFile);
|
|
2324
|
+
if (found) return true;
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
return false;
|
|
2328
|
+
}
|
|
2329
|
+
function renderAstI18nLocaleRegistryFile(options) {
|
|
2330
|
+
const sourceFile = createGeneratedSourceFile(options.fileName);
|
|
2331
|
+
addAutoGeneratedComment(sourceFile, "registry (locale-specific i18n version)");
|
|
2332
|
+
addImportSpec(sourceFile, {
|
|
2333
|
+
moduleSpecifier: "@open-mercato/shared/modules/registry",
|
|
2334
|
+
namedImports: [{ name: "Module", isTypeOnly: true }]
|
|
2335
|
+
});
|
|
2336
|
+
addImportStatements(sourceFile, options.imports);
|
|
2337
|
+
sourceFile.addVariableStatement({
|
|
2338
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
2339
|
+
isExported: true,
|
|
2340
|
+
declarations: [{
|
|
2341
|
+
name: "modules",
|
|
2342
|
+
type: "Module[]",
|
|
2343
|
+
initializer: arrayLiteral(options.moduleEntries, writeValue)
|
|
2344
|
+
}]
|
|
2345
|
+
});
|
|
2346
|
+
sourceFile.addExportAssignment({
|
|
2347
|
+
isExportEquals: false,
|
|
2348
|
+
expression: "modules"
|
|
2349
|
+
});
|
|
2350
|
+
return getSourceText(sourceFile);
|
|
2351
|
+
}
|
|
2352
|
+
function buildI18nLocaleShardFileName(locale) {
|
|
2353
|
+
const safeLocale = locale.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2354
|
+
return `modules.i18n.${safeLocale}.generated.ts`;
|
|
2355
|
+
}
|
|
2356
|
+
function renderI18nLocaleLoadersFile(locales) {
|
|
2357
|
+
const cases = locales.map((locale) => {
|
|
2358
|
+
const moduleSpecifier = `./${buildI18nLocaleShardFileName(locale).replace(/\.ts$/, "")}`;
|
|
2359
|
+
return ` case ${JSON.stringify(locale)}:
|
|
2360
|
+
return import(${JSON.stringify(moduleSpecifier)}).then((entry) => entry.modules)`;
|
|
2361
|
+
}).join("\n");
|
|
2362
|
+
return `// AUTO-GENERATED by mercato generate registry (locale-specific i18n loaders)
|
|
2363
|
+
import type { Module } from '@open-mercato/shared/modules/registry'
|
|
2364
|
+
|
|
2365
|
+
export async function loadI18nModules(locale: string): Promise<Module[]> {
|
|
2366
|
+
switch (locale) {
|
|
2367
|
+
${cases ? `${cases}
|
|
2368
|
+
` : ""} default:
|
|
2369
|
+
return []
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
`;
|
|
2373
|
+
}
|
|
2374
|
+
function removeStaleI18nLocaleShards(outputDir, expectedFileNames) {
|
|
2375
|
+
if (!fs.existsSync(outputDir)) return;
|
|
2376
|
+
for (const entry of fs.readdirSync(outputDir, { withFileTypes: true })) {
|
|
2377
|
+
if (!entry.isFile()) continue;
|
|
2378
|
+
if (!/^modules\.i18n\..+\.generated\.(?:ts|checksum)$/.test(entry.name)) continue;
|
|
2379
|
+
if (entry.name.startsWith("modules.i18n.loaders.generated.")) continue;
|
|
2380
|
+
if (expectedFileNames.has(entry.name)) continue;
|
|
2381
|
+
fs.unlinkSync(path.join(outputDir, entry.name));
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2146
2384
|
function resolveConventionFile(resolved, prefix, modId, importIdRef, imports, extraImports, importStyle = "namespace") {
|
|
2147
2385
|
if (!resolved) return null;
|
|
2148
2386
|
const importName = `${prefix}_${toVar(modId)}_${importIdRef.value++}`;
|
|
@@ -2205,6 +2443,10 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2205
2443
|
const frontendRouteManifestDecls = [];
|
|
2206
2444
|
const backendRouteManifestDecls = [];
|
|
2207
2445
|
const apiRouteManifestDecls = [];
|
|
2446
|
+
const backendRouteShardEntries = [];
|
|
2447
|
+
const backendRouteMetadataEntries = [];
|
|
2448
|
+
const apiRouteShardEntries = [];
|
|
2449
|
+
const apiRouteMetadataEntries = [];
|
|
2208
2450
|
const importIdRef = { value: 0 };
|
|
2209
2451
|
const requiresByModule = /* @__PURE__ */ new Map();
|
|
2210
2452
|
const commandLoaderEntries = [];
|
|
@@ -2370,6 +2612,8 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2370
2612
|
backendRoutes.push(...generatedBackendRoutes.eagerRoutes);
|
|
2371
2613
|
runtimeBackendRoutes.push(...generatedBackendRoutes.runtimeRoutes);
|
|
2372
2614
|
backendRouteManifestDecls.push(...generatedBackendRoutes.manifestRoutes);
|
|
2615
|
+
backendRouteShardEntries.push(...generatedBackendRoutes.manifestShardRoutes);
|
|
2616
|
+
backendRouteMetadataEntries.push(...generatedBackendRoutes.metadataRoutes);
|
|
2373
2617
|
for (const pattern of generatedBackendRoutes.routePatterns) {
|
|
2374
2618
|
assertUniqueBackendRoutePattern(seenBackendRoutePatterns, modId, pattern);
|
|
2375
2619
|
}
|
|
@@ -2388,6 +2632,8 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2388
2632
|
apis.push(...generatedApis.eagerApis);
|
|
2389
2633
|
runtimeApis.push(...generatedApis.runtimeApis);
|
|
2390
2634
|
apiRouteManifestDecls.push(...generatedApis.manifestApis);
|
|
2635
|
+
apiRouteShardEntries.push(...generatedApis.manifestShardApis);
|
|
2636
|
+
apiRouteMetadataEntries.push(...generatedApis.metadataApis);
|
|
2391
2637
|
}
|
|
2392
2638
|
{
|
|
2393
2639
|
const cliResolved = discovered.resolve("cli.ts");
|
|
@@ -2586,6 +2832,12 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2586
2832
|
exportName: "apiRoutes",
|
|
2587
2833
|
entries: apiRouteManifestDecls
|
|
2588
2834
|
});
|
|
2835
|
+
const routeManifestOutputs = [
|
|
2836
|
+
...renderRouteManifestShardOutputs("backend", backendRouteShardEntries),
|
|
2837
|
+
...renderRouteManifestShardOutputs("api", apiRouteShardEntries),
|
|
2838
|
+
renderRouteMetadataOutput("backend", backendRouteMetadataEntries),
|
|
2839
|
+
renderRouteMetadataOutput("api", apiRouteMetadataEntries)
|
|
2840
|
+
];
|
|
2589
2841
|
const legacySubscribersOutput = renderAstLegacyAliasFile({
|
|
2590
2842
|
fileName: "subscribers.generated.ts",
|
|
2591
2843
|
exportName: "moduleSubscribers",
|
|
@@ -2628,6 +2880,29 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2628
2880
|
writeGeneratedFile({ outFile: frontendRoutesOutFile, checksumFile: frontendRoutesChecksumFile, content: frontendRoutesOutput, structureChecksum, result, quiet });
|
|
2629
2881
|
writeGeneratedFile({ outFile: backendRoutesOutFile, checksumFile: backendRoutesChecksumFile, content: backendRoutesOutput, structureChecksum, result, quiet });
|
|
2630
2882
|
writeGeneratedFile({ outFile: apiRoutesOutFile, checksumFile: apiRoutesChecksumFile, content: apiRoutesOutput, structureChecksum, result, quiet });
|
|
2883
|
+
const expectedRouteManifestFiles = new Set(routeManifestOutputs.flatMap(({ fileName }) => [
|
|
2884
|
+
fileName,
|
|
2885
|
+
fileName.replace(/\.ts$/, ".checksum")
|
|
2886
|
+
]));
|
|
2887
|
+
if (fs.existsSync(outputDir)) {
|
|
2888
|
+
for (const entry of fs.readdirSync(outputDir, { withFileTypes: true })) {
|
|
2889
|
+
if (!entry.isFile() || !routeManifestShardFilePattern.test(entry.name)) continue;
|
|
2890
|
+
if (expectedRouteManifestFiles.has(entry.name)) continue;
|
|
2891
|
+
const stalePath = path.join(outputDir, entry.name);
|
|
2892
|
+
fs.unlinkSync(stalePath);
|
|
2893
|
+
result.filesWritten.push(stalePath);
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
for (const routeOutput of routeManifestOutputs) {
|
|
2897
|
+
writeGeneratedFile({
|
|
2898
|
+
outFile: path.join(outputDir, routeOutput.fileName),
|
|
2899
|
+
checksumFile: path.join(outputDir, routeOutput.fileName.replace(/\.ts$/, ".checksum")),
|
|
2900
|
+
content: routeOutput.content,
|
|
2901
|
+
structureChecksum,
|
|
2902
|
+
result,
|
|
2903
|
+
quiet
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2631
2906
|
writeGeneratedFile({ outFile: legacySubscribersOutFile, checksumFile: legacySubscribersChecksumFile, content: legacySubscribersOutput, structureChecksum, result, quiet });
|
|
2632
2907
|
const commandLoadersOutput = renderCommandLoadersFile(commandLoaderEntries);
|
|
2633
2908
|
writeGeneratedFile({ outFile: commandLoadersOutFile, checksumFile: commandLoadersChecksumFile, content: commandLoadersOutput, structureChecksum, result, quiet });
|
|
@@ -2656,14 +2931,14 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2656
2931
|
{
|
|
2657
2932
|
const bootstrapPlugins = [...pluginRegistry.values()].filter((p) => p.bootstrapRegistration);
|
|
2658
2933
|
const allEntryImports = [
|
|
2659
|
-
buildImportStatement(`{
|
|
2934
|
+
buildImportStatement(`{ backendRouteFacades }`, `./backend-route-shards.generated`),
|
|
2660
2935
|
buildImportStatement(`{ frontendRoutes }`, `./frontend-routes.generated`)
|
|
2661
2936
|
];
|
|
2662
2937
|
const allRegImports = [
|
|
2663
2938
|
`import { registerBackendRouteManifests, registerFrontendRouteManifests } from '@open-mercato/shared/modules/registry'`
|
|
2664
2939
|
];
|
|
2665
2940
|
const allCalls = [
|
|
2666
|
-
`registerBackendRouteManifests(
|
|
2941
|
+
`registerBackendRouteManifests(backendRouteFacades)`,
|
|
2667
2942
|
`registerFrontendRouteManifests(frontendRoutes)`
|
|
2668
2943
|
];
|
|
2669
2944
|
for (const plugin of bootstrapPlugins) {
|
|
@@ -2698,6 +2973,8 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
2698
2973
|
const bootstrapChecksumFile = path.join(outputDir, "modules.bootstrap.generated.checksum");
|
|
2699
2974
|
const i18nOutFile = path.join(outputDir, "modules.i18n.generated.ts");
|
|
2700
2975
|
const i18nChecksumFile = path.join(outputDir, "modules.i18n.generated.checksum");
|
|
2976
|
+
const i18nLoadersOutFile = path.join(outputDir, "modules.i18n.loaders.generated.ts");
|
|
2977
|
+
const i18nLoadersChecksumFile = path.join(outputDir, "modules.i18n.loaders.generated.checksum");
|
|
2701
2978
|
const legacyOutFile = path.join(outputDir, "bootstrap-modules.generated.ts");
|
|
2702
2979
|
const legacyChecksumFile = path.join(outputDir, "bootstrap-modules.generated.checksum");
|
|
2703
2980
|
const enabledIdsOutFile = path.join(outputDir, "enabled-module-ids.generated.ts");
|
|
@@ -2711,6 +2988,7 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
2711
2988
|
const moduleDecls = [];
|
|
2712
2989
|
const bootstrapModuleDecls = [];
|
|
2713
2990
|
const i18nModuleDecls = [];
|
|
2991
|
+
const i18nLocaleShards = /* @__PURE__ */ new Map();
|
|
2714
2992
|
const importIdRef = { value: 0 };
|
|
2715
2993
|
const requiresByModule = /* @__PURE__ */ new Map();
|
|
2716
2994
|
const commandLoaderEntries = [];
|
|
@@ -2722,6 +3000,7 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
2722
3000
|
const frontendRoutes = [];
|
|
2723
3001
|
const backendRoutes = [];
|
|
2724
3002
|
const translations = [];
|
|
3003
|
+
const localeTranslations = /* @__PURE__ */ new Map();
|
|
2725
3004
|
const subscribers = [];
|
|
2726
3005
|
const workers = [];
|
|
2727
3006
|
let infoImportName = null;
|
|
@@ -2837,10 +3116,25 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
2837
3116
|
appImportBase,
|
|
2838
3117
|
pkgImportBase: imps.pkgBase,
|
|
2839
3118
|
imports,
|
|
2840
|
-
extraImports: translationImports
|
|
3119
|
+
extraImports: translationImports,
|
|
3120
|
+
localeOutputs: localeTranslations
|
|
2841
3121
|
}));
|
|
2842
|
-
bootstrapImports.push(...translationImports);
|
|
2843
3122
|
i18nImports.push(...translationImports);
|
|
3123
|
+
for (const [locale, localeTranslation] of localeTranslations) {
|
|
3124
|
+
const shard = i18nLocaleShards.get(locale) ?? { imports: [], moduleDecls: [] };
|
|
3125
|
+
shard.imports.push(...localeTranslation.imports);
|
|
3126
|
+
shard.moduleDecls.push(objectLiteral([
|
|
3127
|
+
{ name: "id", value: modId },
|
|
3128
|
+
{
|
|
3129
|
+
name: "translations",
|
|
3130
|
+
value: objectLiteral([{
|
|
3131
|
+
name: JSON.stringify(locale),
|
|
3132
|
+
value: localeTranslation.value
|
|
3133
|
+
}])
|
|
3134
|
+
}
|
|
3135
|
+
]));
|
|
3136
|
+
i18nLocaleShards.set(locale, shard);
|
|
3137
|
+
}
|
|
2844
3138
|
subscribers.push(...processSubscribersAst(await discovered.getSubscribers()));
|
|
2845
3139
|
workers.push(...processWorkersAst(await discovered.getWorkers()));
|
|
2846
3140
|
{
|
|
@@ -2949,7 +3243,9 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
2949
3243
|
routeAwareModuleEntries.push({ name: "backendRoutes", value: arrayLiteral(backendRoutes, writeValue) });
|
|
2950
3244
|
}
|
|
2951
3245
|
moduleDecls.push(objectLiteral(routeAwareModuleEntries));
|
|
2952
|
-
bootstrapModuleDecls.push(objectLiteral(moduleEntries
|
|
3246
|
+
bootstrapModuleDecls.push(objectLiteral(moduleEntries.filter(
|
|
3247
|
+
(entry) => entry.kind === "spread" || entry.name !== "translations"
|
|
3248
|
+
)));
|
|
2953
3249
|
i18nModuleDecls.push(objectLiteral(i18nModuleEntries));
|
|
2954
3250
|
}
|
|
2955
3251
|
const output = renderAstModuleRegistryFile({
|
|
@@ -3001,6 +3297,41 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
3001
3297
|
writeGeneratedFile({ outFile, checksumFile, content: output, structureChecksum, result, quiet });
|
|
3002
3298
|
writeGeneratedFile({ outFile: bootstrapOutFile, checksumFile: bootstrapChecksumFile, content: bootstrapOutput, structureChecksum, result, quiet });
|
|
3003
3299
|
writeGeneratedFile({ outFile: i18nOutFile, checksumFile: i18nChecksumFile, content: i18nOutput, structureChecksum, result, quiet });
|
|
3300
|
+
const i18nLocales = [...i18nLocaleShards.keys()].sort((a, b) => a.localeCompare(b));
|
|
3301
|
+
const shardFileNames = /* @__PURE__ */ new Set();
|
|
3302
|
+
const expectedShardArtifacts = /* @__PURE__ */ new Set();
|
|
3303
|
+
for (const locale of i18nLocales) {
|
|
3304
|
+
const fileName = buildI18nLocaleShardFileName(locale);
|
|
3305
|
+
if (shardFileNames.has(fileName)) {
|
|
3306
|
+
throw new Error(`Locale names produce the same generated i18n shard file: ${locale}`);
|
|
3307
|
+
}
|
|
3308
|
+
shardFileNames.add(fileName);
|
|
3309
|
+
expectedShardArtifacts.add(fileName);
|
|
3310
|
+
expectedShardArtifacts.add(fileName.replace(/\.ts$/, ".checksum"));
|
|
3311
|
+
const shard = i18nLocaleShards.get(locale);
|
|
3312
|
+
const content = renderAstI18nLocaleRegistryFile({
|
|
3313
|
+
fileName,
|
|
3314
|
+
imports: shard.imports,
|
|
3315
|
+
moduleEntries: shard.moduleDecls
|
|
3316
|
+
});
|
|
3317
|
+
writeGeneratedFile({
|
|
3318
|
+
outFile: path.join(outputDir, fileName),
|
|
3319
|
+
checksumFile: path.join(outputDir, fileName.replace(/\.ts$/, ".checksum")),
|
|
3320
|
+
content,
|
|
3321
|
+
structureChecksum,
|
|
3322
|
+
result,
|
|
3323
|
+
quiet
|
|
3324
|
+
});
|
|
3325
|
+
}
|
|
3326
|
+
removeStaleI18nLocaleShards(outputDir, expectedShardArtifacts);
|
|
3327
|
+
writeGeneratedFile({
|
|
3328
|
+
outFile: i18nLoadersOutFile,
|
|
3329
|
+
checksumFile: i18nLoadersChecksumFile,
|
|
3330
|
+
content: renderI18nLocaleLoadersFile(i18nLocales),
|
|
3331
|
+
structureChecksum,
|
|
3332
|
+
result,
|
|
3333
|
+
quiet
|
|
3334
|
+
});
|
|
3004
3335
|
writeGeneratedFile({ outFile: legacyOutFile, checksumFile: legacyChecksumFile, content: legacyOutput, structureChecksum, result, quiet });
|
|
3005
3336
|
const enabledIdsOutput = renderEnabledModuleIdsFile(enabled.map((entry) => entry.id));
|
|
3006
3337
|
writeGeneratedFile({ outFile: enabledIdsOutFile, checksumFile: enabledIdsChecksumFile, content: enabledIdsOutput, structureChecksum, result, quiet });
|
|
@@ -3019,14 +3350,19 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3019
3350
|
const legacyChecksumFile = path.join(outputDir, "cli-modules.generated.checksum");
|
|
3020
3351
|
const commandLoadersOutFile = path.join(outputDir, "command-loaders.generated.ts");
|
|
3021
3352
|
const commandLoadersChecksumFile = path.join(outputDir, "command-loaders.generated.checksum");
|
|
3353
|
+
const devSupervisorOutFile = path.join(outputDir, DEV_SUPERVISOR_MANIFEST_FILE);
|
|
3354
|
+
const devSupervisorChecksumFile = path.join(outputDir, "dev-supervisor.generated.checksum");
|
|
3022
3355
|
const enabled = discovery.enabled;
|
|
3023
3356
|
const imports = [];
|
|
3024
3357
|
const moduleDecls = [];
|
|
3025
3358
|
const importIdRef = { value: 0 };
|
|
3026
3359
|
const requiresByModule = /* @__PURE__ */ new Map();
|
|
3027
3360
|
const commandLoaderEntries = [];
|
|
3361
|
+
const devSupervisorWorkers = [];
|
|
3362
|
+
let schedulerStartStatus = "missing-module";
|
|
3363
|
+
let requiresFullBootstrap = enabled.some((entry) => entry.devSupervisorRequiresFullBootstrap === true) || appDeclaresProgrammaticDevSupervisorOverrides(resolver.getAppDir());
|
|
3028
3364
|
for (const discovered of discovery.modules) {
|
|
3029
|
-
const { modId,
|
|
3365
|
+
const { modId, imps, appImportBase } = discovered;
|
|
3030
3366
|
commandLoaderEntries.push(...discovered.commandLoaderEntries);
|
|
3031
3367
|
let cliImportName = null;
|
|
3032
3368
|
const translations = [];
|
|
@@ -3096,11 +3432,20 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3096
3432
|
if (fields) fieldsImportName = fields.importName;
|
|
3097
3433
|
}
|
|
3098
3434
|
{
|
|
3435
|
+
if (modId === "scheduler") schedulerStartStatus = "missing-cli";
|
|
3099
3436
|
const cliResolved = discovered.resolve("cli.ts");
|
|
3100
3437
|
if (cliResolved) {
|
|
3101
3438
|
const importName = `CLI_${toVar(modId)}`;
|
|
3102
3439
|
imports.push(buildImportStatement(importName, sanitizeGeneratedModuleSpecifier(cliResolved.importPath)));
|
|
3103
3440
|
cliImportName = importName;
|
|
3441
|
+
if (modId === "scheduler") {
|
|
3442
|
+
if (sourceDeclaresCliCommand(cliResolved.absolutePath, "start")) {
|
|
3443
|
+
schedulerStartStatus = "ok";
|
|
3444
|
+
} else {
|
|
3445
|
+
schedulerStartStatus = "missing-command";
|
|
3446
|
+
requiresFullBootstrap = true;
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3104
3449
|
}
|
|
3105
3450
|
}
|
|
3106
3451
|
translations.push(...processTranslationsAst({
|
|
@@ -3111,7 +3456,10 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3111
3456
|
imports
|
|
3112
3457
|
}));
|
|
3113
3458
|
subscribers.push(...processSubscribersAst(await discovered.getSubscribers()));
|
|
3114
|
-
|
|
3459
|
+
const discoveredWorkers = await discovered.getWorkers();
|
|
3460
|
+
const workerGenerationEntries = collectWorkerGenerationEntries(discoveredWorkers, modId);
|
|
3461
|
+
workers.push(...processWorkersAst(discoveredWorkers));
|
|
3462
|
+
devSupervisorWorkers.push(...workerGenerationEntries.map(({ importPath: _importPath, ...worker }) => worker));
|
|
3115
3463
|
{
|
|
3116
3464
|
dashboardWidgetsValue = buildModuleDashboardWidgetsValue(discovered.dashboardWidgetEntries);
|
|
3117
3465
|
}
|
|
@@ -3265,6 +3613,21 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3265
3613
|
const structureChecksum = discovery.getStructureChecksum();
|
|
3266
3614
|
writeGeneratedFile({ outFile, checksumFile, content: output, structureChecksum, result, quiet });
|
|
3267
3615
|
writeGeneratedFile({ outFile: legacyOutFile, checksumFile: legacyChecksumFile, content: legacyOutput, structureChecksum, result, quiet });
|
|
3616
|
+
const devSupervisorOutput = `${JSON.stringify({
|
|
3617
|
+
version: DEV_SUPERVISOR_MANIFEST_VERSION,
|
|
3618
|
+
workers: devSupervisorWorkers,
|
|
3619
|
+
schedulerStartStatus,
|
|
3620
|
+
requiresFullBootstrap
|
|
3621
|
+
}, null, 2)}
|
|
3622
|
+
`;
|
|
3623
|
+
writeGeneratedFile({
|
|
3624
|
+
outFile: devSupervisorOutFile,
|
|
3625
|
+
checksumFile: devSupervisorChecksumFile,
|
|
3626
|
+
content: devSupervisorOutput,
|
|
3627
|
+
structureChecksum,
|
|
3628
|
+
result,
|
|
3629
|
+
quiet
|
|
3630
|
+
});
|
|
3268
3631
|
const commandLoadersOutput = renderCommandLoadersFile(commandLoaderEntries);
|
|
3269
3632
|
writeGeneratedFile({ outFile: commandLoadersOutFile, checksumFile: commandLoadersChecksumFile, content: commandLoadersOutput, structureChecksum, result, quiet });
|
|
3270
3633
|
return result;
|