@open-mercato/shared 0.6.7 → 0.6.8-canary.320.1.bf889f49e4
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 +1 -1
- package/AGENTS.md +62 -6
- package/build.mjs +2 -4
- package/dist/lib/ai/safety-identifier.js +32 -0
- package/dist/lib/ai/safety-identifier.js.map +7 -0
- package/dist/lib/auth/organizationScope.js +34 -0
- package/dist/lib/auth/organizationScope.js.map +7 -0
- package/dist/lib/auth/server.js +15 -2
- package/dist/lib/auth/server.js.map +2 -2
- package/dist/lib/bootstrap/clientOnlyModules.js +55 -0
- package/dist/lib/bootstrap/clientOnlyModules.js.map +7 -0
- package/dist/lib/bootstrap/dynamicLoader.js +190 -70
- package/dist/lib/bootstrap/dynamicLoader.js.map +2 -2
- package/dist/lib/bootstrap/factory.js +18 -13
- package/dist/lib/bootstrap/factory.js.map +2 -2
- package/dist/lib/commands/command-bus.js +9 -3
- package/dist/lib/commands/command-bus.js.map +2 -2
- package/dist/lib/commands/command-interceptor-runner.js +9 -4
- package/dist/lib/commands/command-interceptor-runner.js.map +2 -2
- package/dist/lib/commands/errors.js +25 -4
- package/dist/lib/commands/errors.js.map +2 -2
- package/dist/lib/commands/index.js +7 -1
- package/dist/lib/commands/index.js.map +2 -2
- package/dist/lib/crud/enricher-runner.js +2 -11
- package/dist/lib/crud/enricher-runner.js.map +2 -2
- package/dist/lib/crud/factory.js +104 -23
- package/dist/lib/crud/factory.js.map +2 -2
- package/dist/lib/crud/interceptor-runner.js +2 -2
- package/dist/lib/crud/interceptor-runner.js.map +2 -2
- package/dist/lib/crud/mutation-guard-registry.js +2 -2
- package/dist/lib/crud/mutation-guard-registry.js.map +2 -2
- package/dist/lib/crud/types.js +4 -0
- package/dist/lib/crud/types.js.map +3 -3
- package/dist/lib/data/consistency.js +19 -0
- package/dist/lib/data/consistency.js.map +7 -0
- package/dist/lib/data/engine.js +37 -11
- package/dist/lib/data/engine.js.map +2 -2
- package/dist/lib/db/entityMetadata.js +26 -0
- package/dist/lib/db/entityMetadata.js.map +7 -0
- package/dist/lib/db/pg-errors.js +42 -0
- package/dist/lib/db/pg-errors.js.map +2 -2
- package/dist/lib/di/container.js +48 -6
- package/dist/lib/di/container.js.map +2 -2
- package/dist/lib/email/send.js +56 -0
- package/dist/lib/email/send.js.map +2 -2
- package/dist/lib/encryption/find.js +22 -0
- package/dist/lib/encryption/find.js.map +2 -2
- package/dist/lib/encryption/likeFilterWarning.js +66 -0
- package/dist/lib/encryption/likeFilterWarning.js.map +7 -0
- package/dist/lib/encryption/subscriber.js +2 -10
- package/dist/lib/encryption/subscriber.js.map +2 -2
- package/dist/lib/encryption/tenantDataEncryptionService.js +52 -17
- package/dist/lib/encryption/tenantDataEncryptionService.js.map +2 -2
- package/dist/lib/i18n/config.js +1 -1
- package/dist/lib/i18n/config.js.map +2 -2
- package/dist/lib/i18n/dictionary-cache.js +5 -0
- package/dist/lib/i18n/dictionary-cache.js.map +2 -2
- package/dist/lib/i18n/server.js +4 -4
- package/dist/lib/i18n/server.js.map +3 -3
- package/dist/lib/logger/extension.js +29 -0
- package/dist/lib/logger/extension.js.map +7 -0
- package/dist/lib/logger/index.js +47 -3
- package/dist/lib/logger/index.js.map +3 -3
- package/dist/lib/modules/registry.js +36 -6
- package/dist/lib/modules/registry.js.map +2 -2
- package/dist/lib/modules/surfaceFingerprint.js +47 -0
- package/dist/lib/modules/surfaceFingerprint.js.map +7 -0
- package/dist/lib/query/ciphertext-search-warning.js +51 -0
- package/dist/lib/query/ciphertext-search-warning.js.map +7 -0
- package/dist/lib/query/engine.js +60 -43
- package/dist/lib/query/engine.js.map +2 -2
- package/dist/lib/query/types.js.map +1 -1
- package/dist/lib/redis/connection.js +7 -2
- package/dist/lib/redis/connection.js.map +2 -2
- package/dist/lib/search/auto-indexing.js +14 -0
- package/dist/lib/search/auto-indexing.js.map +7 -0
- package/dist/lib/search/availability.js +107 -0
- package/dist/lib/search/availability.js.map +7 -0
- package/dist/lib/search/config.js +61 -2
- package/dist/lib/search/config.js.map +2 -2
- package/dist/lib/search/tokenLookup.js +46 -0
- package/dist/lib/search/tokenLookup.js.map +7 -0
- package/dist/lib/search/tokenize.js +23 -11
- package/dist/lib/search/tokenize.js.map +2 -2
- package/dist/lib/telemetry/runtime.js +35 -0
- package/dist/lib/telemetry/runtime.js.map +7 -0
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/webhooks/body.js +57 -0
- package/dist/lib/webhooks/body.js.map +7 -0
- package/dist/lib/webhooks/inbound-types.js +1 -0
- package/dist/lib/webhooks/inbound-types.js.map +7 -0
- package/dist/lib/webhooks/index.js +13 -1
- package/dist/lib/webhooks/index.js.map +2 -2
- package/dist/lib/webhooks/verify.js +12 -7
- package/dist/lib/webhooks/verify.js.map +2 -2
- package/dist/modules/analytics.js.map +2 -2
- package/dist/modules/overrides.js +50 -1
- package/dist/modules/overrides.js.map +2 -2
- package/dist/modules/payment_gateways/types.js +8 -1
- package/dist/modules/payment_gateways/types.js.map +2 -2
- package/dist/modules/registry.js +1 -0
- package/dist/modules/registry.js.map +2 -2
- package/dist/modules/widgets/extension-points.js +96 -0
- package/dist/modules/widgets/extension-points.js.map +7 -0
- package/dist/security/enabledModulesRegistry.js +56 -11
- package/dist/security/enabledModulesRegistry.js.map +2 -2
- package/dist/security/featurePolicy.js +62 -0
- package/dist/security/featurePolicy.js.map +7 -0
- package/jest.config.cjs +20 -10
- package/package.json +19 -9
- package/scripts/versionSource.cjs +65 -0
- package/src/lib/__tests__/versionSource.test.ts +64 -0
- package/src/lib/ai/__tests__/llm-provider-contract.test.ts +59 -0
- package/src/lib/ai/__tests__/safety-identifier.test.ts +71 -0
- package/src/lib/ai/llm-provider.ts +33 -0
- package/src/lib/ai/safety-identifier.ts +73 -0
- package/src/lib/auth/__tests__/organizationScope.test.ts +107 -0
- package/src/lib/auth/__tests__/server.test.ts +23 -0
- package/src/lib/auth/organizationScope.ts +65 -0
- package/src/lib/auth/server.ts +23 -2
- package/src/lib/bootstrap/__tests__/clientOnlyModules.test.ts +189 -0
- package/src/lib/bootstrap/__tests__/dynamicLoader.aliasResolver.test.ts +98 -0
- package/src/lib/bootstrap/__tests__/dynamicLoader.appDi.test.ts +211 -0
- package/src/lib/bootstrap/__tests__/dynamicLoader.commandInterceptors.test.ts +63 -8
- package/src/lib/bootstrap/__tests__/dynamicLoader.generatedCacheRecovery.test.ts +256 -0
- package/src/lib/bootstrap/__tests__/dynamicLoader.test.ts +126 -0
- package/src/lib/bootstrap/__tests__/dynamicLoader.tsconfig.test.ts +21 -1
- package/src/lib/bootstrap/__tests__/factory.test.ts +78 -0
- package/src/lib/bootstrap/clientOnlyModules.ts +85 -0
- package/src/lib/bootstrap/dynamicLoader.ts +346 -96
- package/src/lib/bootstrap/factory.ts +21 -15
- package/src/lib/bootstrap/types.ts +6 -0
- package/src/lib/commands/__tests__/command-bus.test.ts +63 -0
- package/src/lib/commands/__tests__/command-interceptor-error.test.ts +91 -1
- package/src/lib/commands/__tests__/command-interceptor-runner.test.ts +101 -0
- package/src/lib/commands/command-bus.ts +9 -3
- package/src/lib/commands/command-interceptor-runner.ts +27 -6
- package/src/lib/commands/command-interceptor.ts +8 -0
- package/src/lib/commands/errors.ts +67 -2
- package/src/lib/commands/index.ts +7 -1
- package/src/lib/crud/__tests__/crud-factory.cache-user-scope.test.ts +171 -0
- package/src/lib/crud/__tests__/crud-factory.test.ts +564 -0
- package/src/lib/crud/__tests__/mutation-guard-registry.test.ts +26 -0
- package/src/lib/crud/enricher-runner.ts +2 -11
- package/src/lib/crud/factory.ts +157 -22
- package/src/lib/crud/interceptor-runner.ts +2 -2
- package/src/lib/crud/mutation-guard-registry.ts +2 -2
- package/src/lib/crud/types.ts +3 -0
- package/src/lib/data/__tests__/consistency.test.ts +38 -0
- package/src/lib/data/__tests__/engine.bulk-suppress.test.ts +18 -3
- package/src/lib/data/consistency.ts +17 -0
- package/src/lib/data/engine.ts +50 -16
- package/src/lib/db/__tests__/entityMetadata.test.ts +38 -0
- package/src/lib/db/__tests__/pg-errors.test.ts +48 -0
- package/src/lib/db/entityMetadata.ts +43 -0
- package/src/lib/db/pg-errors.ts +58 -0
- package/src/lib/di/__tests__/container-app-di-absent.test.ts +155 -0
- package/src/lib/di/__tests__/container-app-di.test.ts +173 -0
- package/src/lib/di/__tests__/registrar-error-log.test.ts +154 -0
- package/src/lib/di/container.ts +72 -8
- package/src/lib/email/__tests__/send.test.ts +37 -1
- package/src/lib/email/send.ts +79 -0
- package/src/lib/encryption/__tests__/likeFilterWarning.test.ts +167 -0
- package/src/lib/encryption/__tests__/subscriber.test.ts +54 -2
- package/src/lib/encryption/__tests__/tenantDataEncryptionService.test.ts +58 -0
- package/src/lib/encryption/find.ts +22 -0
- package/src/lib/encryption/likeFilterWarning.ts +102 -0
- package/src/lib/encryption/subscriber.ts +2 -14
- package/src/lib/encryption/tenantDataEncryptionService.ts +64 -18
- package/src/lib/i18n/__tests__/config.test.ts +8 -0
- package/src/lib/i18n/__tests__/dictionary-cache.test.ts +23 -0
- package/src/lib/i18n/__tests__/server-dictionary-cache.test.ts +30 -0
- package/src/lib/i18n/__tests__/server-unbootstrapped.test.ts +29 -0
- package/src/lib/i18n/config.ts +2 -2
- package/src/lib/i18n/dictionary-cache.ts +5 -0
- package/src/lib/i18n/server.ts +6 -2
- package/src/lib/logger/__tests__/logger.test.ts +77 -0
- package/src/lib/logger/extension.ts +59 -0
- package/src/lib/logger/index.ts +59 -1
- package/src/lib/modules/__tests__/registry.test.ts +26 -0
- package/src/lib/modules/__tests__/surfaceFingerprint.test.ts +122 -0
- package/src/lib/modules/registry.ts +46 -7
- package/src/lib/modules/surfaceFingerprint.ts +87 -0
- package/src/lib/query/__tests__/ciphertext-search-warning.test.ts +178 -0
- package/src/lib/query/__tests__/engine.scope-and-or.test.ts +67 -0
- package/src/lib/query/__tests__/engine.test.ts +213 -13
- package/src/lib/query/ciphertext-search-warning.ts +106 -0
- package/src/lib/query/engine.ts +102 -61
- package/src/lib/query/types.ts +4 -5
- package/src/lib/redis/__tests__/connection.test.ts +16 -0
- package/src/lib/redis/connection.ts +10 -7
- package/src/lib/search/__tests__/availability.test.ts +211 -0
- package/src/lib/search/__tests__/config.test.ts +177 -0
- package/src/lib/search/__tests__/tokenLookup.test.ts +206 -0
- package/src/lib/search/__tests__/tokenize.test.ts +49 -0
- package/src/lib/search/auto-indexing.ts +22 -0
- package/src/lib/search/availability.ts +232 -0
- package/src/lib/search/config.ts +106 -8
- package/src/lib/search/tokenLookup.ts +133 -0
- package/src/lib/search/tokenize.ts +33 -11
- package/src/lib/telemetry/runtime.ts +72 -0
- package/src/lib/webhooks/__tests__/body.test.ts +95 -0
- package/src/lib/webhooks/__tests__/verify.test.ts +20 -1
- package/src/lib/webhooks/body.ts +70 -0
- package/src/lib/webhooks/inbound-types.ts +125 -0
- package/src/lib/webhooks/index.ts +19 -1
- package/src/lib/webhooks/verify.ts +17 -9
- package/src/modules/__tests__/nav-group-order-override.test.ts +183 -0
- package/src/modules/__tests__/registry.test.ts +10 -2
- package/src/modules/analytics.ts +7 -0
- package/src/modules/customer-auth.ts +1 -0
- package/src/modules/encryption.ts +3 -0
- package/src/modules/entities.ts +15 -0
- package/src/modules/navigation/backendChrome.ts +15 -0
- package/src/modules/overrides.ts +103 -0
- package/src/modules/payment_gateways/__tests__/types.test.ts +37 -0
- package/src/modules/payment_gateways/types.ts +41 -0
- package/src/modules/registry.ts +3 -0
- package/src/modules/widgets/__tests__/extension-points.test.ts +101 -0
- package/src/modules/widgets/extension-points.ts +524 -0
- package/src/security/__tests__/featurePolicy.test.ts +166 -0
- package/src/security/enabledModulesRegistry.ts +64 -12
- package/src/security/featurePolicy.ts +89 -0
|
@@ -1,14 +1,92 @@
|
|
|
1
1
|
import { findAppRoot } from "./appResolver.js";
|
|
2
2
|
import { registerEntityIds } from "../encryption/entityIds.js";
|
|
3
|
+
import { createLogger } from "../logger/index.js";
|
|
3
4
|
import {
|
|
4
5
|
ensureMikroOrmV7GeneratedCacheCompatibility,
|
|
5
6
|
recoverMikroOrmV7GeneratedCacheFromImportError
|
|
6
7
|
} from "./generatedCacheRecovery.js";
|
|
8
|
+
import { CLIENT_ONLY_STUB_NAMESPACE, createClientOnlyStubPlugin } from "./clientOnlyModules.js";
|
|
7
9
|
import path from "node:path";
|
|
8
10
|
import fs from "node:fs";
|
|
9
11
|
import crypto from "node:crypto";
|
|
10
12
|
import { createRequire } from "node:module";
|
|
11
13
|
import { pathToFileURL } from "node:url";
|
|
14
|
+
let activeBootstrapLoads = 0;
|
|
15
|
+
let esbuildRuntime = null;
|
|
16
|
+
let esbuildStopPromise = null;
|
|
17
|
+
const logger = createLogger("shared").child({ component: "bootstrap" });
|
|
18
|
+
async function getEsbuildRuntime() {
|
|
19
|
+
if (esbuildStopPromise) await esbuildStopPromise;
|
|
20
|
+
if (esbuildRuntime) return esbuildRuntime;
|
|
21
|
+
const loadedRuntime = await import("esbuild");
|
|
22
|
+
esbuildRuntime ??= loadedRuntime;
|
|
23
|
+
return esbuildRuntime;
|
|
24
|
+
}
|
|
25
|
+
async function withEsbuildLifecycle(load) {
|
|
26
|
+
activeBootstrapLoads += 1;
|
|
27
|
+
try {
|
|
28
|
+
return await load();
|
|
29
|
+
} finally {
|
|
30
|
+
activeBootstrapLoads -= 1;
|
|
31
|
+
if (activeBootstrapLoads === 0 && esbuildRuntime) {
|
|
32
|
+
const runtimeToStop = esbuildRuntime;
|
|
33
|
+
esbuildRuntime = null;
|
|
34
|
+
const stopPromise = runtimeToStop.stop().catch((err) => {
|
|
35
|
+
logger.warn("Failed to stop the bootstrap compiler service", { err });
|
|
36
|
+
});
|
|
37
|
+
esbuildStopPromise = stopPromise;
|
|
38
|
+
try {
|
|
39
|
+
await stopPromise;
|
|
40
|
+
} finally {
|
|
41
|
+
if (esbuildStopPromise === stopPromise) esbuildStopPromise = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
class GeneratedFileNotFoundError extends Error {
|
|
47
|
+
constructor(filePath) {
|
|
48
|
+
super(`Generated file not found: ${filePath}`);
|
|
49
|
+
this.name = "GeneratedFileNotFoundError";
|
|
50
|
+
this.filePath = filePath;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function createCliBundlePlugins(appRoot) {
|
|
54
|
+
const aliasPlugin = {
|
|
55
|
+
name: "alias-resolver",
|
|
56
|
+
setup(build) {
|
|
57
|
+
build.onResolve({ filter: /^@\// }, (args) => {
|
|
58
|
+
const rest = args.path.slice("@/".length);
|
|
59
|
+
const bases = rest.startsWith(".mercato/") ? [path.join(appRoot, rest)] : [path.join(appRoot, "src", rest), path.join(appRoot, rest)];
|
|
60
|
+
for (const base of bases) {
|
|
61
|
+
if (fs.existsSync(base) && fs.statSync(base).isFile()) {
|
|
62
|
+
return { path: base };
|
|
63
|
+
}
|
|
64
|
+
for (const suffix of [".ts", ".tsx", "/index.ts", "/index.tsx"]) {
|
|
65
|
+
if (fs.existsSync(base + suffix)) {
|
|
66
|
+
return { path: base + suffix };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { path: path.join(appRoot, rest) };
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const externalNonJsonPlugin = {
|
|
75
|
+
name: "external-non-json",
|
|
76
|
+
setup(build) {
|
|
77
|
+
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
78
|
+
if (/^[a-zA-Z]:/.test(args.path)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (args.path.endsWith(".json")) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return { path: args.path, external: true };
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return [createClientOnlyStubPlugin(), aliasPlugin, externalNonJsonPlugin];
|
|
89
|
+
}
|
|
12
90
|
const DYNAMIC_LOADER_CACHE_VERSION = 4;
|
|
13
91
|
function cacheMetadataPath(jsPath) {
|
|
14
92
|
return `${jsPath}.cache.json`;
|
|
@@ -126,7 +204,7 @@ function dependenciesAreValid(appRoot, dependencies) {
|
|
|
126
204
|
}
|
|
127
205
|
function collectDependencyHashes(appRoot, inputs) {
|
|
128
206
|
return Object.fromEntries(
|
|
129
|
-
Object.keys(inputs).map((inputPath) => {
|
|
207
|
+
Object.keys(inputs).filter((inputPath) => !inputPath.startsWith(`${CLIENT_ONLY_STUB_NAMESPACE}:`)).map((inputPath) => {
|
|
130
208
|
const absolutePath = path.isAbsolute(inputPath) ? inputPath : path.resolve(appRoot, inputPath);
|
|
131
209
|
const relativePath = path.relative(appRoot, absolutePath).split(path.sep).join("/");
|
|
132
210
|
return [relativePath, contentHash(fs.readFileSync(absolutePath))];
|
|
@@ -155,78 +233,60 @@ function cacheIsValid(appRoot, jsPath, metadataPath, expectedInputHash) {
|
|
|
155
233
|
if (!metadata || metadata.inputHash !== expectedInputHash) return false;
|
|
156
234
|
return contentHash(fs.readFileSync(jsPath)) === metadata.outputHash && dependenciesAreValid(appRoot, metadata.dependencies);
|
|
157
235
|
}
|
|
158
|
-
async function
|
|
159
|
-
|
|
160
|
-
|
|
236
|
+
async function compileAppSourceFile(tsPath, options) {
|
|
237
|
+
return withEsbuildLifecycle(() => compileAppSourceFileWithActiveEsbuild(tsPath, options));
|
|
238
|
+
}
|
|
239
|
+
async function compileAppSourceFileWithActiveEsbuild(tsPath, options) {
|
|
240
|
+
const { appRoot, outFile } = options;
|
|
241
|
+
const format = options.format ?? "esm";
|
|
161
242
|
const appTsconfig = path.join(appRoot, "tsconfig.json");
|
|
162
|
-
const metadataPath = cacheMetadataPath(
|
|
243
|
+
const metadataPath = cacheMetadataPath(outFile);
|
|
163
244
|
const tsExists = fs.existsSync(tsPath);
|
|
164
245
|
const tsconfigExists = fs.existsSync(appTsconfig);
|
|
165
246
|
if (!tsExists) {
|
|
166
|
-
throw new
|
|
247
|
+
throw new GeneratedFileNotFoundError(tsPath);
|
|
167
248
|
}
|
|
168
249
|
if (!tsconfigExists) {
|
|
169
250
|
throw new Error(`App TypeScript config not found: ${appTsconfig}`);
|
|
170
251
|
}
|
|
171
252
|
const tsconfigPaths = collectTsconfigPaths(appTsconfig);
|
|
172
253
|
const expectedInputHash = cacheInputHash(tsPath, appRoot, tsconfigPaths);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const esbuild = await import("esbuild");
|
|
176
|
-
const aliasPlugin = {
|
|
177
|
-
name: "alias-resolver",
|
|
178
|
-
setup(build) {
|
|
179
|
-
build.onResolve({ filter: /^@\// }, (args) => {
|
|
180
|
-
const resolved = path.join(appRoot, args.path.slice(2));
|
|
181
|
-
if (!fs.existsSync(resolved) && fs.existsSync(resolved + ".ts")) {
|
|
182
|
-
return { path: resolved + ".ts" };
|
|
183
|
-
}
|
|
184
|
-
if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory() && fs.existsSync(path.join(resolved, "index.ts"))) {
|
|
185
|
-
return { path: path.join(resolved, "index.ts") };
|
|
186
|
-
}
|
|
187
|
-
return { path: resolved };
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
const externalNonJsonPlugin = {
|
|
192
|
-
name: "external-non-json",
|
|
193
|
-
setup(build) {
|
|
194
|
-
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
195
|
-
if (/^[a-zA-Z]:/.test(args.path)) {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
if (args.path.endsWith(".json")) {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
return { path: args.path, external: true };
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
const result = await esbuild.build({
|
|
206
|
-
entryPoints: [tsPath],
|
|
207
|
-
outfile: jsPath,
|
|
208
|
-
absWorkingDir: appRoot,
|
|
209
|
-
bundle: true,
|
|
210
|
-
metafile: true,
|
|
211
|
-
format: "esm",
|
|
212
|
-
platform: "node",
|
|
213
|
-
target: "node18",
|
|
214
|
-
tsconfig: appTsconfig,
|
|
215
|
-
plugins: [aliasPlugin, externalNonJsonPlugin],
|
|
216
|
-
// Allow JSON imports
|
|
217
|
-
loader: { ".json": "json" }
|
|
218
|
-
});
|
|
219
|
-
const metadata = {
|
|
220
|
-
version: DYNAMIC_LOADER_CACHE_VERSION,
|
|
221
|
-
inputHash: expectedInputHash,
|
|
222
|
-
outputHash: contentHash(fs.readFileSync(jsPath)),
|
|
223
|
-
dependencies: {
|
|
224
|
-
...collectDependencyHashes(appRoot, result.metafile.inputs),
|
|
225
|
-
...hashFilesRelativeTo(appRoot, tsconfigPaths)
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
fs.writeFileSync(metadataPath, JSON.stringify(metadata));
|
|
254
|
+
if (cacheIsValid(appRoot, outFile, metadataPath, expectedInputHash)) {
|
|
255
|
+
return outFile;
|
|
229
256
|
}
|
|
257
|
+
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
|
258
|
+
const esbuild = await getEsbuildRuntime();
|
|
259
|
+
const result = await esbuild.build({
|
|
260
|
+
entryPoints: [tsPath],
|
|
261
|
+
outfile: outFile,
|
|
262
|
+
absWorkingDir: appRoot,
|
|
263
|
+
bundle: true,
|
|
264
|
+
metafile: true,
|
|
265
|
+
format,
|
|
266
|
+
platform: "node",
|
|
267
|
+
target: "node18",
|
|
268
|
+
tsconfig: appTsconfig,
|
|
269
|
+
plugins: createCliBundlePlugins(appRoot),
|
|
270
|
+
// Allow JSON imports
|
|
271
|
+
loader: { ".json": "json" }
|
|
272
|
+
});
|
|
273
|
+
const metadata = {
|
|
274
|
+
version: DYNAMIC_LOADER_CACHE_VERSION,
|
|
275
|
+
inputHash: expectedInputHash,
|
|
276
|
+
outputHash: contentHash(fs.readFileSync(outFile)),
|
|
277
|
+
dependencies: {
|
|
278
|
+
...collectDependencyHashes(appRoot, result.metafile.inputs),
|
|
279
|
+
...hashFilesRelativeTo(appRoot, tsconfigPaths)
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
fs.writeFileSync(metadataPath, JSON.stringify(metadata));
|
|
283
|
+
return outFile;
|
|
284
|
+
}
|
|
285
|
+
async function compileAndImport(tsPath, options = {}) {
|
|
286
|
+
const allowRecovery = options.allowRecovery ?? true;
|
|
287
|
+
const jsPath = options.outFile ?? tsPath.replace(/\.ts$/, ".mjs");
|
|
288
|
+
const appRoot = options.appRoot ?? path.dirname(path.dirname(path.dirname(tsPath)));
|
|
289
|
+
await compileAppSourceFile(tsPath, { appRoot, outFile: jsPath });
|
|
230
290
|
try {
|
|
231
291
|
const outputHash = contentHash(fs.readFileSync(jsPath));
|
|
232
292
|
const fileUrl = `${pathToFileURL(jsPath).href}?cache=${outputHash}`;
|
|
@@ -239,10 +299,28 @@ async function compileAndImport(tsPath, allowRecovery = true) {
|
|
|
239
299
|
if (!recovered.applied) {
|
|
240
300
|
throw error;
|
|
241
301
|
}
|
|
242
|
-
return compileAndImport(tsPath, false);
|
|
302
|
+
return compileAndImport(tsPath, { ...options, allowRecovery: false });
|
|
243
303
|
}
|
|
244
304
|
}
|
|
245
|
-
async function
|
|
305
|
+
async function loadOptionalGeneratedModule(tsPath, fallback) {
|
|
306
|
+
try {
|
|
307
|
+
return await compileAndImport(tsPath);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
if (error instanceof GeneratedFileNotFoundError) {
|
|
310
|
+
logger.debug("Optional generated registry not present, using empty fallback", {
|
|
311
|
+
file: path.basename(tsPath)
|
|
312
|
+
});
|
|
313
|
+
return fallback;
|
|
314
|
+
}
|
|
315
|
+
logger.error("Failed to load generated registry, continuing without its entries", {
|
|
316
|
+
file: path.basename(tsPath),
|
|
317
|
+
filePath: tsPath,
|
|
318
|
+
err: error
|
|
319
|
+
});
|
|
320
|
+
return fallback;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function resolveAppRootOrThrow(appRoot) {
|
|
246
324
|
const resolved = appRoot ? {
|
|
247
325
|
generatedDir: path.join(appRoot, ".mercato", "generated"),
|
|
248
326
|
appDir: appRoot,
|
|
@@ -253,6 +331,37 @@ async function loadBootstrapData(appRoot) {
|
|
|
253
331
|
'Could not find app root with .mercato/generated directory. Make sure you run this command from within a Next.js app directory, or run "yarn mercato generate" first to create the generated files.'
|
|
254
332
|
);
|
|
255
333
|
}
|
|
334
|
+
return resolved;
|
|
335
|
+
}
|
|
336
|
+
async function loadAppDiRegistrar(appDir) {
|
|
337
|
+
const tsPath = path.join(appDir, "src", "di.ts");
|
|
338
|
+
if (!fs.existsSync(tsPath)) {
|
|
339
|
+
logger.debug("App-level DI module not present, skipping its registrations", { filePath: tsPath });
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const appDiModule = await compileAndImport(tsPath, {
|
|
344
|
+
appRoot: appDir,
|
|
345
|
+
outFile: path.join(appDir, ".mercato", "generated", "app-di.compiled.mjs")
|
|
346
|
+
});
|
|
347
|
+
const register = appDiModule.register;
|
|
348
|
+
if (typeof register !== "function") {
|
|
349
|
+
logger.error("App-level DI module exports no register(); its registrations are skipped", {
|
|
350
|
+
filePath: tsPath
|
|
351
|
+
});
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return register;
|
|
355
|
+
} catch (error) {
|
|
356
|
+
logger.error("Failed to load the app-level DI module; its registrations are skipped", {
|
|
357
|
+
filePath: tsPath,
|
|
358
|
+
err: error
|
|
359
|
+
});
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async function loadBootstrapDataWithActiveEsbuild(appRoot) {
|
|
364
|
+
const resolved = resolveAppRootOrThrow(appRoot);
|
|
256
365
|
const { generatedDir } = resolved;
|
|
257
366
|
ensureMikroOrmV7GeneratedCacheCompatibility(resolved.appDir);
|
|
258
367
|
const entityIdsModule = await compileAndImport(path.join(generatedDir, "entities.ids.generated.ts"));
|
|
@@ -269,10 +378,12 @@ async function loadBootstrapData(appRoot) {
|
|
|
269
378
|
compileAndImport(path.join(generatedDir, "modules.cli.generated.ts")),
|
|
270
379
|
compileAndImport(path.join(generatedDir, "entities.generated.ts")),
|
|
271
380
|
compileAndImport(path.join(generatedDir, "di.generated.ts")),
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
381
|
+
loadOptionalGeneratedModule(path.join(generatedDir, "search.generated.ts"), { searchModuleConfigs: [] }),
|
|
382
|
+
loadOptionalGeneratedModule(path.join(generatedDir, "command-loaders.generated.ts"), { commandLoaderEntries: [] }),
|
|
383
|
+
loadOptionalGeneratedModule(path.join(generatedDir, "command-interceptors.generated.ts"), {
|
|
384
|
+
commandInterceptorEntries: []
|
|
385
|
+
}),
|
|
386
|
+
loadOptionalGeneratedModule(path.join(generatedDir, "workflows.generated.ts"), { allCodeWorkflows: [] })
|
|
276
387
|
]);
|
|
277
388
|
return {
|
|
278
389
|
modules: modulesModule.modules,
|
|
@@ -297,16 +408,25 @@ async function loadBootstrapData(appRoot) {
|
|
|
297
408
|
componentOverrideEntries: []
|
|
298
409
|
};
|
|
299
410
|
}
|
|
411
|
+
async function loadBootstrapData(appRoot) {
|
|
412
|
+
return withEsbuildLifecycle(() => loadBootstrapDataWithActiveEsbuild(appRoot));
|
|
413
|
+
}
|
|
300
414
|
async function bootstrapFromAppRoot(appRoot) {
|
|
301
415
|
const { createBootstrap, waitForAsyncRegistration } = await import("./factory.js");
|
|
302
|
-
const
|
|
303
|
-
const
|
|
416
|
+
const resolved = resolveAppRootOrThrow(appRoot);
|
|
417
|
+
const { data, appDiRegistrar } = await withEsbuildLifecycle(async () => ({
|
|
418
|
+
data: await loadBootstrapData(resolved.appDir),
|
|
419
|
+
appDiRegistrar: await loadAppDiRegistrar(resolved.appDir)
|
|
420
|
+
}));
|
|
421
|
+
const bootstrap = createBootstrap(data, appDiRegistrar ? { appDiRegistrar } : {});
|
|
304
422
|
bootstrap();
|
|
305
423
|
await waitForAsyncRegistration();
|
|
306
424
|
return data;
|
|
307
425
|
}
|
|
308
426
|
export {
|
|
309
427
|
bootstrapFromAppRoot,
|
|
428
|
+
compileAppSourceFile,
|
|
429
|
+
createCliBundlePlugins,
|
|
310
430
|
loadBootstrapData
|
|
311
431
|
};
|
|
312
432
|
//# sourceMappingURL=dynamicLoader.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/bootstrap/dynamicLoader.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BootstrapData } from './types'\nimport { findAppRoot, type AppRoot } from './appResolver'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport {\n ensureMikroOrmV7GeneratedCacheCompatibility,\n recoverMikroOrmV7GeneratedCacheFromImportError,\n} from './generatedCacheRecovery'\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport crypto from 'node:crypto'\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\nconst DYNAMIC_LOADER_CACHE_VERSION = 4\n\ntype DynamicLoaderCacheMetadata = {\n version: number\n inputHash: string\n outputHash: string\n dependencies: Record<string, string>\n}\n\nfunction cacheMetadataPath(jsPath: string): string {\n return `${jsPath}.cache.json`\n}\n\nfunction contentHash(content: Buffer | string): string {\n return crypto.createHash('sha256').update(content).digest('hex')\n}\n\nfunction parseJsonConfig(content: string): unknown {\n let normalized = ''\n let inString = false\n let escaped = false\n\n for (let index = 0; index < content.length; index += 1) {\n const character = content[index]\n const nextCharacter = content[index + 1]\n\n if (inString) {\n normalized += character\n if (escaped) {\n escaped = false\n } else if (character === '\\\\') {\n escaped = true\n } else if (character === '\"') {\n inString = false\n }\n continue\n }\n\n if (character === '\"') {\n inString = true\n normalized += character\n continue\n }\n\n if (character === '/' && nextCharacter === '/') {\n while (index < content.length && content[index] !== '\\n') index += 1\n normalized += '\\n'\n continue\n }\n\n if (character === '/' && nextCharacter === '*') {\n index += 2\n while (index < content.length && !(content[index] === '*' && content[index + 1] === '/')) {\n index += 1\n }\n index += 1\n continue\n }\n\n if (character === ',') {\n let lookahead = index + 1\n while (lookahead < content.length && /\\s/.test(content[lookahead])) lookahead += 1\n if (content[lookahead] === '}' || content[lookahead] === ']') continue\n }\n\n normalized += character\n }\n\n return JSON.parse(normalized)\n}\n\nfunction resolveExistingConfigPath(candidate: string): string | null {\n for (const configPath of [candidate, `${candidate}.json`, path.join(candidate, 'tsconfig.json')]) {\n if (fs.existsSync(configPath) && fs.statSync(configPath).isFile()) return configPath\n }\n return null\n}\n\nfunction resolvePackageConfig(configPath: string, reference: string): string | null {\n try {\n const resolved = createRequire(pathToFileURL(configPath)).resolve(reference)\n return path.extname(resolved) === '.json' ? resolved : null\n } catch {\n return null\n }\n}\n\nfunction resolveExtendedConfig(configPath: string, reference: string): string {\n if (path.isAbsolute(reference) || reference.startsWith('.')) {\n const resolved = resolveExistingConfigPath(path.resolve(path.dirname(configPath), reference))\n if (resolved) return resolved\n } else {\n for (const packageReference of [reference, `${reference}/tsconfig.json`]) {\n const resolved = resolvePackageConfig(configPath, packageReference)\n if (resolved) return resolved\n }\n }\n\n throw new Error(`[internal] TypeScript config extends target not found: ${reference}`)\n}\n\nfunction collectTsconfigPaths(entryPath: string, visited: Set<string> = new Set()): string[] {\n const configPath = path.resolve(entryPath)\n if (visited.has(configPath)) return []\n visited.add(configPath)\n\n const parsed = parseJsonConfig(fs.readFileSync(configPath, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null || !('extends' in parsed)) return [configPath]\n\n const extendsValue = parsed.extends\n const references = typeof extendsValue === 'string'\n ? [extendsValue]\n : Array.isArray(extendsValue) && extendsValue.every((value) => typeof value === 'string')\n ? extendsValue\n : []\n\n return [\n ...references.flatMap((reference) => collectTsconfigPaths(\n resolveExtendedConfig(configPath, reference),\n visited,\n )),\n configPath,\n ]\n}\n\nfunction hashFilesRelativeTo(appRoot: string, filePaths: string[]): Record<string, string> {\n return Object.fromEntries(filePaths.map((filePath) => [\n path.relative(appRoot, filePath).split(path.sep).join('/'),\n contentHash(fs.readFileSync(filePath)),\n ]))\n}\n\nfunction cacheInputHash(tsPath: string, appRoot: string, tsconfigPaths: string[]): string {\n const hash = crypto.createHash('sha256')\n hash.update(JSON.stringify({\n version: DYNAMIC_LOADER_CACHE_VERSION,\n sourceHash: contentHash(fs.readFileSync(tsPath)),\n tsconfigHashes: hashFilesRelativeTo(appRoot, tsconfigPaths),\n }))\n return hash.digest('hex')\n}\n\nfunction dependenciesAreValid(appRoot: string, dependencies: Record<string, string>): boolean {\n return Object.entries(dependencies).every(([relativePath, expectedHash]) => {\n const dependencyPath = path.resolve(appRoot, relativePath)\n return fs.existsSync(dependencyPath)\n && contentHash(fs.readFileSync(dependencyPath)) === expectedHash\n })\n}\n\nfunction collectDependencyHashes(\n appRoot: string,\n inputs: Record<string, unknown>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.keys(inputs)\n .map((inputPath) => {\n const absolutePath = path.isAbsolute(inputPath)\n ? inputPath\n : path.resolve(appRoot, inputPath)\n const relativePath = path.relative(appRoot, absolutePath).split(path.sep).join('/')\n return [relativePath, contentHash(fs.readFileSync(absolutePath))]\n })\n .sort(([left], [right]) => left.localeCompare(right)),\n )\n}\n\nfunction readCacheMetadata(metadataPath: string): DynamicLoaderCacheMetadata | null {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(metadataPath, 'utf8'))\n if (\n typeof parsed === 'object'\n && parsed !== null\n && 'version' in parsed\n && parsed.version === DYNAMIC_LOADER_CACHE_VERSION\n && 'inputHash' in parsed\n && typeof parsed.inputHash === 'string'\n && 'outputHash' in parsed\n && typeof parsed.outputHash === 'string'\n && 'dependencies' in parsed\n && typeof parsed.dependencies === 'object'\n && parsed.dependencies !== null\n && Object.values(parsed.dependencies).every((hash) => typeof hash === 'string')\n ) {\n return {\n version: parsed.version,\n inputHash: parsed.inputHash,\n outputHash: parsed.outputHash,\n dependencies: parsed.dependencies as Record<string, string>,\n }\n }\n } catch {\n return null\n }\n return null\n}\n\nfunction cacheIsValid(\n appRoot: string,\n jsPath: string,\n metadataPath: string,\n expectedInputHash: string,\n): boolean {\n if (!fs.existsSync(jsPath)) return false\n const metadata = readCacheMetadata(metadataPath)\n if (!metadata || metadata.inputHash !== expectedInputHash) return false\n return contentHash(fs.readFileSync(jsPath)) === metadata.outputHash\n && dependenciesAreValid(appRoot, metadata.dependencies)\n}\n\n/**\n * Compile a TypeScript file to JavaScript using esbuild bundler.\n * This bundles the file and all its dependencies, handling JSON imports properly.\n * The compiled file is written next to the source file with a .mjs extension.\n */\nasync function compileAndImport(tsPath: string, allowRecovery: boolean = true): Promise<Record<string, unknown>> {\n const jsPath = tsPath.replace(/\\.ts$/, '.mjs')\n const appRoot = path.dirname(path.dirname(path.dirname(tsPath)))\n const appTsconfig = path.join(appRoot, 'tsconfig.json')\n const metadataPath = cacheMetadataPath(jsPath)\n\n const tsExists = fs.existsSync(tsPath)\n const tsconfigExists = fs.existsSync(appTsconfig)\n\n if (!tsExists) {\n throw new Error(`Generated file not found: ${tsPath}`)\n }\n if (!tsconfigExists) {\n throw new Error(`App TypeScript config not found: ${appTsconfig}`)\n }\n\n const tsconfigPaths = collectTsconfigPaths(appTsconfig)\n const expectedInputHash = cacheInputHash(tsPath, appRoot, tsconfigPaths)\n const needsCompile = !cacheIsValid(appRoot, jsPath, metadataPath, expectedInputHash)\n\n if (needsCompile) {\n // Dynamically import esbuild only when needed\n const esbuild = await import('esbuild')\n\n // Plugin to resolve @/ alias to app root (works for @app modules)\n const aliasPlugin: import('esbuild').Plugin = {\n name: 'alias-resolver',\n setup(build) {\n // Resolve @/ alias to app root\n build.onResolve({ filter: /^@\\// }, (args) => {\n const resolved = path.join(appRoot, args.path.slice(2))\n // Try with .ts extension if base path doesn't exist\n if (!fs.existsSync(resolved) && fs.existsSync(resolved + '.ts')) {\n return { path: resolved + '.ts' }\n }\n // Also check for /index.ts if it's a directory\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory() && fs.existsSync(path.join(resolved, 'index.ts'))) {\n return { path: path.join(resolved, 'index.ts') }\n }\n return { path: resolved }\n })\n },\n }\n\n // Plugin to mark non-JSON package imports as external\n const externalNonJsonPlugin: import('esbuild').Plugin = {\n name: 'external-non-json',\n setup(build) {\n // Mark all package imports as external EXCEPT JSON files\n // Filter matches paths that don't start with . or / (package imports like @open-mercato/shared)\n build.onResolve({ filter: /^[^./]/ }, (args) => {\n // Skip Windows absolute paths (e.g., C:\\...) - they're local files, not packages\n if (/^[a-zA-Z]:/.test(args.path)) {\n return null // Let esbuild handle it\n }\n // If it's a JSON file, let esbuild bundle it\n if (args.path.endsWith('.json')) {\n return null // Let esbuild handle it\n }\n // Otherwise mark as external\n return { path: args.path, external: true }\n })\n },\n }\n\n // Use esbuild.build with bundling to handle JSON imports\n const result = await esbuild.build({\n entryPoints: [tsPath],\n outfile: jsPath,\n absWorkingDir: appRoot,\n bundle: true,\n metafile: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n tsconfig: appTsconfig,\n plugins: [aliasPlugin, externalNonJsonPlugin],\n // Allow JSON imports\n loader: { '.json': 'json' },\n })\n const metadata: DynamicLoaderCacheMetadata = {\n version: DYNAMIC_LOADER_CACHE_VERSION,\n inputHash: expectedInputHash,\n outputHash: contentHash(fs.readFileSync(jsPath)),\n dependencies: {\n ...collectDependencyHashes(appRoot, result.metafile.inputs),\n ...hashFilesRelativeTo(appRoot, tsconfigPaths),\n },\n }\n fs.writeFileSync(metadataPath, JSON.stringify(metadata))\n }\n\n // Import the compiled JavaScript\n try {\n const outputHash = contentHash(fs.readFileSync(jsPath))\n const fileUrl = `${pathToFileURL(jsPath).href}?cache=${outputHash}`\n return await import(fileUrl)\n } catch (error) {\n if (!allowRecovery) {\n throw error\n }\n\n const recovered = recoverMikroOrmV7GeneratedCacheFromImportError(appRoot, error)\n if (!recovered.applied) {\n throw error\n }\n\n return compileAndImport(tsPath, false)\n }\n}\n\n\n/**\n * Dynamically load bootstrap data from a resolved app directory.\n *\n * IMPORTANT: This only works in unbundled contexts (CLI, tsx).\n * Do NOT use this in Next.js bundled code - use static imports instead.\n *\n * For CLI context, we skip loading modules.generated.ts which has Next.js dependencies.\n * CLI commands are discovered separately via the CLI module system.\n *\n * @param appRoot - Optional explicit app root path. If not provided, will search from cwd.\n * @returns The loaded bootstrap data\n * @throws Error if app root cannot be found or generated files are missing\n */\nexport async function loadBootstrapData(appRoot?: string): Promise<BootstrapData> {\n const resolved: AppRoot | null = appRoot\n ? {\n generatedDir: path.join(appRoot, '.mercato', 'generated'),\n appDir: appRoot,\n mercatoDir: path.join(appRoot, '.mercato'),\n }\n : findAppRoot()\n\n if (!resolved) {\n throw new Error(\n 'Could not find app root with .mercato/generated directory. ' +\n 'Make sure you run this command from within a Next.js app directory, ' +\n 'or run \"yarn mercato generate\" first to create the generated files.',\n )\n }\n\n const { generatedDir } = resolved\n\n ensureMikroOrmV7GeneratedCacheCompatibility(resolved.appDir)\n\n // IMPORTANT: Load entity IDs FIRST and register them before loading modules.\n // This is because modules (e.g., ce.ts files) use E.xxx.xxx at module scope,\n // and they need entity IDs to be available when they're imported.\n const entityIdsModule = await compileAndImport(path.join(generatedDir, 'entities.ids.generated.ts'))\n registerEntityIds(entityIdsModule.E as BootstrapData['entityIds'])\n\n // Now load the rest of the generated files.\n // modules.cli.generated.ts excludes Next.js-dependent code (routes, APIs, widgets)\n const [\n modulesModule,\n entitiesModule,\n diModule,\n searchModule,\n commandLoadersModule,\n commandInterceptorsModule,\n workflowsModule,\n ] = await Promise.all([\n compileAndImport(path.join(generatedDir, 'modules.cli.generated.ts')),\n compileAndImport(path.join(generatedDir, 'entities.generated.ts')),\n compileAndImport(path.join(generatedDir, 'di.generated.ts')),\n compileAndImport(path.join(generatedDir, 'search.generated.ts')).catch(() => ({ searchModuleConfigs: [] })),\n compileAndImport(path.join(generatedDir, 'command-loaders.generated.ts')).catch(() => ({ commandLoaderEntries: [] })),\n compileAndImport(path.join(generatedDir, 'command-interceptors.generated.ts')).catch(() => ({ commandInterceptorEntries: [] })),\n compileAndImport(path.join(generatedDir, 'workflows.generated.ts')).catch(() => ({ allCodeWorkflows: [] })),\n ])\n\n return {\n modules: modulesModule.modules as BootstrapData['modules'],\n entities: entitiesModule.entities as BootstrapData['entities'],\n diRegistrars: diModule.diRegistrars as BootstrapData['diRegistrars'],\n entityIds: entityIdsModule.E as BootstrapData['entityIds'],\n // Search configs are needed by workers for indexing\n searchModuleConfigs: (searchModule.searchModuleConfigs ?? []) as BootstrapData['searchModuleConfigs'],\n commandLoaderEntries: (commandLoadersModule.commandLoaderEntries ?? []) as BootstrapData['commandLoaderEntries'],\n // Command interceptors must apply in worker/CLI processes too \u2014 the\n // interceptor registry is per-process, so relying on the Next.js runtime's\n // registration silently no-ops every interceptor for queued/CLI commands\n // (#4327).\n commandInterceptorEntries: (commandInterceptorsModule.commandInterceptorEntries ??\n []) as BootstrapData['commandInterceptorEntries'],\n // Code workflow definitions are needed by workers to resume code-defined instances\n codeWorkflows: (workflowsModule.allCodeWorkflows ?? []) as BootstrapData['codeWorkflows'],\n // Empty UI-related data - not needed for CLI\n dashboardWidgetEntries: [],\n injectionWidgetEntries: [],\n injectionTables: [],\n interceptorEntries: [],\n componentOverrideEntries: [],\n }\n}\n\n/**\n * Create and execute bootstrap in CLI context.\n *\n * This is a convenience function that finds the app root, loads the generated\n * data dynamically, and runs bootstrap. Use this in CLI entry points.\n *\n * Returns the loaded bootstrap data so the CLI can register modules directly\n * (avoids module resolution issues when importing @open-mercato/cli/mercato).\n *\n * @param appRoot - Optional explicit app root path\n * @returns The loaded bootstrap data (modules, entities, etc.)\n */\nexport async function bootstrapFromAppRoot(appRoot?: string): Promise<BootstrapData> {\n const { createBootstrap, waitForAsyncRegistration } = await import('./factory.js')\n const data = await loadBootstrapData(appRoot)\n const bootstrap = createBootstrap(data)\n bootstrap()\n // In CLI context, wait for async registrations (UI widgets, search configs, etc.)\n await waitForAsyncRegistration()\n\n return data\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,mBAAiC;AAC1C,SAAS,yBAAyB;AAClC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,YAAY;AACnB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAE9B,MAAM,+BAA+B;AASrC,SAAS,kBAAkB,QAAwB;AACjD,SAAO,GAAG,MAAM;AAClB;AAEA,SAAS,YAAY,SAAkC;AACrD,SAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AACjE;AAEA,SAAS,gBAAgB,SAA0B;AACjD,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,UAAM,YAAY,QAAQ,KAAK;AAC/B,UAAM,gBAAgB,QAAQ,QAAQ,CAAC;AAEvC,QAAI,UAAU;AACZ,oBAAc;AACd,UAAI,SAAS;AACX,kBAAU;AAAA,MACZ,WAAW,cAAc,MAAM;AAC7B,kBAAU;AAAA,MACZ,WAAW,cAAc,KAAK;AAC5B,mBAAW;AAAA,MACb;AACA;AAAA,IACF;AAEA,QAAI,cAAc,KAAK;AACrB,iBAAW;AACX,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,cAAc,OAAO,kBAAkB,KAAK;AAC9C,aAAO,QAAQ,QAAQ,UAAU,QAAQ,KAAK,MAAM,KAAM,UAAS;AACnE,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,cAAc,OAAO,kBAAkB,KAAK;AAC9C,eAAS;AACT,aAAO,QAAQ,QAAQ,UAAU,EAAE,QAAQ,KAAK,MAAM,OAAO,QAAQ,QAAQ,CAAC,MAAM,MAAM;AACxF,iBAAS;AAAA,MACX;AACA,eAAS;AACT;AAAA,IACF;AAEA,QAAI,cAAc,KAAK;AACrB,UAAI,YAAY,QAAQ;AACxB,aAAO,YAAY,QAAQ,UAAU,KAAK,KAAK,QAAQ,SAAS,CAAC,EAAG,cAAa;AACjF,UAAI,QAAQ,SAAS,MAAM,OAAO,QAAQ,SAAS,MAAM,IAAK;AAAA,IAChE;AAEA,kBAAc;AAAA,EAChB;AAEA,SAAO,KAAK,MAAM,UAAU;AAC9B;AAEA,SAAS,0BAA0B,WAAkC;AACnE,aAAW,cAAc,CAAC,WAAW,GAAG,SAAS,SAAS,KAAK,KAAK,WAAW,eAAe,CAAC,GAAG;AAChG,QAAI,GAAG,WAAW,UAAU,KAAK,GAAG,SAAS,UAAU,EAAE,OAAO,EAAG,QAAO;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,YAAoB,WAAkC;AAClF,MAAI;AACF,UAAM,WAAW,cAAc,cAAc,UAAU,CAAC,EAAE,QAAQ,SAAS;AAC3E,WAAO,KAAK,QAAQ,QAAQ,MAAM,UAAU,WAAW;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,sBAAsB,YAAoB,WAA2B;AAC5E,MAAI,KAAK,WAAW,SAAS,KAAK,UAAU,WAAW,GAAG,GAAG;AAC3D,UAAM,WAAW,0BAA0B,KAAK,QAAQ,KAAK,QAAQ,UAAU,GAAG,SAAS,CAAC;AAC5F,QAAI,SAAU,QAAO;AAAA,EACvB,OAAO;AACL,eAAW,oBAAoB,CAAC,WAAW,GAAG,SAAS,gBAAgB,GAAG;AACxE,YAAM,WAAW,qBAAqB,YAAY,gBAAgB;AAClE,UAAI,SAAU,QAAO;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,0DAA0D,SAAS,EAAE;AACvF;AAEA,SAAS,qBAAqB,WAAmB,UAAuB,oBAAI,IAAI,GAAa;AAC3F,QAAM,aAAa,KAAK,QAAQ,SAAS;AACzC,MAAI,QAAQ,IAAI,UAAU,EAAG,QAAO,CAAC;AACrC,UAAQ,IAAI,UAAU;AAEtB,QAAM,SAAS,gBAAgB,GAAG,aAAa,YAAY,MAAM,CAAC;AAClE,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,EAAE,aAAa,QAAS,QAAO,CAAC,UAAU;AAE/F,QAAM,eAAe,OAAO;AAC5B,QAAM,aAAa,OAAO,iBAAiB,WACvC,CAAC,YAAY,IACb,MAAM,QAAQ,YAAY,KAAK,aAAa,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ,IACpF,eACA,CAAC;AAEP,SAAO;AAAA,IACL,GAAG,WAAW,QAAQ,CAAC,cAAc;AAAA,MACnC,sBAAsB,YAAY,SAAS;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,IACD;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,SAAiB,WAA6C;AACzF,SAAO,OAAO,YAAY,UAAU,IAAI,CAAC,aAAa;AAAA,IACpD,KAAK,SAAS,SAAS,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAAA,IACzD,YAAY,GAAG,aAAa,QAAQ,CAAC;AAAA,EACvC,CAAC,CAAC;AACJ;AAEA,SAAS,eAAe,QAAgB,SAAiB,eAAiC;AACxF,QAAM,OAAO,OAAO,WAAW,QAAQ;AACvC,OAAK,OAAO,KAAK,UAAU;AAAA,IACzB,SAAS;AAAA,IACT,YAAY,YAAY,GAAG,aAAa,MAAM,CAAC;AAAA,IAC/C,gBAAgB,oBAAoB,SAAS,aAAa;AAAA,EAC5D,CAAC,CAAC;AACF,SAAO,KAAK,OAAO,KAAK;AAC1B;AAEA,SAAS,qBAAqB,SAAiB,cAA+C;AAC5F,SAAO,OAAO,QAAQ,YAAY,EAAE,MAAM,CAAC,CAAC,cAAc,YAAY,MAAM;AAC1E,UAAM,iBAAiB,KAAK,QAAQ,SAAS,YAAY;AACzD,WAAO,GAAG,WAAW,cAAc,KAC9B,YAAY,GAAG,aAAa,cAAc,CAAC,MAAM;AAAA,EACxD,CAAC;AACH;AAEA,SAAS,wBACP,SACA,QACwB;AACxB,SAAO,OAAO;AAAA,IACZ,OAAO,KAAK,MAAM,EACf,IAAI,CAAC,cAAc;AAClB,YAAM,eAAe,KAAK,WAAW,SAAS,IAC1C,YACA,KAAK,QAAQ,SAAS,SAAS;AACnC,YAAM,eAAe,KAAK,SAAS,SAAS,YAAY,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAClF,aAAO,CAAC,cAAc,YAAY,GAAG,aAAa,YAAY,CAAC,CAAC;AAAA,IAClE,CAAC,EACA,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC;AAAA,EACxD;AACF;AAEA,SAAS,kBAAkB,cAAyD;AAClF,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;AACxE,QACE,OAAO,WAAW,YACf,WAAW,QACX,aAAa,UACb,OAAO,YAAY,gCACnB,eAAe,UACf,OAAO,OAAO,cAAc,YAC5B,gBAAgB,UAChB,OAAO,OAAO,eAAe,YAC7B,kBAAkB,UAClB,OAAO,OAAO,iBAAiB,YAC/B,OAAO,iBAAiB,QACxB,OAAO,OAAO,OAAO,YAAY,EAAE,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAC9E;AACA,aAAO;AAAA,QACL,SAAS,OAAO;AAAA,QAChB,WAAW,OAAO;AAAA,QAClB,YAAY,OAAO;AAAA,QACnB,cAAc,OAAO;AAAA,MACvB;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,aACP,SACA,QACA,cACA,mBACS;AACT,MAAI,CAAC,GAAG,WAAW,MAAM,EAAG,QAAO;AACnC,QAAM,WAAW,kBAAkB,YAAY;AAC/C,MAAI,CAAC,YAAY,SAAS,cAAc,kBAAmB,QAAO;AAClE,SAAO,YAAY,GAAG,aAAa,MAAM,CAAC,MAAM,SAAS,cACpD,qBAAqB,SAAS,SAAS,YAAY;AAC1D;AAOA,eAAe,iBAAiB,QAAgB,gBAAyB,MAAwC;AAC/G,QAAM,SAAS,OAAO,QAAQ,SAAS,MAAM;AAC7C,QAAM,UAAU,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,CAAC,CAAC;AAC/D,QAAM,cAAc,KAAK,KAAK,SAAS,eAAe;AACtD,QAAM,eAAe,kBAAkB,MAAM;AAE7C,QAAM,WAAW,GAAG,WAAW,MAAM;AACrC,QAAM,iBAAiB,GAAG,WAAW,WAAW;AAEhD,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,6BAA6B,MAAM,EAAE;AAAA,EACvD;AACA,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI,MAAM,oCAAoC,WAAW,EAAE;AAAA,EACnE;AAEA,QAAM,gBAAgB,qBAAqB,WAAW;AACtD,QAAM,oBAAoB,eAAe,QAAQ,SAAS,aAAa;AACvE,QAAM,eAAe,CAAC,aAAa,SAAS,QAAQ,cAAc,iBAAiB;AAEnF,MAAI,cAAc;AAEhB,UAAM,UAAU,MAAM,OAAO,SAAS;AAGtC,UAAM,cAAwC;AAAA,MAC5C,MAAM;AAAA,MACN,MAAM,OAAO;AAEX,cAAM,UAAU,EAAE,QAAQ,OAAO,GAAG,CAAC,SAAS;AAC5C,gBAAM,WAAW,KAAK,KAAK,SAAS,KAAK,KAAK,MAAM,CAAC,CAAC;AAEtD,cAAI,CAAC,GAAG,WAAW,QAAQ,KAAK,GAAG,WAAW,WAAW,KAAK,GAAG;AAC/D,mBAAO,EAAE,MAAM,WAAW,MAAM;AAAA,UAClC;AAEA,cAAI,GAAG,WAAW,QAAQ,KAAK,GAAG,SAAS,QAAQ,EAAE,YAAY,KAAK,GAAG,WAAW,KAAK,KAAK,UAAU,UAAU,CAAC,GAAG;AACpH,mBAAO,EAAE,MAAM,KAAK,KAAK,UAAU,UAAU,EAAE;AAAA,UACjD;AACA,iBAAO,EAAE,MAAM,SAAS;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,wBAAkD;AAAA,MACtD,MAAM;AAAA,MACN,MAAM,OAAO;AAGX,cAAM,UAAU,EAAE,QAAQ,SAAS,GAAG,CAAC,SAAS;AAE9C,cAAI,aAAa,KAAK,KAAK,IAAI,GAAG;AAChC,mBAAO;AAAA,UACT;AAEA,cAAI,KAAK,KAAK,SAAS,OAAO,GAAG;AAC/B,mBAAO;AAAA,UACT;AAEA,iBAAO,EAAE,MAAM,KAAK,MAAM,UAAU,KAAK;AAAA,QAC3C,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,SAAS,MAAM,QAAQ,MAAM;AAAA,MACjC,aAAa,CAAC,MAAM;AAAA,MACpB,SAAS;AAAA,MACT,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS,CAAC,aAAa,qBAAqB;AAAA;AAAA,MAE5C,QAAQ,EAAE,SAAS,OAAO;AAAA,IAC5B,CAAC;AACD,UAAM,WAAuC;AAAA,MAC3C,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY,YAAY,GAAG,aAAa,MAAM,CAAC;AAAA,MAC/C,cAAc;AAAA,QACZ,GAAG,wBAAwB,SAAS,OAAO,SAAS,MAAM;AAAA,QAC1D,GAAG,oBAAoB,SAAS,aAAa;AAAA,MAC/C;AAAA,IACF;AACA,OAAG,cAAc,cAAc,KAAK,UAAU,QAAQ,CAAC;AAAA,EACzD;AAGA,MAAI;AACF,UAAM,aAAa,YAAY,GAAG,aAAa,MAAM,CAAC;AACtD,UAAM,UAAU,GAAG,cAAc,MAAM,EAAE,IAAI,UAAU,UAAU;AACjE,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,OAAO;AACd,QAAI,CAAC,eAAe;AAClB,YAAM;AAAA,IACR;AAEA,UAAM,YAAY,+CAA+C,SAAS,KAAK;AAC/E,QAAI,CAAC,UAAU,SAAS;AACtB,YAAM;AAAA,IACR;AAEA,WAAO,iBAAiB,QAAQ,KAAK;AAAA,EACvC;AACF;AAgBA,eAAsB,kBAAkB,SAA0C;AAChF,QAAM,WAA2B,UAC7B;AAAA,IACE,cAAc,KAAK,KAAK,SAAS,YAAY,WAAW;AAAA,IACxD,QAAQ;AAAA,IACR,YAAY,KAAK,KAAK,SAAS,UAAU;AAAA,EAC3C,IACA,YAAY;AAEhB,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AAEA,QAAM,EAAE,aAAa,IAAI;AAEzB,8CAA4C,SAAS,MAAM;AAK3D,QAAM,kBAAkB,MAAM,iBAAiB,KAAK,KAAK,cAAc,2BAA2B,CAAC;AACnG,oBAAkB,gBAAgB,CAA+B;AAIjE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,iBAAiB,KAAK,KAAK,cAAc,0BAA0B,CAAC;AAAA,IACpE,iBAAiB,KAAK,KAAK,cAAc,uBAAuB,CAAC;AAAA,IACjE,iBAAiB,KAAK,KAAK,cAAc,iBAAiB,CAAC;AAAA,IAC3D,iBAAiB,KAAK,KAAK,cAAc,qBAAqB,CAAC,EAAE,MAAM,OAAO,EAAE,qBAAqB,CAAC,EAAE,EAAE;AAAA,IAC1G,iBAAiB,KAAK,KAAK,cAAc,8BAA8B,CAAC,EAAE,MAAM,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE;AAAA,IACpH,iBAAiB,KAAK,KAAK,cAAc,mCAAmC,CAAC,EAAE,MAAM,OAAO,EAAE,2BAA2B,CAAC,EAAE,EAAE;AAAA,IAC9H,iBAAiB,KAAK,KAAK,cAAc,wBAAwB,CAAC,EAAE,MAAM,OAAO,EAAE,kBAAkB,CAAC,EAAE,EAAE;AAAA,EAC5G,CAAC;AAED,SAAO;AAAA,IACL,SAAS,cAAc;AAAA,IACvB,UAAU,eAAe;AAAA,IACzB,cAAc,SAAS;AAAA,IACvB,WAAW,gBAAgB;AAAA;AAAA,IAE3B,qBAAsB,aAAa,uBAAuB,CAAC;AAAA,IAC3D,sBAAuB,qBAAqB,wBAAwB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKrE,2BAA4B,0BAA0B,6BACpD,CAAC;AAAA;AAAA,IAEH,eAAgB,gBAAgB,oBAAoB,CAAC;AAAA;AAAA,IAErD,wBAAwB,CAAC;AAAA,IACzB,wBAAwB,CAAC;AAAA,IACzB,iBAAiB,CAAC;AAAA,IAClB,oBAAoB,CAAC;AAAA,IACrB,0BAA0B,CAAC;AAAA,EAC7B;AACF;AAcA,eAAsB,qBAAqB,SAA0C;AACnF,QAAM,EAAE,iBAAiB,yBAAyB,IAAI,MAAM,OAAO,cAAc;AACjF,QAAM,OAAO,MAAM,kBAAkB,OAAO;AAC5C,QAAM,YAAY,gBAAgB,IAAI;AACtC,YAAU;AAEV,QAAM,yBAAyB;AAE/B,SAAO;AACT;",
|
|
4
|
+
"sourcesContent": ["import type { BootstrapData } from './types'\nimport type { AppDiRegistrar } from '../di/container'\nimport { findAppRoot, type AppRoot } from './appResolver'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport { createLogger } from '../logger'\nimport {\n ensureMikroOrmV7GeneratedCacheCompatibility,\n recoverMikroOrmV7GeneratedCacheFromImportError,\n} from './generatedCacheRecovery'\nimport { CLIENT_ONLY_STUB_NAMESPACE, createClientOnlyStubPlugin } from './clientOnlyModules'\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport crypto from 'node:crypto'\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\nlet activeBootstrapLoads = 0\nlet esbuildRuntime: typeof import('esbuild') | null = null\nlet esbuildStopPromise: Promise<void> | null = null\n\nconst logger = createLogger('shared').child({ component: 'bootstrap' })\n\nasync function getEsbuildRuntime(): Promise<typeof import('esbuild')> {\n if (esbuildStopPromise) await esbuildStopPromise\n if (esbuildRuntime) return esbuildRuntime\n\n const loadedRuntime = await import('esbuild')\n esbuildRuntime ??= loadedRuntime\n return esbuildRuntime\n}\n\nasync function withEsbuildLifecycle<T>(load: () => Promise<T>): Promise<T> {\n activeBootstrapLoads += 1\n\n try {\n return await load()\n } finally {\n activeBootstrapLoads -= 1\n if (activeBootstrapLoads === 0 && esbuildRuntime) {\n // esbuild keeps a helper process alive after build(). Bootstrap compilation\n // is a bounded phase, so release it once every concurrent loader is done.\n // A later build() call transparently starts a fresh helper process.\n const runtimeToStop = esbuildRuntime\n esbuildRuntime = null\n const stopPromise = runtimeToStop.stop().catch((err) => {\n logger.warn('Failed to stop the bootstrap compiler service', { err })\n })\n esbuildStopPromise = stopPromise\n try {\n await stopPromise\n } finally {\n if (esbuildStopPromise === stopPromise) esbuildStopPromise = null\n }\n }\n }\n}\n\n/**\n * Thrown when an expected generated source file is absent.\n *\n * Optional registries treat this as the supported compatibility case (an app\n * that never generated the file), which is what makes it distinguishable from\n * a file that exists but fails to compile or import.\n */\nclass GeneratedFileNotFoundError extends Error {\n readonly filePath: string\n\n constructor(filePath: string) {\n super(`Generated file not found: ${filePath}`)\n this.name = 'GeneratedFileNotFoundError'\n this.filePath = filePath\n }\n}\n\n/**\n * esbuild plugins for the CLI bundle, in resolution order. The client-only stub must come\n * first so it wins over the alias and external plugins for `*.client` dynamic imports.\n *\n * Exported so the wiring itself is testable: a test that only exercises\n * `createClientOnlyStubPlugin` in isolation stays green if the plugin is dropped from this\n * list, which would silently reintroduce #4623.\n */\nexport function createCliBundlePlugins(appRoot: string): import('esbuild').Plugin[] {\n // Plugin to resolve the @/ alias the way the app tsconfig maps it:\n // `@/.mercato/*` to the app root, every other `@/*` to the app's src/ directory.\n const aliasPlugin: import('esbuild').Plugin = {\n name: 'alias-resolver',\n setup(build) {\n build.onResolve({ filter: /^@\\// }, (args) => {\n const rest = args.path.slice('@/'.length)\n const bases = rest.startsWith('.mercato/')\n ? [path.join(appRoot, rest)]\n : [path.join(appRoot, 'src', rest), path.join(appRoot, rest)]\n for (const base of bases) {\n if (fs.existsSync(base) && fs.statSync(base).isFile()) {\n return { path: base }\n }\n for (const suffix of ['.ts', '.tsx', '/index.ts', '/index.tsx']) {\n if (fs.existsSync(base + suffix)) {\n return { path: base + suffix }\n }\n }\n }\n // Nothing matched \u2014 hand esbuild the literal mapping so it reports the\n // missing file against the path the app author actually wrote.\n return { path: path.join(appRoot, rest) }\n })\n },\n }\n\n // Plugin to mark non-JSON package imports as external\n const externalNonJsonPlugin: import('esbuild').Plugin = {\n name: 'external-non-json',\n setup(build) {\n // Mark all package imports as external EXCEPT JSON files\n // Filter matches paths that don't start with . or / (package imports like @open-mercato/shared)\n build.onResolve({ filter: /^[^./]/ }, (args) => {\n // Skip Windows absolute paths (e.g., C:\\...) - they're local files, not packages\n if (/^[a-zA-Z]:/.test(args.path)) {\n return null // Let esbuild handle it\n }\n // If it's a JSON file, let esbuild bundle it\n if (args.path.endsWith('.json')) {\n return null // Let esbuild handle it\n }\n // Otherwise mark as external\n return { path: args.path, external: true }\n })\n },\n }\n\n return [createClientOnlyStubPlugin(), aliasPlugin, externalNonJsonPlugin]\n}\n\nconst DYNAMIC_LOADER_CACHE_VERSION = 4\n\ntype DynamicLoaderCacheMetadata = {\n version: number\n inputHash: string\n outputHash: string\n dependencies: Record<string, string>\n}\n\nfunction cacheMetadataPath(jsPath: string): string {\n return `${jsPath}.cache.json`\n}\n\nfunction contentHash(content: Buffer | string): string {\n return crypto.createHash('sha256').update(content).digest('hex')\n}\n\nfunction parseJsonConfig(content: string): unknown {\n let normalized = ''\n let inString = false\n let escaped = false\n\n for (let index = 0; index < content.length; index += 1) {\n const character = content[index]\n const nextCharacter = content[index + 1]\n\n if (inString) {\n normalized += character\n if (escaped) {\n escaped = false\n } else if (character === '\\\\') {\n escaped = true\n } else if (character === '\"') {\n inString = false\n }\n continue\n }\n\n if (character === '\"') {\n inString = true\n normalized += character\n continue\n }\n\n if (character === '/' && nextCharacter === '/') {\n while (index < content.length && content[index] !== '\\n') index += 1\n normalized += '\\n'\n continue\n }\n\n if (character === '/' && nextCharacter === '*') {\n index += 2\n while (index < content.length && !(content[index] === '*' && content[index + 1] === '/')) {\n index += 1\n }\n index += 1\n continue\n }\n\n if (character === ',') {\n let lookahead = index + 1\n while (lookahead < content.length && /\\s/.test(content[lookahead])) lookahead += 1\n if (content[lookahead] === '}' || content[lookahead] === ']') continue\n }\n\n normalized += character\n }\n\n return JSON.parse(normalized)\n}\n\nfunction resolveExistingConfigPath(candidate: string): string | null {\n for (const configPath of [candidate, `${candidate}.json`, path.join(candidate, 'tsconfig.json')]) {\n if (fs.existsSync(configPath) && fs.statSync(configPath).isFile()) return configPath\n }\n return null\n}\n\nfunction resolvePackageConfig(configPath: string, reference: string): string | null {\n try {\n const resolved = createRequire(pathToFileURL(configPath)).resolve(reference)\n return path.extname(resolved) === '.json' ? resolved : null\n } catch {\n return null\n }\n}\n\nfunction resolveExtendedConfig(configPath: string, reference: string): string {\n if (path.isAbsolute(reference) || reference.startsWith('.')) {\n const resolved = resolveExistingConfigPath(path.resolve(path.dirname(configPath), reference))\n if (resolved) return resolved\n } else {\n for (const packageReference of [reference, `${reference}/tsconfig.json`]) {\n const resolved = resolvePackageConfig(configPath, packageReference)\n if (resolved) return resolved\n }\n }\n\n throw new Error(`[internal] TypeScript config extends target not found: ${reference}`)\n}\n\nfunction collectTsconfigPaths(entryPath: string, visited: Set<string> = new Set()): string[] {\n const configPath = path.resolve(entryPath)\n if (visited.has(configPath)) return []\n visited.add(configPath)\n\n const parsed = parseJsonConfig(fs.readFileSync(configPath, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null || !('extends' in parsed)) return [configPath]\n\n const extendsValue = parsed.extends\n const references = typeof extendsValue === 'string'\n ? [extendsValue]\n : Array.isArray(extendsValue) && extendsValue.every((value) => typeof value === 'string')\n ? extendsValue\n : []\n\n return [\n ...references.flatMap((reference) => collectTsconfigPaths(\n resolveExtendedConfig(configPath, reference),\n visited,\n )),\n configPath,\n ]\n}\n\nfunction hashFilesRelativeTo(appRoot: string, filePaths: string[]): Record<string, string> {\n return Object.fromEntries(filePaths.map((filePath) => [\n path.relative(appRoot, filePath).split(path.sep).join('/'),\n contentHash(fs.readFileSync(filePath)),\n ]))\n}\n\nfunction cacheInputHash(tsPath: string, appRoot: string, tsconfigPaths: string[]): string {\n const hash = crypto.createHash('sha256')\n hash.update(JSON.stringify({\n version: DYNAMIC_LOADER_CACHE_VERSION,\n sourceHash: contentHash(fs.readFileSync(tsPath)),\n tsconfigHashes: hashFilesRelativeTo(appRoot, tsconfigPaths),\n }))\n return hash.digest('hex')\n}\n\nfunction dependenciesAreValid(appRoot: string, dependencies: Record<string, string>): boolean {\n return Object.entries(dependencies).every(([relativePath, expectedHash]) => {\n const dependencyPath = path.resolve(appRoot, relativePath)\n return fs.existsSync(dependencyPath)\n && contentHash(fs.readFileSync(dependencyPath)) === expectedHash\n })\n}\n\nfunction collectDependencyHashes(\n appRoot: string,\n inputs: Record<string, unknown>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.keys(inputs)\n .filter((inputPath) => !inputPath.startsWith(`${CLIENT_ONLY_STUB_NAMESPACE}:`))\n .map((inputPath) => {\n const absolutePath = path.isAbsolute(inputPath)\n ? inputPath\n : path.resolve(appRoot, inputPath)\n const relativePath = path.relative(appRoot, absolutePath).split(path.sep).join('/')\n return [relativePath, contentHash(fs.readFileSync(absolutePath))]\n })\n .sort(([left], [right]) => left.localeCompare(right)),\n )\n}\n\nfunction readCacheMetadata(metadataPath: string): DynamicLoaderCacheMetadata | null {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(metadataPath, 'utf8'))\n if (\n typeof parsed === 'object'\n && parsed !== null\n && 'version' in parsed\n && parsed.version === DYNAMIC_LOADER_CACHE_VERSION\n && 'inputHash' in parsed\n && typeof parsed.inputHash === 'string'\n && 'outputHash' in parsed\n && typeof parsed.outputHash === 'string'\n && 'dependencies' in parsed\n && typeof parsed.dependencies === 'object'\n && parsed.dependencies !== null\n && Object.values(parsed.dependencies).every((hash) => typeof hash === 'string')\n ) {\n return {\n version: parsed.version,\n inputHash: parsed.inputHash,\n outputHash: parsed.outputHash,\n dependencies: parsed.dependencies as Record<string, string>,\n }\n }\n } catch {\n return null\n }\n return null\n}\n\nfunction cacheIsValid(\n appRoot: string,\n jsPath: string,\n metadataPath: string,\n expectedInputHash: string,\n): boolean {\n if (!fs.existsSync(jsPath)) return false\n const metadata = readCacheMetadata(metadataPath)\n if (!metadata || metadata.inputHash !== expectedInputHash) return false\n return contentHash(fs.readFileSync(jsPath)) === metadata.outputHash\n && dependenciesAreValid(appRoot, metadata.dependencies)\n}\n\n/**\n * Options for `compileAndImport`.\n *\n * Both paths default to the generated-registry layout (`<appRoot>/.mercato/generated/<file>.ts`\n * compiled to a `.mjs` sibling). Sources that live elsewhere in the app \u2014 `src/di.ts` \u2014 MUST pass\n * both explicitly: the default app root is derived by walking three directories up from the source,\n * which only holds inside `.mercato/generated`.\n */\ntype CompileAndImportOptions = {\n appRoot?: string\n outFile?: string\n allowRecovery?: boolean\n}\n\n/**\n * Options for `compileAppSourceFile`.\n *\n * `appRoot` anchors the tsconfig, the `@/` alias resolution and the dependency\n * cache; `outFile` is the absolute path of the artifact to write. `format`\n * selects the module system of that artifact \u2014 `'cjs'` exists for the Jest\n * runtime, which cannot `import()` an ESM sibling.\n */\nexport type CompileAppSourceOptions = {\n appRoot: string\n outFile: string\n format?: 'esm' | 'cjs'\n}\n\n/**\n * Compile one app-owned TypeScript source and its relative import graph into a\n * single JavaScript artifact, leaving every package import external.\n *\n * This is the only supported way to load app source (`apps/<app>/src/**`,\n * `.mercato/generated/**`) from a plain Node process. Those files are never\n * compiled to `dist`, and Node's own type stripping cannot load them: it\n * requires explicit file extensions on relative specifiers and rejects the\n * decorator and enum syntax the entities and DI files use.\n *\n * The artifact is cached against the content of the entry, its whole bundled\n * dependency graph, and the tsconfig chain, so an edit anywhere in the graph\n * invalidates it.\n *\n * The build runs inside the shared esbuild lifecycle. Callers outside a\n * bootstrap load \u2014 the generated-registry loader compiling an `@app` module \u2014\n * would otherwise hold a build on a service another scope is entitled to\n * `stop()`, and would leave the helper process running afterwards. Nesting is\n * safe: the scope only releases the service when the last participant exits.\n */\nexport async function compileAppSourceFile(\n tsPath: string,\n options: CompileAppSourceOptions,\n): Promise<string> {\n return withEsbuildLifecycle(() => compileAppSourceFileWithActiveEsbuild(tsPath, options))\n}\n\nasync function compileAppSourceFileWithActiveEsbuild(\n tsPath: string,\n options: CompileAppSourceOptions,\n): Promise<string> {\n const { appRoot, outFile } = options\n const format = options.format ?? 'esm'\n const appTsconfig = path.join(appRoot, 'tsconfig.json')\n const metadataPath = cacheMetadataPath(outFile)\n\n const tsExists = fs.existsSync(tsPath)\n const tsconfigExists = fs.existsSync(appTsconfig)\n\n if (!tsExists) {\n throw new GeneratedFileNotFoundError(tsPath)\n }\n if (!tsconfigExists) {\n throw new Error(`App TypeScript config not found: ${appTsconfig}`)\n }\n\n const tsconfigPaths = collectTsconfigPaths(appTsconfig)\n const expectedInputHash = cacheInputHash(tsPath, appRoot, tsconfigPaths)\n\n if (cacheIsValid(appRoot, outFile, metadataPath, expectedInputHash)) {\n return outFile\n }\n\n fs.mkdirSync(path.dirname(outFile), { recursive: true })\n // Dynamically import esbuild only when needed\n const esbuild = await getEsbuildRuntime()\n\n // Use esbuild.build with bundling to handle JSON imports\n const result = await esbuild.build({\n entryPoints: [tsPath],\n outfile: outFile,\n absWorkingDir: appRoot,\n bundle: true,\n metafile: true,\n format,\n platform: 'node',\n target: 'node18',\n tsconfig: appTsconfig,\n plugins: createCliBundlePlugins(appRoot),\n // Allow JSON imports\n loader: { '.json': 'json' },\n })\n const metadata: DynamicLoaderCacheMetadata = {\n version: DYNAMIC_LOADER_CACHE_VERSION,\n inputHash: expectedInputHash,\n outputHash: contentHash(fs.readFileSync(outFile)),\n dependencies: {\n ...collectDependencyHashes(appRoot, result.metafile.inputs),\n ...hashFilesRelativeTo(appRoot, tsconfigPaths),\n },\n }\n fs.writeFileSync(metadataPath, JSON.stringify(metadata))\n\n return outFile\n}\n\n/**\n * Compile a TypeScript file to JavaScript using esbuild bundler.\n * This bundles the file and all its dependencies, handling JSON imports properly.\n * The compiled file is written next to the source file with a .mjs extension unless\n * `outFile` says otherwise.\n */\nasync function compileAndImport(\n tsPath: string,\n options: CompileAndImportOptions = {},\n): Promise<Record<string, unknown>> {\n const allowRecovery = options.allowRecovery ?? true\n const jsPath = options.outFile ?? tsPath.replace(/\\.ts$/, '.mjs')\n const appRoot = options.appRoot ?? path.dirname(path.dirname(path.dirname(tsPath)))\n\n await compileAppSourceFile(tsPath, { appRoot, outFile: jsPath })\n\n // Import the compiled JavaScript\n try {\n const outputHash = contentHash(fs.readFileSync(jsPath))\n const fileUrl = `${pathToFileURL(jsPath).href}?cache=${outputHash}`\n return await import(fileUrl)\n } catch (error) {\n if (!allowRecovery) {\n throw error\n }\n\n const recovered = recoverMikroOrmV7GeneratedCacheFromImportError(appRoot, error)\n if (!recovered.applied) {\n throw error\n }\n\n return compileAndImport(tsPath, { ...options, allowRecovery: false })\n }\n}\n\n\n/**\n * Load a generated registry that older apps may not have generated yet.\n *\n * An absent source file is the supported compatibility case and resolves to\n * `fallback` quietly. Any other failure \u2014 a compile error, a broken import, a\n * runtime throw at module scope \u2014 still resolves to `fallback` so bootstrap\n * keeps working, but is reported at error level: a registry that silently\n * degrades to nothing is exactly how command interceptors stopped applying in\n * worker/CLI processes (#4327, #4491).\n */\nasync function loadOptionalGeneratedModule(\n tsPath: string,\n fallback: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n try {\n return await compileAndImport(tsPath)\n } catch (error) {\n if (error instanceof GeneratedFileNotFoundError) {\n logger.debug('Optional generated registry not present, using empty fallback', {\n file: path.basename(tsPath),\n })\n return fallback\n }\n\n logger.error('Failed to load generated registry, continuing without its entries', {\n file: path.basename(tsPath),\n filePath: tsPath,\n err: error,\n })\n return fallback\n }\n}\n\nfunction resolveAppRootOrThrow(appRoot?: string): AppRoot {\n const resolved: AppRoot | null = appRoot\n ? {\n generatedDir: path.join(appRoot, '.mercato', 'generated'),\n appDir: appRoot,\n mercatoDir: path.join(appRoot, '.mercato'),\n }\n : findAppRoot()\n\n if (!resolved) {\n throw new Error(\n 'Could not find app root with .mercato/generated directory. ' +\n 'Make sure you run this command from within a Next.js app directory, ' +\n 'or run \"yarn mercato generate\" first to create the generated files.',\n )\n }\n\n return resolved\n}\n\n/**\n * Load the app-level DI registrar (`src/di.ts`) for the dynamic bootstrap path.\n *\n * The Next.js runtime imports `@/di` statically from its own `src/bootstrap.ts` and hands the\n * registrar to `createBootstrap`. Worker, scheduler and CLI processes bootstrap through\n * `bootstrapFromAppRoot` instead, where the `@/` alias does not exist \u2014 so without this the app's\n * DI registrations silently never ran there, and every request container paid a failed\n * `import('@/di')` resolution (the compatibility fallback in `lib/di/container.ts`).\n *\n * An absent `src/di.ts` is the supported case and resolves to `null` quietly. A file that exists\n * but cannot be compiled, imported, or does not export `register` is reported at error level and\n * still resolves to `null`, so a broken app DI module degrades the same way a broken generated\n * registry does (#4327, #4491) instead of taking the whole process down.\n */\nasync function loadAppDiRegistrar(appDir: string): Promise<AppDiRegistrar | null> {\n const tsPath = path.join(appDir, 'src', 'di.ts')\n if (!fs.existsSync(tsPath)) {\n logger.debug('App-level DI module not present, skipping its registrations', { filePath: tsPath })\n return null\n }\n\n try {\n const appDiModule = await compileAndImport(tsPath, {\n appRoot: appDir,\n outFile: path.join(appDir, '.mercato', 'generated', 'app-di.compiled.mjs'),\n })\n const register = appDiModule.register\n if (typeof register !== 'function') {\n logger.error('App-level DI module exports no register(); its registrations are skipped', {\n filePath: tsPath,\n })\n return null\n }\n return register as AppDiRegistrar\n } catch (error) {\n logger.error('Failed to load the app-level DI module; its registrations are skipped', {\n filePath: tsPath,\n err: error,\n })\n return null\n }\n}\n\n/**\n * Dynamically load bootstrap data from a resolved app directory.\n *\n * IMPORTANT: This only works in unbundled contexts (CLI, tsx).\n * Do NOT use this in Next.js bundled code - use static imports instead.\n *\n * For CLI context, we skip loading modules.generated.ts which has Next.js dependencies.\n * CLI commands are discovered separately via the CLI module system.\n *\n * @param appRoot - Optional explicit app root path. If not provided, will search from cwd.\n * @returns The loaded bootstrap data\n * @throws Error if app root cannot be found or generated files are missing\n */\nasync function loadBootstrapDataWithActiveEsbuild(appRoot?: string): Promise<BootstrapData> {\n const resolved = resolveAppRootOrThrow(appRoot)\n\n const { generatedDir } = resolved\n\n ensureMikroOrmV7GeneratedCacheCompatibility(resolved.appDir)\n\n // IMPORTANT: Load entity IDs FIRST and register them before loading modules.\n // This is because modules (e.g., ce.ts files) use E.xxx.xxx at module scope,\n // and they need entity IDs to be available when they're imported.\n const entityIdsModule = await compileAndImport(path.join(generatedDir, 'entities.ids.generated.ts'))\n registerEntityIds(entityIdsModule.E as BootstrapData['entityIds'])\n\n // Now load the rest of the generated files.\n // modules.cli.generated.ts excludes Next.js-dependent code (routes, APIs, widgets)\n const [\n modulesModule,\n entitiesModule,\n diModule,\n searchModule,\n commandLoadersModule,\n commandInterceptorsModule,\n workflowsModule,\n ] = await Promise.all([\n compileAndImport(path.join(generatedDir, 'modules.cli.generated.ts')),\n compileAndImport(path.join(generatedDir, 'entities.generated.ts')),\n compileAndImport(path.join(generatedDir, 'di.generated.ts')),\n loadOptionalGeneratedModule(path.join(generatedDir, 'search.generated.ts'), { searchModuleConfigs: [] }),\n loadOptionalGeneratedModule(path.join(generatedDir, 'command-loaders.generated.ts'), { commandLoaderEntries: [] }),\n loadOptionalGeneratedModule(path.join(generatedDir, 'command-interceptors.generated.ts'), {\n commandInterceptorEntries: [],\n }),\n loadOptionalGeneratedModule(path.join(generatedDir, 'workflows.generated.ts'), { allCodeWorkflows: [] }),\n ])\n\n return {\n modules: modulesModule.modules as BootstrapData['modules'],\n entities: entitiesModule.entities as BootstrapData['entities'],\n diRegistrars: diModule.diRegistrars as BootstrapData['diRegistrars'],\n entityIds: entityIdsModule.E as BootstrapData['entityIds'],\n // Search configs are needed by workers for indexing\n searchModuleConfigs: (searchModule.searchModuleConfigs ?? []) as BootstrapData['searchModuleConfigs'],\n commandLoaderEntries: (commandLoadersModule.commandLoaderEntries ?? []) as BootstrapData['commandLoaderEntries'],\n // Command interceptors must apply in worker/CLI processes too \u2014 the\n // interceptor registry is per-process, so relying on the Next.js runtime's\n // registration silently no-ops every interceptor for queued/CLI commands\n // (#4327).\n commandInterceptorEntries: (commandInterceptorsModule.commandInterceptorEntries ??\n []) as BootstrapData['commandInterceptorEntries'],\n // Code workflow definitions are needed by workers to resume code-defined instances\n codeWorkflows: (workflowsModule.allCodeWorkflows ?? []) as BootstrapData['codeWorkflows'],\n // Empty UI-related data - not needed for CLI\n dashboardWidgetEntries: [],\n injectionWidgetEntries: [],\n injectionTables: [],\n interceptorEntries: [],\n componentOverrideEntries: [],\n }\n}\n\nexport async function loadBootstrapData(appRoot?: string): Promise<BootstrapData> {\n return withEsbuildLifecycle(() => loadBootstrapDataWithActiveEsbuild(appRoot))\n}\n\n/**\n * Create and execute bootstrap in CLI context.\n *\n * This is a convenience function that finds the app root, loads the generated\n * data dynamically, and runs bootstrap. Use this in CLI entry points.\n *\n * Returns the loaded bootstrap data so the CLI can register modules directly\n * (avoids module resolution issues when importing @open-mercato/cli/mercato).\n *\n * @param appRoot - Optional explicit app root path\n * @returns The loaded bootstrap data (modules, entities, etc.)\n */\nexport async function bootstrapFromAppRoot(appRoot?: string): Promise<BootstrapData> {\n const { createBootstrap, waitForAsyncRegistration } = await import('./factory.js')\n const resolved = resolveAppRootOrThrow(appRoot)\n // Both loads compile through esbuild, so they share one lifecycle scope: without it\n // `loadBootstrapData` releases the esbuild helper process and `loadAppDiRegistrar`\n // silently starts a second one that nothing ever stops.\n const { data, appDiRegistrar } = await withEsbuildLifecycle(async () => ({\n data: await loadBootstrapData(resolved.appDir),\n appDiRegistrar: await loadAppDiRegistrar(resolved.appDir),\n }))\n const bootstrap = createBootstrap(data, appDiRegistrar ? { appDiRegistrar } : {})\n bootstrap()\n // In CLI context, wait for async registrations (UI widgets, search configs, etc.)\n await waitForAsyncRegistration()\n\n return data\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,15 +15,16 @@ import { registerCommandLoaders } from "../commands/registry.js";
|
|
|
15
15
|
import { registerNotificationHandlers } from "../notifications/handler-registry.js";
|
|
16
16
|
import { clearRegisteredIntegrations, registerBundles, registerIntegrations } from "../../modules/integrations/types.js";
|
|
17
17
|
import { applyComponentOverridesToEntries } from "../../modules/overrides.js";
|
|
18
|
-
|
|
18
|
+
const _bootstrappedKeys = /* @__PURE__ */ new Set();
|
|
19
19
|
let _asyncRegistrationPromise = null;
|
|
20
20
|
function createBootstrap(data, options = {}) {
|
|
21
21
|
return function bootstrap() {
|
|
22
|
+
const registrationKey = options.registrationKey ?? "default";
|
|
22
23
|
if (options.appDiRegistrar) {
|
|
23
24
|
registerAppDiRegistrar(options.appDiRegistrar);
|
|
24
25
|
}
|
|
25
|
-
if (
|
|
26
|
-
|
|
26
|
+
if (_bootstrappedKeys.has(registrationKey) && process.env.NODE_ENV !== "development") return;
|
|
27
|
+
_bootstrappedKeys.add(registrationKey);
|
|
27
28
|
registerOrmEntities(data.entities);
|
|
28
29
|
registerDiRegistrars(data.diRegistrars.filter((r) => r != null));
|
|
29
30
|
registerModules(data.modules);
|
|
@@ -84,26 +85,30 @@ async function waitForAsyncRegistration() {
|
|
|
84
85
|
}
|
|
85
86
|
async function registerWidgetsAndOptionalPackages(data, options) {
|
|
86
87
|
try {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
]);
|
|
92
|
-
dashboardRegistry.registerDashboardWidgets(data.dashboardWidgetEntries);
|
|
93
|
-
injectionRegistry.registerInjectionWidgets(data.injectionWidgetEntries);
|
|
94
|
-
coreInjection.registerCoreInjectionWidgets(data.injectionWidgetEntries);
|
|
88
|
+
const coreInjection = await import("@open-mercato/core/modules/widgets/lib/injection");
|
|
89
|
+
if (!options.skipCoreInjectionWidgets) {
|
|
90
|
+
coreInjection.registerCoreInjectionWidgets(data.injectionWidgetEntries);
|
|
91
|
+
}
|
|
95
92
|
coreInjection.registerCoreInjectionTables(data.injectionTables);
|
|
96
93
|
coreInjection.registerEnabledModuleIds(
|
|
97
94
|
data.modules.map((module) => module.id).filter((id) => typeof id === "string" && id.length > 0)
|
|
98
95
|
);
|
|
96
|
+
if (!options.skipUiRegistries) {
|
|
97
|
+
const [dashboardRegistry, injectionRegistry] = await Promise.all([
|
|
98
|
+
import("@open-mercato/ui/backend/dashboard/widgetRegistry"),
|
|
99
|
+
import("@open-mercato/ui/backend/injection/widgetRegistry")
|
|
100
|
+
]);
|
|
101
|
+
dashboardRegistry.registerDashboardWidgets(data.dashboardWidgetEntries);
|
|
102
|
+
injectionRegistry.registerInjectionWidgets(data.injectionWidgetEntries);
|
|
103
|
+
}
|
|
99
104
|
} catch {
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
function isBootstrapped() {
|
|
103
|
-
return
|
|
108
|
+
return _bootstrappedKeys.size > 0;
|
|
104
109
|
}
|
|
105
110
|
function resetBootstrapState() {
|
|
106
|
-
|
|
111
|
+
_bootstrappedKeys.clear();
|
|
107
112
|
}
|
|
108
113
|
export {
|
|
109
114
|
createBootstrap,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/bootstrap/factory.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BootstrapData, BootstrapOptions } from './types'\nimport { registerOrmEntities } from '../db/mikro'\nimport { registerAppDiRegistrar, registerDiRegistrars } from '../di/container'\nimport { registerModules } from '../modules/registry'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport { registerEntityFields } from '../encryption/entityFields'\nimport { registerSearchModuleConfigs } from '../../modules/search'\nimport { registerAnalyticsModuleConfigs } from '../../modules/analytics'\nimport { registerCodeWorkflowEntries } from '../../modules/workflows/code-registry'\nimport { registerResponseEnrichers } from '../crud/enricher-registry'\nimport { registerApiInterceptors } from '../crud/interceptor-registry'\nimport { registerComponentOverrides } from '../../modules/widgets/component-registry'\nimport { registerMutationGuards } from '../crud/mutation-guard-store'\nimport { registerCommandInterceptors } from '../commands/command-interceptor-store'\nimport { registerCommandLoaders } from '../commands/registry'\nimport { registerNotificationHandlers } from '../notifications/handler-registry'\nimport { clearRegisteredIntegrations, registerBundles, registerIntegrations } from '../../modules/integrations/types'\nimport { applyComponentOverridesToEntries } from '../../modules/overrides'\n\
|
|
5
|
-
"mappings": "AACA,SAAS,2BAA2B;AACpC,SAAS,wBAAwB,4BAA4B;AAC7D,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,mCAAmC;AAC5C,SAAS,sCAAsC;AAC/C,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AAC1C,SAAS,+BAA+B;AACxC,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AACvC,SAAS,mCAAmC;AAC5C,SAAS,8BAA8B;AACvC,SAAS,oCAAoC;AAC7C,SAAS,6BAA6B,iBAAiB,4BAA4B;AACnF,SAAS,wCAAwC;AAEjD,
|
|
4
|
+
"sourcesContent": ["import type { BootstrapData, BootstrapOptions } from './types'\nimport { registerOrmEntities } from '../db/mikro'\nimport { registerAppDiRegistrar, registerDiRegistrars } from '../di/container'\nimport { registerModules } from '../modules/registry'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport { registerEntityFields } from '../encryption/entityFields'\nimport { registerSearchModuleConfigs } from '../../modules/search'\nimport { registerAnalyticsModuleConfigs } from '../../modules/analytics'\nimport { registerCodeWorkflowEntries } from '../../modules/workflows/code-registry'\nimport { registerResponseEnrichers } from '../crud/enricher-registry'\nimport { registerApiInterceptors } from '../crud/interceptor-registry'\nimport { registerComponentOverrides } from '../../modules/widgets/component-registry'\nimport { registerMutationGuards } from '../crud/mutation-guard-store'\nimport { registerCommandInterceptors } from '../commands/command-interceptor-store'\nimport { registerCommandLoaders } from '../commands/registry'\nimport { registerNotificationHandlers } from '../notifications/handler-registry'\nimport { clearRegisteredIntegrations, registerBundles, registerIntegrations } from '../../modules/integrations/types'\nimport { applyComponentOverridesToEntries } from '../../modules/overrides'\n\nconst _bootstrappedKeys = new Set<string>()\n\n// Store the async registration promise so callers can await it if needed\nlet _asyncRegistrationPromise: Promise<void> | null = null\n\n/**\n * Creates a bootstrap function that registers all application dependencies.\n *\n * The returned function should be called once at application startup.\n * In development mode, it can be called multiple times (for HMR).\n *\n * @param data - All generated registry data from .mercato/generated/\n * @param options - Optional configuration\n * @returns A bootstrap function to call at app startup\n */\nexport function createBootstrap(data: BootstrapData, options: BootstrapOptions = {}) {\n return function bootstrap(): void {\n const registrationKey = options.registrationKey ?? 'default'\n if (options.appDiRegistrar) {\n registerAppDiRegistrar(options.appDiRegistrar)\n }\n // In development, always re-run registrations to handle HMR\n // (Module state may be reset when Turbopack reloads packages)\n if (_bootstrappedKeys.has(registrationKey) && process.env.NODE_ENV !== 'development') return\n _bootstrappedKeys.add(registrationKey)\n\n // === 1. Foundation: ORM entities and DI registrars ===\n registerOrmEntities(data.entities)\n registerDiRegistrars(data.diRegistrars.filter((r): r is NonNullable<typeof r> => r != null))\n\n // === 2. Modules registry (required by i18n, query engine, dashboards, CLI) ===\n registerModules(data.modules)\n clearRegisteredIntegrations()\n for (const module of data.modules) {\n if (module.integrations?.length) {\n registerIntegrations(module.integrations)\n }\n if (module.bundles?.length) {\n registerBundles(module.bundles)\n }\n }\n\n // === 3. Entity IDs (required by encryption, indexing, entity links) ===\n registerEntityIds(data.entityIds)\n\n // === 4. Entity fields registry (for encryption manager, Turbopack compatibility) ===\n if (data.entityFieldsRegistry) {\n registerEntityFields(data.entityFieldsRegistry)\n }\n\n // === 5. Search module configs (for search service registration in DI) ===\n if (data.searchModuleConfigs) {\n registerSearchModuleConfigs(data.searchModuleConfigs)\n }\n\n // === 6. Analytics module configs (for dashboard widgets and analytics API) ===\n if (data.analyticsModuleConfigs) {\n registerAnalyticsModuleConfigs(data.analyticsModuleConfigs)\n }\n\n // === 6a. Code workflow definitions (so CLI/worker processes resolve them like the app runtime) ===\n if (data.codeWorkflows?.length) {\n registerCodeWorkflowEntries(data.codeWorkflows)\n }\n\n // === 6b. Response enrichers (for CRUD response enrichment) ===\n if (data.enricherEntries) {\n registerResponseEnrichers(data.enricherEntries)\n }\n\n // === 6c. API interceptors (for CRUD route interception) ===\n if (data.interceptorEntries) {\n registerApiInterceptors(data.interceptorEntries)\n }\n\n // === 6d. Component overrides (for page/component replacement) ===\n if (data.componentOverrideEntries) {\n const finalEntries = applyComponentOverridesToEntries(data.componentOverrideEntries)\n const allOverrides = finalEntries.flatMap((entry) => entry.componentOverrides ?? [])\n registerComponentOverrides(allOverrides)\n }\n\n // === 6e. Mutation guards (for CRUD mutation lifecycle) ===\n if (data.guardEntries) {\n registerMutationGuards(data.guardEntries)\n }\n\n // === 6f. Command interceptors (for command bus lifecycle) ===\n if (data.commandInterceptorEntries) {\n registerCommandInterceptors(data.commandInterceptorEntries)\n }\n\n // === 6f.1. Command loaders (for lazy command handler registration) ===\n if (data.commandLoaderEntries) {\n registerCommandLoaders(data.commandLoaderEntries)\n }\n\n // === 6g. Notification handlers (reactive notification side-effects) ===\n if (data.notificationHandlerEntries) {\n registerNotificationHandlers(data.notificationHandlerEntries)\n }\n\n // === 7-8. UI Widgets and Optional packages (async to avoid circular deps) ===\n // Store the promise so CLI context can await it\n _asyncRegistrationPromise = registerWidgetsAndOptionalPackages(data, options)\n void _asyncRegistrationPromise\n\n options.onRegistrationComplete?.()\n }\n}\n\n/**\n * Wait for async registrations (CLI modules, widgets, etc.) to complete.\n * Call this after bootstrap() in CLI context where you need modules immediately.\n */\nexport async function waitForAsyncRegistration(): Promise<void> {\n if (_asyncRegistrationPromise) {\n await _asyncRegistrationPromise\n }\n}\n\nasync function registerWidgetsAndOptionalPackages(data: BootstrapData, options: BootstrapOptions): Promise<void> {\n // Register widget data required by server-side injection independently from\n // browser-facing UI registries. API-only bootstraps avoid loading @open-mercato/ui.\n try {\n const coreInjection = await import('@open-mercato/core/modules/widgets/lib/injection')\n if (!options.skipCoreInjectionWidgets) {\n coreInjection.registerCoreInjectionWidgets(data.injectionWidgetEntries)\n }\n coreInjection.registerCoreInjectionTables(data.injectionTables)\n coreInjection.registerEnabledModuleIds(\n data.modules.map((module) => module.id).filter((id): id is string => typeof id === 'string' && id.length > 0),\n )\n\n if (!options.skipUiRegistries) {\n const [dashboardRegistry, injectionRegistry] = await Promise.all([\n import('@open-mercato/ui/backend/dashboard/widgetRegistry'),\n import('@open-mercato/ui/backend/injection/widgetRegistry'),\n ])\n dashboardRegistry.registerDashboardWidgets(data.dashboardWidgetEntries)\n injectionRegistry.registerInjectionWidgets(data.injectionWidgetEntries)\n }\n } catch {\n // UI packages may not be available in all contexts\n }\n\n // Note: Search module configs are registered synchronously in the main bootstrap.\n // The actual registerSearchModule() call happens in core/bootstrap.ts when the\n // DI container is created, using getSearchModuleConfigs() from the global registry.\n\n // Note: CLI module registration is handled separately in CLI context\n // via bootstrapFromAppRoot in dynamicLoader. We don't import CLI here\n // to avoid Turbopack tracing through the CLI package in Next.js context.\n}\n\n/**\n * Check if bootstrap has been called.\n */\nexport function isBootstrapped(): boolean {\n return _bootstrappedKeys.size > 0\n}\n\n/**\n * Reset bootstrap state. Useful for testing.\n */\nexport function resetBootstrapState(): void {\n _bootstrappedKeys.clear()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|