@open-mercato/cli 0.7.0 → 0.7.1-develop.7103.1.41ff100d93
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 +7 -1
- package/dist/agentic/guides/module-facts.json +5509 -599
- package/dist/agentic/guides/module-facts.v2.json +5595 -599
- package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
- package/dist/agentic/guides/modules/api_docs/index.md +1 -1
- package/dist/agentic/guides/modules/api_keys/di-registrations-rich.md +11 -0
- package/dist/agentic/guides/modules/api_keys/di-service-tokens.md +11 -0
- package/dist/agentic/guides/modules/api_keys/exact-override-targets.md +1 -0
- package/dist/agentic/guides/modules/api_keys/index.md +4 -2
- package/dist/agentic/guides/modules/attachments/di-registrations-rich.md +6 -5
- package/dist/agentic/guides/modules/attachments/di-service-tokens.md +5 -4
- package/dist/agentic/guides/modules/attachments/exact-override-targets.md +6 -5
- package/dist/agentic/guides/modules/attachments/index.md +2 -2
- package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
- package/dist/agentic/guides/modules/auth/di-registrations-rich.md +3 -2
- package/dist/agentic/guides/modules/auth/di-service-tokens.md +3 -2
- package/dist/agentic/guides/modules/auth/exact-override-targets.md +3 -2
- package/dist/agentic/guides/modules/auth/index.md +1 -1
- package/dist/agentic/guides/modules/business_rules/index.md +1 -1
- package/dist/agentic/guides/modules/catalog/incoming-installed-contributions.md +3 -0
- package/dist/agentic/guides/modules/catalog/index.md +2 -2
- package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
- package/dist/agentic/guides/modules/channel_discord/acl-features.md +13 -0
- package/dist/agentic/guides/modules/channel_discord/ai-agents.md +11 -0
- package/dist/agentic/guides/modules/channel_discord/backend-pages.md +11 -0
- package/dist/agentic/guides/modules/channel_discord/cli-commands.md +13 -0
- package/dist/agentic/guides/modules/channel_discord/contribution-resolutions.md +14 -0
- package/dist/agentic/guides/modules/channel_discord/di-registrations-rich.md +12 -0
- package/dist/agentic/guides/modules/channel_discord/exact-override-targets.md +26 -0
- package/dist/agentic/guides/modules/channel_discord/index.md +22 -0
- package/dist/agentic/guides/modules/channel_discord/owned-contract-module-metadata.md +11 -0
- package/dist/agentic/guides/modules/channel_discord/setup.md +11 -0
- package/dist/agentic/guides/modules/channel_discord/umes-contributions.md +14 -0
- package/dist/agentic/guides/modules/channel_discord/workers.md +12 -0
- package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
- package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
- package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
- package/dist/agentic/guides/modules/checkout/index.md +1 -1
- package/dist/agentic/guides/modules/communication_channels/di-registrations-rich.md +9 -8
- package/dist/agentic/guides/modules/communication_channels/exact-override-targets.md +9 -8
- package/dist/agentic/guides/modules/communication_channels/incoming-installed-contributions.md +2 -0
- package/dist/agentic/guides/modules/communication_channels/index.md +3 -3
- package/dist/agentic/guides/modules/configs/index.md +1 -1
- package/dist/agentic/guides/modules/content/index.md +1 -1
- package/dist/agentic/guides/modules/currencies/index.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
- package/dist/agentic/guides/modules/customers/active-extension-bindings.md +6 -3
- package/dist/agentic/guides/modules/customers/contribution-resolutions.md +1 -0
- package/dist/agentic/guides/modules/customers/events.md +2 -1
- package/dist/agentic/guides/modules/customers/incoming-installed-contributions.md +7 -0
- package/dist/agentic/guides/modules/customers/index.md +4 -4
- package/dist/agentic/guides/modules/customers/umes-contributions.md +1 -0
- package/dist/agentic/guides/modules/customers/umes-hosts.md +1 -0
- package/dist/agentic/guides/modules/dashboards/index.md +1 -1
- package/dist/agentic/guides/modules/data_sync/exact-override-targets.md +2 -2
- package/dist/agentic/guides/modules/data_sync/index.md +1 -1
- package/dist/agentic/guides/modules/data_sync/workers.md +2 -2
- package/dist/agentic/guides/modules/design_system/index.md +1 -1
- package/dist/agentic/guides/modules/devices/index.md +1 -1
- package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
- package/dist/agentic/guides/modules/directory/di-registrations-rich.md +12 -0
- package/dist/agentic/guides/modules/directory/di-service-tokens.md +12 -0
- package/dist/agentic/guides/modules/directory/exact-override-targets.md +2 -0
- package/dist/agentic/guides/modules/directory/index.md +5 -3
- package/dist/agentic/guides/modules/documents/acl-features.md +17 -0
- package/dist/agentic/guides/modules/documents/backend-pages.md +13 -0
- package/dist/agentic/guides/modules/documents/contribution-resolutions.md +27 -0
- package/dist/agentic/guides/modules/documents/di-registrations-rich.md +21 -0
- package/dist/agentic/guides/modules/documents/domain-commands.md +37 -0
- package/dist/agentic/guides/modules/documents/encryption.md +11 -0
- package/dist/agentic/guides/modules/documents/entities.md +21 -0
- package/dist/agentic/guides/modules/documents/events.md +25 -0
- package/dist/agentic/guides/modules/documents/exact-override-targets.md +39 -0
- package/dist/agentic/guides/modules/documents/index.md +25 -0
- package/dist/agentic/guides/modules/documents/notifications.md +13 -0
- package/dist/agentic/guides/modules/documents/owned-contract-module-metadata.md +11 -0
- package/dist/agentic/guides/modules/documents/setup.md +11 -0
- package/dist/agentic/guides/modules/documents/umes-contributions.md +27 -0
- package/dist/agentic/guides/modules/documents/umes-hosts.md +36 -0
- package/dist/agentic/guides/modules/entities/index.md +1 -1
- package/dist/agentic/guides/modules/eudr/index.md +1 -1
- package/dist/agentic/guides/modules/events/index.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/exact-override-targets.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/workers.md +1 -1
- package/dist/agentic/guides/modules/generators/index.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
- package/dist/agentic/guides/modules/integrations/index.md +1 -1
- package/dist/agentic/guides/modules/messages/index.md +1 -1
- package/dist/agentic/guides/modules/notifications/index.md +1 -1
- package/dist/agentic/guides/modules/onboarding/index.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
- package/dist/agentic/guides/modules/perspectives/index.md +1 -1
- package/dist/agentic/guides/modules/planner/index.md +1 -1
- package/dist/agentic/guides/modules/portal/index.md +1 -1
- package/dist/agentic/guides/modules/progress/index.md +1 -1
- package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
- package/dist/agentic/guides/modules/query_index/index.md +1 -1
- package/dist/agentic/guides/modules/record_locks/index.md +1 -1
- package/dist/agentic/guides/modules/resources/index.md +1 -1
- package/dist/agentic/guides/modules/sales/active-extension-bindings.md +1 -0
- package/dist/agentic/guides/modules/sales/contribution-resolutions.md +1 -0
- package/dist/agentic/guides/modules/sales/exact-override-targets.md +5 -4
- package/dist/agentic/guides/modules/sales/host-extension-points.md +1 -1
- package/dist/agentic/guides/modules/sales/incoming-installed-contributions.md +2 -0
- package/dist/agentic/guides/modules/sales/index.md +3 -3
- package/dist/agentic/guides/modules/sales/setup.md +1 -1
- package/dist/agentic/guides/modules/sales/umes-contributions.md +1 -0
- package/dist/agentic/guides/modules/sales/umes-diagnostics.md +1 -0
- package/dist/agentic/guides/modules/sales/umes-hosts.md +9 -0
- package/dist/agentic/guides/modules/scheduler/cli-commands.md +1 -0
- package/dist/agentic/guides/modules/scheduler/exact-override-targets.md +3 -1
- package/dist/agentic/guides/modules/scheduler/index.md +2 -2
- package/dist/agentic/guides/modules/scheduler/workers.md +2 -1
- package/dist/agentic/guides/modules/search/index.md +1 -1
- package/dist/agentic/guides/modules/security/index.md +1 -1
- package/dist/agentic/guides/modules/security/owned-contract-module-metadata.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
- package/dist/agentic/guides/modules/sso/index.md +1 -1
- package/dist/agentic/guides/modules/staff/index.md +1 -1
- package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
- package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
- package/dist/agentic/guides/modules/translations/index.md +1 -1
- package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
- package/dist/agentic/guides/modules/webhooks/index.md +1 -1
- package/dist/agentic/guides/modules/wms/index.md +1 -1
- package/dist/agentic/guides/modules/workflows/index.md +1 -1
- package/dist/agentic/guides/reference-module-facts.json +2 -2
- package/dist/agentic/guides/reference-modules/example/index.md +1 -1
- package/dist/agentic/guides/upstream/manifest.json +1 -1
- package/dist/agentic/shared/AGENTS.md.template +3 -3
- package/dist/agentic/shared/ai/harness/README.md +2 -2
- package/dist/agentic/shared/ai/harness/RELEASE.md +8 -6
- package/dist/agentic/shared/ai/harness/cases.json +83 -0
- package/dist/agentic/shared/ai/harness/cases.schema.json +4 -4
- package/dist/agentic/shared/ai/harness/validators.json +1 -1
- package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +37 -11
- package/dist/lib/generators/ast/index.js +4 -1
- package/dist/lib/generators/ast/index.js.map +2 -2
- package/dist/lib/generators/ast/source-file.js +8 -1
- package/dist/lib/generators/ast/source-file.js.map +2 -2
- package/dist/lib/generators/ast/writers.js +9 -1
- package/dist/lib/generators/ast/writers.js.map +2 -2
- package/dist/lib/generators/module-registry.js +424 -189
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/generators/route-manifest-shards.js +4 -1
- package/dist/lib/generators/route-manifest-shards.js.map +2 -2
- package/dist/lib/spawn.js +3 -2
- package/dist/lib/spawn.js.map +2 -2
- package/dist/lib/testing/integration.js +162 -24
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/mercato.js +14 -0
- package/dist/mercato.js.map +2 -2
- package/package.json +8 -7
- package/src/__tests__/resolve-queue-abandon-hook.test.ts +39 -0
- package/src/lib/__tests__/spawn.test.ts +23 -0
- package/src/lib/generators/__tests__/__snapshots__/bootstrap-registrations.test.ts.snap +14 -0
- package/src/lib/generators/__tests__/__snapshots__/command-loaders.test.ts.snap +23 -0
- package/src/lib/generators/__tests__/ast-writers-escaping.test.ts +64 -0
- package/src/lib/generators/__tests__/bootstrap-registrations.test.ts +176 -0
- package/src/lib/generators/__tests__/command-loaders.test.ts +239 -0
- package/src/lib/generators/__tests__/generated-registry-imports.test.ts +128 -0
- package/src/lib/generators/__tests__/metadata-extraction.test.ts +44 -0
- package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +32 -8
- package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +4 -1
- package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +1 -1
- package/src/lib/generators/__tests__/module-subset.test.ts +96 -72
- package/src/lib/generators/__tests__/output-snapshots.test.ts +1 -1
- package/src/lib/generators/__tests__/registry-variant-parity.test.ts +258 -0
- package/src/lib/generators/__tests__/route-manifest-shards.test.ts +15 -0
- package/src/lib/generators/__tests__/structural-contracts.test.ts +7 -3
- package/src/lib/generators/ast/index.ts +2 -1
- package/src/lib/generators/ast/source-file.ts +13 -0
- package/src/lib/generators/ast/writers.ts +26 -1
- package/src/lib/generators/module-registry.ts +534 -227
- package/src/lib/generators/route-manifest-shards.ts +8 -1
- package/src/lib/spawn.ts +5 -4
- package/src/lib/testing/__tests__/integration.test.ts +435 -0
- package/src/lib/testing/integration.ts +254 -32
- package/src/mercato.ts +27 -0
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
conditionalExpression,
|
|
29
29
|
createGeneratedSourceFile,
|
|
30
30
|
elementAccess,
|
|
31
|
+
escapeGeneratedJsonLiteral,
|
|
31
32
|
returnStatement,
|
|
32
33
|
getSourceText,
|
|
33
34
|
identifier,
|
|
@@ -40,6 +41,7 @@ import {
|
|
|
40
41
|
optionalPropertyAccess,
|
|
41
42
|
parenthesized,
|
|
42
43
|
propertyAccess,
|
|
44
|
+
renderGeneratedValue,
|
|
43
45
|
spreadExpression,
|
|
44
46
|
variableStatement,
|
|
45
47
|
writeArrayLiteral,
|
|
@@ -320,6 +322,38 @@ function extractObjectPropertiesFromAst(sourceFile, exportName) {
|
|
|
320
322
|
}
|
|
321
323
|
return Object.keys(result).length > 0 ? result : null;
|
|
322
324
|
}
|
|
325
|
+
function namedObjectLiteralDeclaresProperty(sourceFile, exportName, propertyName) {
|
|
326
|
+
let source = "";
|
|
327
|
+
try {
|
|
328
|
+
source = fs.readFileSync(sourceFile, "utf8");
|
|
329
|
+
} catch {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
const parsed = ts.createSourceFile(sourceFile, source, ts.ScriptTarget.Latest, true, inferScriptKind(sourceFile));
|
|
333
|
+
const exportedNames = /* @__PURE__ */ new Set();
|
|
334
|
+
for (const statement of parsed.statements) {
|
|
335
|
+
if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause) && !statement.moduleSpecifier) {
|
|
336
|
+
for (const element of statement.exportClause.elements) exportedNames.add(element.name.text);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
for (const statement of parsed.statements) {
|
|
340
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
341
|
+
const exportsDirectly = (ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : void 0)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
|
|
342
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
343
|
+
if (!ts.isIdentifier(declaration.name) || declaration.name.text !== exportName) continue;
|
|
344
|
+
if (!exportsDirectly && !exportedNames.has(exportName)) continue;
|
|
345
|
+
const objectLiteral2 = unwrapObjectLiteralExpression(declaration.initializer);
|
|
346
|
+
if (!objectLiteral2) return false;
|
|
347
|
+
return objectLiteral2.properties.some((property) => {
|
|
348
|
+
const name = property.name;
|
|
349
|
+
if (!name) return false;
|
|
350
|
+
const key = ts.isIdentifier(name) ? name.text : ts.isStringLiteral(name) ? name.text : null;
|
|
351
|
+
return key === propertyName;
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
323
357
|
function extractNamedObjectLiteralExport(sourceFile, exportName) {
|
|
324
358
|
const literal = extractNamedObjectLiteralSource(sourceFile, exportName);
|
|
325
359
|
if (literal) {
|
|
@@ -743,7 +777,7 @@ function requiresRuntimePageMetadataFromSourceFile(sourceFile) {
|
|
|
743
777
|
return !/^['"`]/.test(iconMatch[1].trim());
|
|
744
778
|
}
|
|
745
779
|
function toLiteral(value) {
|
|
746
|
-
return JSON.stringify(value)
|
|
780
|
+
return escapeGeneratedJsonLiteral(JSON.stringify(value));
|
|
747
781
|
}
|
|
748
782
|
const GENERATED_MODULE_RELATIVE_PREFIXES = ["@/", "../../src/modules/", "./"];
|
|
749
783
|
const GENERATED_MODULE_SPECIFIER_SEGMENT = /^[A-Za-z0-9_.\-[\]()']+$/;
|
|
@@ -932,28 +966,66 @@ function collectCommandLoaderEntries(roots, imps, modId, quiet = false) {
|
|
|
932
966
|
}
|
|
933
967
|
function renderCommandLoadersFile(entries) {
|
|
934
968
|
const seenCommandIds = /* @__PURE__ */ new Map();
|
|
935
|
-
const
|
|
969
|
+
const loaderEntries = [];
|
|
936
970
|
for (const entry of entries) {
|
|
937
|
-
const
|
|
971
|
+
const loadValue = arrowFunction({
|
|
972
|
+
body: importExpression(sanitizeGeneratedModuleSpecifier(entry.importPath))
|
|
973
|
+
});
|
|
938
974
|
for (const id of entry.ids) {
|
|
939
975
|
const previous = seenCommandIds.get(id);
|
|
940
976
|
if (previous && previous !== entry.key) {
|
|
941
977
|
throw new Error(`[generate] Duplicate command id "${id}" discovered in "${previous}" and "${entry.key}"`);
|
|
942
978
|
}
|
|
943
979
|
seenCommandIds.set(id, entry.key);
|
|
944
|
-
|
|
980
|
+
loaderEntries.push(objectLiteral([
|
|
981
|
+
{ name: "moduleId", value: entry.moduleId },
|
|
982
|
+
{ name: "id", value: id },
|
|
983
|
+
{ name: "key", value: entry.key },
|
|
984
|
+
{ name: "load", value: loadValue }
|
|
985
|
+
]));
|
|
945
986
|
}
|
|
946
|
-
|
|
987
|
+
loaderEntries.push(objectLiteral([
|
|
988
|
+
{ name: "moduleId", value: entry.moduleId },
|
|
989
|
+
{ name: "key", value: entry.key },
|
|
990
|
+
{ name: "load", value: loadValue }
|
|
991
|
+
]));
|
|
947
992
|
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
]
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
993
|
+
const sourceFile = createGeneratedSourceFile("command-loaders.generated.ts");
|
|
994
|
+
addAutoGeneratedComment(sourceFile, "command-loaders");
|
|
995
|
+
addImportSpec(sourceFile, {
|
|
996
|
+
moduleSpecifier: "@open-mercato/shared/lib/commands",
|
|
997
|
+
isTypeOnly: true,
|
|
998
|
+
namedImports: [{ name: "CommandLoader" }]
|
|
999
|
+
});
|
|
1000
|
+
sourceFile.addVariableStatement({
|
|
1001
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
1002
|
+
isExported: true,
|
|
1003
|
+
declarations: [
|
|
1004
|
+
{
|
|
1005
|
+
name: "commandLoaderEntries",
|
|
1006
|
+
type: "CommandLoader[]",
|
|
1007
|
+
initializer: arrayLiteral(loaderEntries, writeValue)
|
|
1008
|
+
}
|
|
1009
|
+
]
|
|
1010
|
+
});
|
|
1011
|
+
sourceFile.addExportAssignment({
|
|
1012
|
+
isExportEquals: false,
|
|
1013
|
+
expression: "commandLoaderEntries"
|
|
1014
|
+
});
|
|
1015
|
+
return getSourceText(sourceFile);
|
|
1016
|
+
}
|
|
1017
|
+
function renderBootstrapRegistrationsFile(options) {
|
|
1018
|
+
const uniqueImports = [.../* @__PURE__ */ new Set([...options.entryImports, ...options.registrationImports])];
|
|
1019
|
+
const sourceFile = createGeneratedSourceFile("bootstrap-registrations.generated.ts");
|
|
1020
|
+
addAutoGeneratedComment(sourceFile, "registry");
|
|
1021
|
+
addImportStatements(sourceFile, uniqueImports);
|
|
1022
|
+
sourceFile.addFunction({
|
|
1023
|
+
name: "runBootstrapRegistrations",
|
|
1024
|
+
isExported: true,
|
|
1025
|
+
returnType: "void",
|
|
1026
|
+
statements: options.calls
|
|
1027
|
+
});
|
|
1028
|
+
return getSourceText(sourceFile);
|
|
957
1029
|
}
|
|
958
1030
|
function serializeGeneratedImport(statement) {
|
|
959
1031
|
if (typeof statement === "string") {
|
|
@@ -1136,7 +1208,35 @@ function buildPageRouteProps(metaExpr, routePath) {
|
|
|
1136
1208
|
return `pattern: ${toLiteral(routePath || "/")}, requireAuth: (${metaExpr})?.requireAuth, requireRoles: (${metaExpr})?.requireRoles, requireFeatures: (${metaExpr})?.requireFeatures, requireCustomerAuth: (${metaExpr})?.requireCustomerAuth, requireCustomerFeatures: (${metaExpr})?.requireCustomerFeatures, nav: (${metaExpr})?.nav, title: (${metaExpr})?.pageTitle ?? (${metaExpr})?.title, titleKey: (${metaExpr})?.pageTitleKey ?? (${metaExpr})?.titleKey, group: (${metaExpr})?.pageGroup ?? (${metaExpr})?.group, groupKey: (${metaExpr})?.pageGroupKey ?? (${metaExpr})?.groupKey, icon: (${metaExpr})?.icon, order: (${metaExpr})?.pageOrder ?? (${metaExpr})?.order, priority: (${metaExpr})?.pagePriority ?? (${metaExpr})?.priority, navHidden: (${metaExpr})?.navHidden, visible: (${metaExpr})?.visible, enabled: (${metaExpr})?.enabled, breadcrumb: (${metaExpr})?.breadcrumb, pageContext: (${metaExpr})?.pageContext, placement: (${metaExpr})?.placement`;
|
|
1137
1209
|
}
|
|
1138
1210
|
function buildPageRouteManifestSpread(metaExpr, routePath) {
|
|
1139
|
-
return
|
|
1211
|
+
return callExpression(identifier("resolvePageRouteMetadata"), [routePath || "/", identifier(metaExpr)]);
|
|
1212
|
+
}
|
|
1213
|
+
function buildManifestRouteLoader(importPath) {
|
|
1214
|
+
return arrowFunction({
|
|
1215
|
+
async: true,
|
|
1216
|
+
body: block((writer) => {
|
|
1217
|
+
writeStatements(writer, [
|
|
1218
|
+
variableStatement({
|
|
1219
|
+
name: "mod",
|
|
1220
|
+
initializer: awaitExpression(importExpression(sanitizeGeneratedModuleSpecifier(importPath)))
|
|
1221
|
+
}),
|
|
1222
|
+
returnStatement(
|
|
1223
|
+
asExpression(
|
|
1224
|
+
parenthesized(nullishCoalesce([
|
|
1225
|
+
propertyAccess(identifier("mod"), "default"),
|
|
1226
|
+
identifier("mod")
|
|
1227
|
+
])),
|
|
1228
|
+
"any"
|
|
1229
|
+
)
|
|
1230
|
+
)
|
|
1231
|
+
]);
|
|
1232
|
+
})
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
function buildManifestApiLoader(importPath) {
|
|
1236
|
+
return arrowFunction({
|
|
1237
|
+
async: true,
|
|
1238
|
+
body: importExpression(sanitizeGeneratedModuleSpecifier(importPath))
|
|
1239
|
+
});
|
|
1140
1240
|
}
|
|
1141
1241
|
function normalizeBreadcrumb(raw) {
|
|
1142
1242
|
if (!Array.isArray(raw)) return void 0;
|
|
@@ -1238,6 +1338,14 @@ function normalizeWorkerMetadata(raw) {
|
|
|
1238
1338
|
if (typeof source.concurrency === "number") normalized.concurrency = source.concurrency;
|
|
1239
1339
|
if (typeof source.lockDuration === "number") normalized.lockDuration = source.lockDuration;
|
|
1240
1340
|
if (typeof source.maxStalledCount === "number") normalized.maxStalledCount = source.maxStalledCount;
|
|
1341
|
+
if (typeof source.onJobAbandoned === "function") normalized.hasJobAbandonedHook = true;
|
|
1342
|
+
if (source.schedulerSafe === true) normalized.schedulerSafe = true;
|
|
1343
|
+
if (Array.isArray(source.schedulerRequiredFeatures)) {
|
|
1344
|
+
const features = source.schedulerRequiredFeatures.filter(
|
|
1345
|
+
(feature) => typeof feature === "string" && feature.length > 0
|
|
1346
|
+
);
|
|
1347
|
+
if (features.length > 0) normalized.schedulerRequiredFeatures = features;
|
|
1348
|
+
}
|
|
1241
1349
|
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
1242
1350
|
}
|
|
1243
1351
|
async function loadSubscriberMetadata(sourceFile) {
|
|
@@ -1246,7 +1354,12 @@ async function loadSubscriberMetadata(sourceFile) {
|
|
|
1246
1354
|
}
|
|
1247
1355
|
async function loadWorkerMetadata(sourceFile) {
|
|
1248
1356
|
const sourceModule = await loadModuleExportsFromSource(sourceFile);
|
|
1249
|
-
|
|
1357
|
+
const metadata = normalizeWorkerMetadata(sourceModule?.metadata) ?? normalizeWorkerMetadata(extractNamedObjectLiteralExport(sourceFile, "metadata"));
|
|
1358
|
+
if (!metadata) return null;
|
|
1359
|
+
if (!metadata.hasJobAbandonedHook && namedObjectLiteralDeclaresProperty(sourceFile, "metadata", "onJobAbandoned")) {
|
|
1360
|
+
metadata.hasJobAbandonedHook = true;
|
|
1361
|
+
}
|
|
1362
|
+
return metadata;
|
|
1250
1363
|
}
|
|
1251
1364
|
async function discoverSubscribers(roots, imps, modId) {
|
|
1252
1365
|
const subscribers = [];
|
|
@@ -1457,18 +1570,25 @@ async function processPageFiles(options) {
|
|
|
1457
1570
|
const manifestBaseProps = buildPageRouteManifestSpread(manifestMetaExpr, routePath);
|
|
1458
1571
|
eagerRoutes.push(`{ ${baseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1459
1572
|
runtimeRoutes.push(`{ ${runtimeBaseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1573
|
+
const metadataEntries = [
|
|
1574
|
+
{ name: "moduleId", value: modId },
|
|
1575
|
+
{ kind: "spread", value: manifestBaseProps }
|
|
1576
|
+
];
|
|
1577
|
+
const manifestEntry = objectLiteral([
|
|
1578
|
+
...metadataEntries,
|
|
1579
|
+
{ name: "load", value: buildManifestRouteLoader(importPath) }
|
|
1580
|
+
]);
|
|
1581
|
+
const shardImports = manifestImportStatement ? [manifestImportStatement] : [];
|
|
1582
|
+
manifestRoutes.push(manifestEntry);
|
|
1463
1583
|
manifestShardRoutes.push({
|
|
1464
1584
|
path: routePath,
|
|
1465
|
-
declaration:
|
|
1466
|
-
imports:
|
|
1585
|
+
declaration: renderGeneratedValue(manifestEntry),
|
|
1586
|
+
imports: shardImports
|
|
1467
1587
|
});
|
|
1468
1588
|
metadataRoutes.push({
|
|
1469
1589
|
path: routePath,
|
|
1470
|
-
declaration:
|
|
1471
|
-
imports:
|
|
1590
|
+
declaration: renderGeneratedValue(objectLiteral(metadataEntries)),
|
|
1591
|
+
imports: shardImports
|
|
1472
1592
|
});
|
|
1473
1593
|
routePatterns.push(routePath);
|
|
1474
1594
|
}
|
|
@@ -1542,18 +1662,25 @@ async function processPageFiles(options) {
|
|
|
1542
1662
|
const manifestBaseProps = buildPageRouteManifestSpread(manifestMetaExpr, routePath);
|
|
1543
1663
|
eagerRoutes.push(`{ ${baseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1544
1664
|
runtimeRoutes.push(`{ ${runtimeBaseProps}, Component: ${buildLazyRouteComponentExpression(importPath)} }`);
|
|
1545
|
-
const
|
|
1546
|
-
|
|
1547
|
-
|
|
1665
|
+
const metadataEntries = [
|
|
1666
|
+
{ name: "moduleId", value: modId },
|
|
1667
|
+
{ kind: "spread", value: manifestBaseProps }
|
|
1668
|
+
];
|
|
1669
|
+
const manifestEntry = objectLiteral([
|
|
1670
|
+
...metadataEntries,
|
|
1671
|
+
{ name: "load", value: buildManifestRouteLoader(importPath) }
|
|
1672
|
+
]);
|
|
1673
|
+
const shardImports = manifestImportStatement ? [manifestImportStatement] : [];
|
|
1674
|
+
manifestRoutes.push(manifestEntry);
|
|
1548
1675
|
manifestShardRoutes.push({
|
|
1549
1676
|
path: routePath,
|
|
1550
|
-
declaration:
|
|
1551
|
-
imports:
|
|
1677
|
+
declaration: renderGeneratedValue(manifestEntry),
|
|
1678
|
+
imports: shardImports
|
|
1552
1679
|
});
|
|
1553
1680
|
metadataRoutes.push({
|
|
1554
1681
|
path: routePath,
|
|
1555
|
-
declaration:
|
|
1556
|
-
imports:
|
|
1682
|
+
declaration: renderGeneratedValue(objectLiteral(metadataEntries)),
|
|
1683
|
+
imports: shardImports
|
|
1557
1684
|
});
|
|
1558
1685
|
routePatterns.push(routePath);
|
|
1559
1686
|
}
|
|
@@ -1606,11 +1733,19 @@ async function processApiRoutes(options) {
|
|
|
1606
1733
|
eagerImports.push(buildImportStatement(`* as ${importName}`, importPath));
|
|
1607
1734
|
eagerApis.push(`{ path: ((${importName} as any).metadata?.path ?? ${toLiteral(routePath)}), metadata: (${importName} as any).metadata, handlers: ${importName} as any${docsPart} }`);
|
|
1608
1735
|
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(", ")} } }`);
|
|
1609
|
-
const
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1736
|
+
const metadataEntries = [
|
|
1737
|
+
{ name: "moduleId", value: modId },
|
|
1738
|
+
{ name: "kind", value: "route-file" },
|
|
1739
|
+
{ name: "path", value: resolvedPath },
|
|
1740
|
+
{ name: "methods", value: arrayLiteral(exportedMethods, writeValue) }
|
|
1741
|
+
];
|
|
1742
|
+
const manifestEntry = objectLiteral([
|
|
1743
|
+
...metadataEntries,
|
|
1744
|
+
{ name: "load", value: buildManifestApiLoader(importPath) }
|
|
1745
|
+
]);
|
|
1746
|
+
manifestApis.push(manifestEntry);
|
|
1747
|
+
manifestShardApis.push({ path: resolvedPath, declaration: renderGeneratedValue(manifestEntry) });
|
|
1748
|
+
metadataApis.push({ path: resolvedPath, declaration: renderGeneratedValue(objectLiteral(metadataEntries)) });
|
|
1614
1749
|
}
|
|
1615
1750
|
const plainFiles = scanModuleDir(roots, SCAN_CONFIGS.apiPlainFiles);
|
|
1616
1751
|
for (const { relPath, fromApp } of plainFiles) {
|
|
@@ -1640,11 +1775,19 @@ async function processApiRoutes(options) {
|
|
|
1640
1775
|
eagerImports.push(buildImportStatement(`* as ${importName}`, importPath));
|
|
1641
1776
|
eagerApis.push(`{ path: ((${importName} as any).metadata?.path ?? ${toLiteral(routePath)}), metadata: (${importName} as any).metadata, handlers: ${importName} as any${docsPart} }`);
|
|
1642
1777
|
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(", ")} } }`);
|
|
1643
|
-
const
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1778
|
+
const metadataEntries = [
|
|
1779
|
+
{ name: "moduleId", value: modId },
|
|
1780
|
+
{ name: "kind", value: "route-file" },
|
|
1781
|
+
{ name: "path", value: resolvedPath },
|
|
1782
|
+
{ name: "methods", value: arrayLiteral(exportedMethods, writeValue) }
|
|
1783
|
+
];
|
|
1784
|
+
const manifestEntry = objectLiteral([
|
|
1785
|
+
...metadataEntries,
|
|
1786
|
+
{ name: "load", value: buildManifestApiLoader(importPath) }
|
|
1787
|
+
]);
|
|
1788
|
+
manifestApis.push(manifestEntry);
|
|
1789
|
+
manifestShardApis.push({ path: resolvedPath, declaration: renderGeneratedValue(manifestEntry) });
|
|
1790
|
+
metadataApis.push({ path: resolvedPath, declaration: renderGeneratedValue(objectLiteral(metadataEntries)) });
|
|
1648
1791
|
}
|
|
1649
1792
|
const methods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
1650
1793
|
for (const method of methods) {
|
|
@@ -1683,11 +1826,20 @@ async function processApiRoutes(options) {
|
|
|
1683
1826
|
eagerImports.push(buildImportStatement(`${importName}, * as ${metaName}`, importPath));
|
|
1684
1827
|
eagerApis.push(`{ method: ${toLiteral(method)}, path: (${metaName}.metadata?.path ?? ${toLiteral(routePath)}), handler: ${importName}, metadata: ${metaName}.metadata${docsPart} }`);
|
|
1685
1828
|
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} }`);
|
|
1686
|
-
const
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1829
|
+
const metadataEntries = [
|
|
1830
|
+
{ name: "moduleId", value: modId },
|
|
1831
|
+
{ name: "kind", value: "legacy" },
|
|
1832
|
+
{ name: "method", value: method },
|
|
1833
|
+
{ name: "path", value: resolvedPath },
|
|
1834
|
+
{ name: "methods", value: arrayLiteral([method], writeValue) }
|
|
1835
|
+
];
|
|
1836
|
+
const manifestEntry = objectLiteral([
|
|
1837
|
+
...metadataEntries,
|
|
1838
|
+
{ name: "load", value: buildManifestApiLoader(importPath) }
|
|
1839
|
+
]);
|
|
1840
|
+
manifestApis.push(manifestEntry);
|
|
1841
|
+
manifestShardApis.push({ path: resolvedPath, declaration: renderGeneratedValue(manifestEntry) });
|
|
1842
|
+
metadataApis.push({ path: resolvedPath, declaration: renderGeneratedValue(objectLiteral(metadataEntries)) });
|
|
1691
1843
|
}
|
|
1692
1844
|
}
|
|
1693
1845
|
return {
|
|
@@ -1698,53 +1850,9 @@ async function processApiRoutes(options) {
|
|
|
1698
1850
|
metadataApis
|
|
1699
1851
|
};
|
|
1700
1852
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
const subscriberId = metadata?.id ?? id;
|
|
1705
|
-
subscribers.push(
|
|
1706
|
-
`{ id: ${toLiteral(subscriberId)}, event: ${toLiteral(metadata?.event ?? "")}, persistent: ${metadata?.persistent === void 0 ? "undefined" : toLiteral(metadata.persistent)}, sync: ${metadata?.sync === void 0 ? "undefined" : toLiteral(metadata.sync)}, priority: ${metadata?.priority === void 0 ? "undefined" : toLiteral(metadata.priority)}, handler: createLazyModuleSubscriber(() => ${buildDynamicImportExpression(importPath)}, ${toLiteral(subscriberId)}) }`
|
|
1707
|
-
);
|
|
1708
|
-
}
|
|
1709
|
-
return subscribers;
|
|
1710
|
-
}
|
|
1711
|
-
function processWorkers(discovered) {
|
|
1712
|
-
const workers = [];
|
|
1713
|
-
for (const { id, importPath, metadata } of discovered) {
|
|
1714
|
-
const workerId = metadata.id ?? id;
|
|
1715
|
-
workers.push(
|
|
1716
|
-
`{ id: ${toLiteral(workerId)}, queue: ${toLiteral(metadata.queue)}, concurrency: ${toLiteral(metadata.concurrency ?? 1)}${metadata.lockDuration === void 0 ? "" : `, lockDuration: ${toLiteral(metadata.lockDuration)}`}${metadata.maxStalledCount === void 0 ? "" : `, maxStalledCount: ${toLiteral(metadata.maxStalledCount)}`}, handler: createLazyModuleWorker(() => ${buildDynamicImportExpression(importPath)}, ${toLiteral(workerId)}) }`
|
|
1717
|
-
);
|
|
1718
|
-
}
|
|
1719
|
-
return workers;
|
|
1720
|
-
}
|
|
1721
|
-
function processTranslations(options) {
|
|
1722
|
-
const { discovered, modId, appImportBase, pkgImportBase, imports, extraImports } = options;
|
|
1723
|
-
const translations = [];
|
|
1724
|
-
for (const { locale, coreHas, appHas } of discovered) {
|
|
1725
|
-
if (coreHas && appHas) {
|
|
1726
|
-
const cName = `T_${toVar(modId)}_${toVar(locale)}_C`;
|
|
1727
|
-
const aName = `T_${toVar(modId)}_${toVar(locale)}_A`;
|
|
1728
|
-
imports.push(buildImportStatement(cName, `${pkgImportBase}/i18n/${locale}.json`));
|
|
1729
|
-
imports.push(buildImportStatement(aName, `${appImportBase}/i18n/${locale}.json`));
|
|
1730
|
-
extraImports?.push(buildImportStatement(cName, `${pkgImportBase}/i18n/${locale}.json`));
|
|
1731
|
-
extraImports?.push(buildImportStatement(aName, `${appImportBase}/i18n/${locale}.json`));
|
|
1732
|
-
translations.push(
|
|
1733
|
-
`'${locale}': { ...( ${cName} as unknown as Record<string,string> ), ...( ${aName} as unknown as Record<string,string> ) }`
|
|
1734
|
-
);
|
|
1735
|
-
} else if (appHas) {
|
|
1736
|
-
const aName = `T_${toVar(modId)}_${toVar(locale)}_A`;
|
|
1737
|
-
imports.push(buildImportStatement(aName, `${appImportBase}/i18n/${locale}.json`));
|
|
1738
|
-
extraImports?.push(buildImportStatement(aName, `${appImportBase}/i18n/${locale}.json`));
|
|
1739
|
-
translations.push(`'${locale}': ${aName} as unknown as Record<string,string>`);
|
|
1740
|
-
} else if (coreHas) {
|
|
1741
|
-
const cName = `T_${toVar(modId)}_${toVar(locale)}_C`;
|
|
1742
|
-
imports.push(buildImportStatement(cName, `${pkgImportBase}/i18n/${locale}.json`));
|
|
1743
|
-
extraImports?.push(buildImportStatement(cName, `${pkgImportBase}/i18n/${locale}.json`));
|
|
1744
|
-
translations.push(`'${locale}': ${cName} as unknown as Record<string,string>`);
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
return translations;
|
|
1853
|
+
const ABANDON_HOOK_FACTORY = "createLazyModuleWorkerAbandonHook";
|
|
1854
|
+
function workersDeclareAbandonHook(discovered) {
|
|
1855
|
+
return discovered.some(({ metadata }) => metadata.hasJobAbandonedHook === true);
|
|
1748
1856
|
}
|
|
1749
1857
|
function processStandaloneConfig(options) {
|
|
1750
1858
|
const {
|
|
@@ -1870,6 +1978,37 @@ function buildModuleDashboardWidgetsValue(entries) {
|
|
|
1870
1978
|
writeValue
|
|
1871
1979
|
);
|
|
1872
1980
|
}
|
|
1981
|
+
function preRenderedExpressionList(expressions) {
|
|
1982
|
+
return arrayLiteral(expressions.map((expression) => identifier(expression)), writeValue);
|
|
1983
|
+
}
|
|
1984
|
+
function legacyNamespaceMemberFallback(importName, members) {
|
|
1985
|
+
return parenthesized(nullishCoalesce([
|
|
1986
|
+
propertyAccess(identifier(importName), members[0]),
|
|
1987
|
+
propertyAccess(identifier(importName), members[1])
|
|
1988
|
+
]));
|
|
1989
|
+
}
|
|
1990
|
+
function buildLegacyModuleListValue(options) {
|
|
1991
|
+
return logicalOr([
|
|
1992
|
+
asExpression(legacyNamespaceMemberFallback(options.importName, options.members), options.castType),
|
|
1993
|
+
emptyArray()
|
|
1994
|
+
]);
|
|
1995
|
+
}
|
|
1996
|
+
function buildLegacyModuleSetupValue(importName) {
|
|
1997
|
+
return logicalOr([
|
|
1998
|
+
legacyNamespaceMemberFallback(importName, ["default", "setup"]),
|
|
1999
|
+
identifier("undefined")
|
|
2000
|
+
]);
|
|
2001
|
+
}
|
|
2002
|
+
function buildLegacyIntegrationListValue(importName, pluralMember, singularMember, castType) {
|
|
2003
|
+
const singular = propertyAccess(identifier(importName), singularMember);
|
|
2004
|
+
return asExpression(
|
|
2005
|
+
parenthesized(nullishCoalesce([
|
|
2006
|
+
propertyAccess(identifier(importName), pluralMember),
|
|
2007
|
+
parenthesized(conditionalExpression(singular, arrayLiteral([singular], writeValue), emptyArray()))
|
|
2008
|
+
])),
|
|
2009
|
+
castType
|
|
2010
|
+
);
|
|
2011
|
+
}
|
|
1873
2012
|
function buildModuleIntegrationListValue(importName, pluralMember, singularMember, castType) {
|
|
1874
2013
|
const plural = namespaceLookup(importName, pluralMember);
|
|
1875
2014
|
const singular = namespaceLookup(importName, singularMember);
|
|
@@ -1920,10 +2059,11 @@ function renderAstModuleRegistryFile(options) {
|
|
|
1920
2059
|
namedImports: [
|
|
1921
2060
|
{ name: "createLazyModuleSubscriber" },
|
|
1922
2061
|
{ name: "createLazyModuleWorker" },
|
|
2062
|
+
...options.includeAbandonHookImport ? [{ name: ABANDON_HOOK_FACTORY }] : [],
|
|
1923
2063
|
{ name: "Module", isTypeOnly: true }
|
|
1924
2064
|
]
|
|
1925
2065
|
});
|
|
1926
|
-
addImportStatements(sourceFile, options.imports);
|
|
2066
|
+
addImportStatements(sourceFile, options.imports.map((entry) => serializeGeneratedImport(entry)));
|
|
1927
2067
|
sourceFile.addVariableStatement({
|
|
1928
2068
|
declarationKind: VariableDeclarationKind.Const,
|
|
1929
2069
|
isExported: true,
|
|
@@ -1951,6 +2091,39 @@ function renderAstModuleRegistryFile(options) {
|
|
|
1951
2091
|
});
|
|
1952
2092
|
return getSourceText(sourceFile);
|
|
1953
2093
|
}
|
|
2094
|
+
function renderAstManifestFile(options) {
|
|
2095
|
+
const sourceFile = createGeneratedSourceFile(options.fileName);
|
|
2096
|
+
addAutoGeneratedComment(sourceFile, "registry");
|
|
2097
|
+
const usesPageRouteMetadataHelper = options.typeName === "FrontendRouteManifestEntry" || options.typeName === "BackendRouteManifestEntry";
|
|
2098
|
+
addImportSpec(sourceFile, usesPageRouteMetadataHelper ? {
|
|
2099
|
+
moduleSpecifier: "@open-mercato/shared/modules/registry",
|
|
2100
|
+
namedImports: [
|
|
2101
|
+
{ name: "resolvePageRouteMetadata" },
|
|
2102
|
+
{ name: options.typeName, isTypeOnly: true }
|
|
2103
|
+
]
|
|
2104
|
+
} : {
|
|
2105
|
+
moduleSpecifier: "@open-mercato/shared/modules/registry",
|
|
2106
|
+
isTypeOnly: true,
|
|
2107
|
+
namedImports: [{ name: options.typeName }]
|
|
2108
|
+
});
|
|
2109
|
+
addImportStatements(sourceFile, options.imports ?? []);
|
|
2110
|
+
sourceFile.addVariableStatement({
|
|
2111
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
2112
|
+
isExported: true,
|
|
2113
|
+
declarations: [
|
|
2114
|
+
{
|
|
2115
|
+
name: options.exportName,
|
|
2116
|
+
type: `${options.typeName}[]`,
|
|
2117
|
+
initializer: arrayLiteral(options.entries, writeValue)
|
|
2118
|
+
}
|
|
2119
|
+
]
|
|
2120
|
+
});
|
|
2121
|
+
sourceFile.addExportAssignment({
|
|
2122
|
+
isExportEquals: false,
|
|
2123
|
+
expression: options.exportName
|
|
2124
|
+
});
|
|
2125
|
+
return getSourceText(sourceFile);
|
|
2126
|
+
}
|
|
1954
2127
|
function renderAstLegacyAliasFile(options) {
|
|
1955
2128
|
const sourceFile = createGeneratedSourceFile(options.fileName);
|
|
1956
2129
|
addAutoGeneratedComment(sourceFile, "registry");
|
|
@@ -2001,42 +2174,9 @@ function renderEnabledModuleIdsFile(moduleIds) {
|
|
|
2001
2174
|
});
|
|
2002
2175
|
return getSourceText(sourceFile);
|
|
2003
2176
|
}
|
|
2004
|
-
function renderLegacyCompatibleArray(entries) {
|
|
2005
|
-
return `[
|
|
2006
|
-
${entries.join(",\n ")}
|
|
2007
|
-
]`;
|
|
2008
|
-
}
|
|
2009
2177
|
function buildLazyRouteComponentExpression(importPath) {
|
|
2010
2178
|
return `async (props: any) => { const mod = await ${buildDynamicImportExpression(importPath)}; const Component = (mod.default ?? mod) as any; return createElement(Component, props) }`;
|
|
2011
2179
|
}
|
|
2012
|
-
function renderAstLegacyModuleRegistryOutput(options) {
|
|
2013
|
-
const importSection = [
|
|
2014
|
-
...options.includeCreateElementImport ? ["import { createElement } from 'react'"] : [],
|
|
2015
|
-
"import { createLazyModuleSubscriber, createLazyModuleWorker, type Module } from '@open-mercato/shared/modules/registry'",
|
|
2016
|
-
...options.imports.map((entry) => serializeGeneratedImport(entry))
|
|
2017
|
-
].join("\n");
|
|
2018
|
-
return `// AUTO-GENERATED by mercato generate registry
|
|
2019
|
-
${importSection}
|
|
2020
|
-
|
|
2021
|
-
export const modules: Module[] = ${renderLegacyCompatibleArray(options.moduleEntries)}
|
|
2022
|
-
export const modulesInfo = modules.map(m => ({ id: m.id, ...(m.info || {}) }))
|
|
2023
|
-
export default modules
|
|
2024
|
-
`;
|
|
2025
|
-
}
|
|
2026
|
-
function renderAstLegacyManifestOutput(options) {
|
|
2027
|
-
const usesPageRouteMetadataHelper = options.typeName === "FrontendRouteManifestEntry" || options.typeName === "BackendRouteManifestEntry";
|
|
2028
|
-
const importSection = [
|
|
2029
|
-
usesPageRouteMetadataHelper ? `import { resolvePageRouteMetadata, type ${options.typeName} } from '@open-mercato/shared/modules/registry'` : `import type { ${options.typeName} } from '@open-mercato/shared/modules/registry'`,
|
|
2030
|
-
...(options.imports ?? []).map((entry) => serializeGeneratedImport(entry))
|
|
2031
|
-
].join("\n");
|
|
2032
|
-
return `// AUTO-GENERATED by mercato generate registry
|
|
2033
|
-
${importSection}
|
|
2034
|
-
|
|
2035
|
-
export const ${options.exportName}: ${options.typeName}[] = ${renderLegacyCompatibleArray(options.entries)}
|
|
2036
|
-
|
|
2037
|
-
export default ${options.exportName}
|
|
2038
|
-
`;
|
|
2039
|
-
}
|
|
2040
2180
|
function buildRuntimeRouteComponent(importPath) {
|
|
2041
2181
|
return arrowFunction({
|
|
2042
2182
|
async: true,
|
|
@@ -2277,8 +2417,17 @@ function processWorkersAst(discovered) {
|
|
|
2277
2417
|
{ name: "id", value: workerId },
|
|
2278
2418
|
{ name: "queue", value: metadata.queue },
|
|
2279
2419
|
{ name: "concurrency", value: metadata.concurrency ?? 1 },
|
|
2420
|
+
...metadata.schedulerSafe === true ? [{ name: "schedulerSafe", value: true }] : [],
|
|
2421
|
+
...metadata.schedulerRequiredFeatures ? [{ name: "schedulerRequiredFeatures", value: arrayLiteral(metadata.schedulerRequiredFeatures, writeValue) }] : [],
|
|
2280
2422
|
...metadata.lockDuration === void 0 ? [] : [{ name: "lockDuration", value: metadata.lockDuration }],
|
|
2281
2423
|
...metadata.maxStalledCount === void 0 ? [] : [{ name: "maxStalledCount", value: metadata.maxStalledCount }],
|
|
2424
|
+
...metadata.hasJobAbandonedHook ? [{
|
|
2425
|
+
name: "onJobAbandoned",
|
|
2426
|
+
value: callExpression(identifier(ABANDON_HOOK_FACTORY), [
|
|
2427
|
+
arrowFunction({ body: importExpression(importPath) }),
|
|
2428
|
+
workerId
|
|
2429
|
+
])
|
|
2430
|
+
}] : [],
|
|
2282
2431
|
{
|
|
2283
2432
|
name: "handler",
|
|
2284
2433
|
value: callExpression(identifier("createLazyModuleWorker"), [
|
|
@@ -2588,6 +2737,7 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2588
2737
|
const requiresByModule = /* @__PURE__ */ new Map();
|
|
2589
2738
|
const commandLoaderEntries = [];
|
|
2590
2739
|
let hasRouteComponents = false;
|
|
2740
|
+
let hasAbandonHookWorkers = false;
|
|
2591
2741
|
const umesConflictSources = [];
|
|
2592
2742
|
const seenBackendRoutePatterns = /* @__PURE__ */ new Map();
|
|
2593
2743
|
for (const discovered of discovery.modules) {
|
|
@@ -2782,7 +2932,7 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2782
2932
|
cliImportName = importName;
|
|
2783
2933
|
}
|
|
2784
2934
|
}
|
|
2785
|
-
translations.push(...
|
|
2935
|
+
translations.push(...processTranslationsAst({
|
|
2786
2936
|
discovered: discovered.translations,
|
|
2787
2937
|
modId,
|
|
2788
2938
|
appImportBase,
|
|
@@ -2790,8 +2940,10 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2790
2940
|
imports,
|
|
2791
2941
|
extraImports: runtimeImports
|
|
2792
2942
|
}));
|
|
2793
|
-
subscribers.push(...
|
|
2794
|
-
|
|
2943
|
+
subscribers.push(...processSubscribersAst(await discovered.getSubscribers()));
|
|
2944
|
+
const discoveredWorkersForModule = await discovered.getWorkers();
|
|
2945
|
+
if (workersDeclareAbandonHook(discoveredWorkersForModule)) hasAbandonHookWorkers = true;
|
|
2946
|
+
workers.push(...processWorkersAst(discoveredWorkersForModule));
|
|
2795
2947
|
{
|
|
2796
2948
|
const parts = [];
|
|
2797
2949
|
if (fieldsImportName)
|
|
@@ -2809,44 +2961,116 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2809
2961
|
);
|
|
2810
2962
|
}
|
|
2811
2963
|
}
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2964
|
+
const identityEntries = [{ name: "id", value: modId }];
|
|
2965
|
+
if (infoImportName) {
|
|
2966
|
+
identityEntries.push({ name: "info", value: propertyAccess(identifier(infoImportName), "metadata") });
|
|
2967
|
+
}
|
|
2968
|
+
const sharedTailEntries = [];
|
|
2969
|
+
if (translations.length > 0) {
|
|
2970
|
+
sharedTailEntries.push({ name: "translations", value: objectLiteral(translations) });
|
|
2971
|
+
}
|
|
2972
|
+
if (subscribers.length > 0) {
|
|
2973
|
+
sharedTailEntries.push({ name: "subscribers", value: arrayLiteral(subscribers, writeValue) });
|
|
2974
|
+
}
|
|
2975
|
+
if (workers.length > 0) {
|
|
2976
|
+
sharedTailEntries.push({ name: "workers", value: arrayLiteral(workers, writeValue) });
|
|
2977
|
+
}
|
|
2978
|
+
if (extensionsImportName) {
|
|
2979
|
+
sharedTailEntries.push({
|
|
2980
|
+
name: "entityExtensions",
|
|
2981
|
+
value: buildLegacyModuleListValue({
|
|
2982
|
+
importName: extensionsImportName,
|
|
2983
|
+
members: ["default", "extensions"],
|
|
2984
|
+
castType: "import('@open-mercato/shared/modules/entities').EntityExtension[]"
|
|
2985
|
+
})
|
|
2986
|
+
});
|
|
2987
|
+
}
|
|
2988
|
+
sharedTailEntries.push({ name: "customFieldSets", value: identifier(customFieldSetsExpr) });
|
|
2989
|
+
if (featuresImportName) {
|
|
2990
|
+
sharedTailEntries.push({
|
|
2991
|
+
name: "features",
|
|
2992
|
+
value: buildLegacyModuleListValue({
|
|
2993
|
+
importName: featuresImportName,
|
|
2994
|
+
members: ["default", "features"],
|
|
2995
|
+
castType: "any"
|
|
2996
|
+
})
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2999
|
+
if (customEntitiesImportName) {
|
|
3000
|
+
sharedTailEntries.push({
|
|
3001
|
+
name: "customEntities",
|
|
3002
|
+
value: buildLegacyModuleListValue({
|
|
3003
|
+
importName: customEntitiesImportName,
|
|
3004
|
+
members: ["default", "entities"],
|
|
3005
|
+
castType: "any"
|
|
3006
|
+
})
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
const setupAndBeyondEntries = [];
|
|
3010
|
+
if (setupImportName) {
|
|
3011
|
+
setupAndBeyondEntries.push({ name: "setup", value: buildLegacyModuleSetupValue(setupImportName) });
|
|
3012
|
+
}
|
|
3013
|
+
if (encryptionImportName) {
|
|
3014
|
+
setupAndBeyondEntries.push({
|
|
3015
|
+
name: "defaultEncryptionMaps",
|
|
3016
|
+
value: buildLegacyModuleListValue({
|
|
3017
|
+
importName: encryptionImportName,
|
|
3018
|
+
members: ["default", "defaultEncryptionMaps"],
|
|
3019
|
+
castType: "import('@open-mercato/shared/modules/encryption').ModuleEncryptionMap[]"
|
|
3020
|
+
})
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
if (integrationExports) {
|
|
3024
|
+
setupAndBeyondEntries.push({
|
|
3025
|
+
name: "integrations",
|
|
3026
|
+
value: buildLegacyIntegrationListValue(
|
|
3027
|
+
integrationExports,
|
|
3028
|
+
"integrations",
|
|
3029
|
+
"integration",
|
|
3030
|
+
"import('@open-mercato/shared/modules/integrations/types').IntegrationDefinition[]"
|
|
3031
|
+
)
|
|
3032
|
+
});
|
|
3033
|
+
setupAndBeyondEntries.push({
|
|
3034
|
+
name: "bundles",
|
|
3035
|
+
value: buildLegacyIntegrationListValue(
|
|
3036
|
+
integrationExports,
|
|
3037
|
+
"bundles",
|
|
3038
|
+
"bundle",
|
|
3039
|
+
"import('@open-mercato/shared/modules/integrations/types').IntegrationBundle[]"
|
|
3040
|
+
)
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
const eagerEntries = [...identityEntries];
|
|
3044
|
+
if (frontendRoutes.length > 0) {
|
|
3045
|
+
eagerEntries.push({ name: "frontendRoutes", value: preRenderedExpressionList(frontendRoutes) });
|
|
3046
|
+
}
|
|
3047
|
+
if (backendRoutes.length > 0) {
|
|
3048
|
+
eagerEntries.push({ name: "backendRoutes", value: preRenderedExpressionList(backendRoutes) });
|
|
3049
|
+
}
|
|
3050
|
+
if (apis.length > 0) {
|
|
3051
|
+
eagerEntries.push({ name: "apis", value: preRenderedExpressionList(apis) });
|
|
3052
|
+
}
|
|
3053
|
+
if (cliImportName) {
|
|
3054
|
+
eagerEntries.push({ name: "cli", value: identifier(cliImportName) });
|
|
3055
|
+
}
|
|
3056
|
+
eagerEntries.push(...sharedTailEntries);
|
|
3057
|
+
if (dashboardWidgets.length > 0) {
|
|
3058
|
+
eagerEntries.push({ name: "dashboardWidgets", value: preRenderedExpressionList(dashboardWidgets) });
|
|
3059
|
+
}
|
|
3060
|
+
eagerEntries.push(...setupAndBeyondEntries);
|
|
3061
|
+
moduleDecls.push(objectLiteral(eagerEntries));
|
|
3062
|
+
const runtimeEntries = [...identityEntries];
|
|
3063
|
+
if (runtimeFrontendRoutes.length > 0) {
|
|
3064
|
+
runtimeEntries.push({ name: "frontendRoutes", value: preRenderedExpressionList(runtimeFrontendRoutes) });
|
|
3065
|
+
}
|
|
3066
|
+
if (runtimeBackendRoutes.length > 0) {
|
|
3067
|
+
runtimeEntries.push({ name: "backendRoutes", value: preRenderedExpressionList(runtimeBackendRoutes) });
|
|
3068
|
+
}
|
|
3069
|
+
if (runtimeApis.length > 0) {
|
|
3070
|
+
runtimeEntries.push({ name: "apis", value: preRenderedExpressionList(runtimeApis) });
|
|
3071
|
+
}
|
|
3072
|
+
runtimeEntries.push(...sharedTailEntries, ...setupAndBeyondEntries);
|
|
3073
|
+
runtimeModuleDecls.push(objectLiteral(runtimeEntries));
|
|
2850
3074
|
}
|
|
2851
3075
|
{
|
|
2852
3076
|
const { detectConflicts } = await import("@open-mercato/shared/lib/umes/conflict-detection");
|
|
@@ -2939,33 +3163,37 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
2939
3163
|
);
|
|
2940
3164
|
}
|
|
2941
3165
|
}
|
|
2942
|
-
const output =
|
|
3166
|
+
const output = renderAstModuleRegistryFile({
|
|
2943
3167
|
fileName: "modules.generated.ts",
|
|
3168
|
+
generator: "registry",
|
|
2944
3169
|
imports,
|
|
2945
3170
|
moduleEntries: moduleDecls,
|
|
2946
|
-
includeCreateElementImport: hasRouteComponents
|
|
3171
|
+
includeCreateElementImport: hasRouteComponents,
|
|
3172
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
2947
3173
|
});
|
|
2948
|
-
const runtimeOutput =
|
|
3174
|
+
const runtimeOutput = renderAstModuleRegistryFile({
|
|
2949
3175
|
fileName: "modules.runtime.generated.ts",
|
|
3176
|
+
generator: "registry",
|
|
2950
3177
|
imports: runtimeImports,
|
|
2951
3178
|
moduleEntries: runtimeModuleDecls,
|
|
2952
|
-
includeCreateElementImport: true
|
|
3179
|
+
includeCreateElementImport: true,
|
|
3180
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
2953
3181
|
});
|
|
2954
|
-
const frontendRoutesOutput =
|
|
3182
|
+
const frontendRoutesOutput = renderAstManifestFile({
|
|
2955
3183
|
fileName: "frontend-routes.generated.ts",
|
|
2956
3184
|
typeName: "FrontendRouteManifestEntry",
|
|
2957
3185
|
exportName: "frontendRoutes",
|
|
2958
3186
|
imports: frontendRouteManifestImports,
|
|
2959
3187
|
entries: frontendRouteManifestDecls
|
|
2960
3188
|
});
|
|
2961
|
-
const backendRoutesOutput =
|
|
3189
|
+
const backendRoutesOutput = renderAstManifestFile({
|
|
2962
3190
|
fileName: "backend-routes.generated.ts",
|
|
2963
3191
|
typeName: "BackendRouteManifestEntry",
|
|
2964
3192
|
exportName: "backendRoutes",
|
|
2965
3193
|
imports: backendRouteManifestImports,
|
|
2966
3194
|
entries: backendRouteManifestDecls
|
|
2967
3195
|
});
|
|
2968
|
-
const apiRoutesOutput =
|
|
3196
|
+
const apiRoutesOutput = renderAstManifestFile({
|
|
2969
3197
|
fileName: "api-routes.generated.ts",
|
|
2970
3198
|
typeName: "ApiRouteManifestEntry",
|
|
2971
3199
|
exportName: "apiRoutes",
|
|
@@ -3092,16 +3320,11 @@ async function generateModuleRegistryFromDiscovery(options) {
|
|
|
3092
3320
|
allRegImports.push(...reg.registrationImports);
|
|
3093
3321
|
allCalls.push(reg.buildCall(reg.entriesExportName));
|
|
3094
3322
|
}
|
|
3095
|
-
const
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
` : ""}
|
|
3101
|
-
export function runBootstrapRegistrations(): void {
|
|
3102
|
-
${body}
|
|
3103
|
-
}
|
|
3104
|
-
`;
|
|
3323
|
+
const bootstrapRegsOutput = renderBootstrapRegistrationsFile({
|
|
3324
|
+
entryImports: allEntryImports,
|
|
3325
|
+
registrationImports: allRegImports,
|
|
3326
|
+
calls: allCalls
|
|
3327
|
+
});
|
|
3105
3328
|
writeGeneratedFile({ outFile: bootstrapRegsOutFile, checksumFile: bootstrapRegsChecksumFile, content: bootstrapRegsOutput, structureChecksum, result, quiet });
|
|
3106
3329
|
}
|
|
3107
3330
|
return result;
|
|
@@ -3137,6 +3360,7 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
3137
3360
|
const requiresByModule = /* @__PURE__ */ new Map();
|
|
3138
3361
|
const commandLoaderEntries = [];
|
|
3139
3362
|
let hasRouteComponents = false;
|
|
3363
|
+
let hasAbandonHookWorkers = false;
|
|
3140
3364
|
const seenBackendRoutePatterns = /* @__PURE__ */ new Map();
|
|
3141
3365
|
for (const discovered of discovery.modules) {
|
|
3142
3366
|
const { modId, roots, imps, appImportBase } = discovered;
|
|
@@ -3282,7 +3506,9 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
3282
3506
|
i18nLocaleShards.set(locale, shard);
|
|
3283
3507
|
}
|
|
3284
3508
|
subscribers.push(...processSubscribersAst(await discovered.getSubscribers()));
|
|
3285
|
-
|
|
3509
|
+
const discoveredWorkersForModule = await discovered.getWorkers();
|
|
3510
|
+
if (workersDeclareAbandonHook(discoveredWorkersForModule)) hasAbandonHookWorkers = true;
|
|
3511
|
+
workers.push(...processWorkersAst(discoveredWorkersForModule));
|
|
3286
3512
|
{
|
|
3287
3513
|
dashboardWidgetsValue = buildModuleDashboardWidgetsValue(discovered.dashboardWidgetEntries);
|
|
3288
3514
|
}
|
|
@@ -3399,19 +3625,22 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
3399
3625
|
generator: "registry (app version)",
|
|
3400
3626
|
imports,
|
|
3401
3627
|
moduleEntries: moduleDecls,
|
|
3402
|
-
includeCreateElementImport: hasRouteComponents
|
|
3628
|
+
includeCreateElementImport: hasRouteComponents,
|
|
3629
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
3403
3630
|
});
|
|
3404
3631
|
const bootstrapOutput = renderAstModuleRegistryFile({
|
|
3405
3632
|
fileName: "modules.bootstrap.generated.ts",
|
|
3406
3633
|
generator: "registry (bootstrap version)",
|
|
3407
3634
|
imports: bootstrapImports,
|
|
3408
|
-
moduleEntries: bootstrapModuleDecls
|
|
3635
|
+
moduleEntries: bootstrapModuleDecls,
|
|
3636
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
3409
3637
|
});
|
|
3410
3638
|
const i18nOutput = renderAstModuleRegistryFile({
|
|
3411
3639
|
fileName: "modules.i18n.generated.ts",
|
|
3412
3640
|
generator: "registry (i18n version)",
|
|
3413
3641
|
imports: i18nImports,
|
|
3414
|
-
moduleEntries: i18nModuleDecls
|
|
3642
|
+
moduleEntries: i18nModuleDecls,
|
|
3643
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
3415
3644
|
});
|
|
3416
3645
|
const legacyOutput = renderAstLegacyAliasFile({
|
|
3417
3646
|
fileName: "bootstrap-modules.generated.ts",
|
|
@@ -3486,6 +3715,7 @@ async function generateModuleRegistryAppFromDiscovery(options) {
|
|
|
3486
3715
|
return result;
|
|
3487
3716
|
}
|
|
3488
3717
|
async function generateModuleRegistryCliFromDiscovery(options) {
|
|
3718
|
+
let hasAbandonHookWorkers = false;
|
|
3489
3719
|
const { resolver, quiet = false } = options;
|
|
3490
3720
|
const { discovery } = options;
|
|
3491
3721
|
const result = createGeneratorResult();
|
|
@@ -3604,6 +3834,7 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3604
3834
|
subscribers.push(...processSubscribersAst(await discovered.getSubscribers()));
|
|
3605
3835
|
const discoveredWorkers = await discovered.getWorkers();
|
|
3606
3836
|
const workerGenerationEntries = collectWorkerGenerationEntries(discoveredWorkers, modId);
|
|
3837
|
+
if (workersDeclareAbandonHook(discoveredWorkers)) hasAbandonHookWorkers = true;
|
|
3607
3838
|
workers.push(...processWorkersAst(discoveredWorkers));
|
|
3608
3839
|
devSupervisorWorkers.push(...workerGenerationEntries.map(({ importPath: _importPath, ...worker }) => worker));
|
|
3609
3840
|
{
|
|
@@ -3720,7 +3951,8 @@ async function generateModuleRegistryCliFromDiscovery(options) {
|
|
|
3720
3951
|
fileName: "modules.cli.generated.ts",
|
|
3721
3952
|
generator: "registry (CLI version)",
|
|
3722
3953
|
imports,
|
|
3723
|
-
moduleEntries: moduleDecls
|
|
3954
|
+
moduleEntries: moduleDecls,
|
|
3955
|
+
includeAbandonHookImport: hasAbandonHookWorkers
|
|
3724
3956
|
});
|
|
3725
3957
|
const legacyOutput = renderAstLegacyAliasFile({
|
|
3726
3958
|
fileName: "cli-modules.generated.ts",
|
|
@@ -3806,6 +4038,9 @@ export {
|
|
|
3806
4038
|
generateModuleRegistryApp,
|
|
3807
4039
|
generateModuleRegistryCli,
|
|
3808
4040
|
hasNamedExport,
|
|
4041
|
+
namedObjectLiteralDeclaresProperty,
|
|
4042
|
+
renderBootstrapRegistrationsFile,
|
|
4043
|
+
renderCommandLoadersFile,
|
|
3809
4044
|
resetConventionWarnings,
|
|
3810
4045
|
resolveNamedObjectExport,
|
|
3811
4046
|
warnIfPageMetaMissingMetadataExport,
|