@open-mercato/shared 0.4.2-canary-c02407ff85
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/build.mjs +101 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/api/crud.js +47 -0
- package/dist/lib/api/crud.js.map +7 -0
- package/dist/lib/api/scoped.js +140 -0
- package/dist/lib/api/scoped.js.map +7 -0
- package/dist/lib/auth/jwt.js +34 -0
- package/dist/lib/auth/jwt.js.map +7 -0
- package/dist/lib/auth/server.js +157 -0
- package/dist/lib/auth/server.js.map +7 -0
- package/dist/lib/boolean.js +22 -0
- package/dist/lib/boolean.js.map +7 -0
- package/dist/lib/bootstrap/appResolver.js +43 -0
- package/dist/lib/bootstrap/appResolver.js.map +7 -0
- package/dist/lib/bootstrap/dynamicLoader.js +108 -0
- package/dist/lib/bootstrap/dynamicLoader.js.map +7 -0
- package/dist/lib/bootstrap/factory.js +59 -0
- package/dist/lib/bootstrap/factory.js.map +7 -0
- package/dist/lib/bootstrap/index.js +11 -0
- package/dist/lib/bootstrap/index.js.map +7 -0
- package/dist/lib/bootstrap/types.js +1 -0
- package/dist/lib/bootstrap/types.js.map +7 -0
- package/dist/lib/cache/segments.js +36 -0
- package/dist/lib/cache/segments.js.map +7 -0
- package/dist/lib/cli/progress.js +46 -0
- package/dist/lib/cli/progress.js.map +7 -0
- package/dist/lib/commands/command-bus.js +285 -0
- package/dist/lib/commands/command-bus.js.map +7 -0
- package/dist/lib/commands/customFieldSnapshots.js +66 -0
- package/dist/lib/commands/customFieldSnapshots.js.map +7 -0
- package/dist/lib/commands/helpers.js +98 -0
- package/dist/lib/commands/helpers.js.map +7 -0
- package/dist/lib/commands/index.js +8 -0
- package/dist/lib/commands/index.js.map +7 -0
- package/dist/lib/commands/operationMetadata.js +32 -0
- package/dist/lib/commands/operationMetadata.js.map +7 -0
- package/dist/lib/commands/registry.js +43 -0
- package/dist/lib/commands/registry.js.map +7 -0
- package/dist/lib/commands/scope.js +44 -0
- package/dist/lib/commands/scope.js.map +7 -0
- package/dist/lib/commands/types.js +8 -0
- package/dist/lib/commands/types.js.map +7 -0
- package/dist/lib/crud/cache-stats.js +98 -0
- package/dist/lib/crud/cache-stats.js.map +7 -0
- package/dist/lib/crud/cache.js +175 -0
- package/dist/lib/crud/cache.js.map +7 -0
- package/dist/lib/crud/custom-fields-client.js +52 -0
- package/dist/lib/crud/custom-fields-client.js.map +7 -0
- package/dist/lib/crud/custom-fields.js +467 -0
- package/dist/lib/crud/custom-fields.js.map +7 -0
- package/dist/lib/crud/errors.js +24 -0
- package/dist/lib/crud/errors.js.map +7 -0
- package/dist/lib/crud/exporters.js +154 -0
- package/dist/lib/crud/exporters.js.map +7 -0
- package/dist/lib/crud/factory.js +1311 -0
- package/dist/lib/crud/factory.js.map +7 -0
- package/dist/lib/crud/types.js +1 -0
- package/dist/lib/crud/types.js.map +7 -0
- package/dist/lib/custom-fields/normalize.js +36 -0
- package/dist/lib/custom-fields/normalize.js.map +7 -0
- package/dist/lib/data/engine.js +396 -0
- package/dist/lib/data/engine.js.map +7 -0
- package/dist/lib/db/escapeLikePattern.js +5 -0
- package/dist/lib/db/escapeLikePattern.js.map +7 -0
- package/dist/lib/db/mikro.js +82 -0
- package/dist/lib/db/mikro.js.map +7 -0
- package/dist/lib/di/container.js +94 -0
- package/dist/lib/di/container.js.map +7 -0
- package/dist/lib/email/send.js +12 -0
- package/dist/lib/email/send.js.map +7 -0
- package/dist/lib/encryption/aes.js +58 -0
- package/dist/lib/encryption/aes.js.map +7 -0
- package/dist/lib/encryption/customFieldValues.js +49 -0
- package/dist/lib/encryption/customFieldValues.js.map +7 -0
- package/dist/lib/encryption/entityFields.js +26 -0
- package/dist/lib/encryption/entityFields.js.map +7 -0
- package/dist/lib/encryption/entityIds.js +80 -0
- package/dist/lib/encryption/entityIds.js.map +7 -0
- package/dist/lib/encryption/find.js +45 -0
- package/dist/lib/encryption/find.js.map +7 -0
- package/dist/lib/encryption/indexDoc.js +69 -0
- package/dist/lib/encryption/indexDoc.js.map +7 -0
- package/dist/lib/encryption/kms.js +282 -0
- package/dist/lib/encryption/kms.js.map +7 -0
- package/dist/lib/encryption/subscriber.js +330 -0
- package/dist/lib/encryption/subscriber.js.map +7 -0
- package/dist/lib/encryption/tenantDataEncryptionService.js +252 -0
- package/dist/lib/encryption/tenantDataEncryptionService.js.map +7 -0
- package/dist/lib/encryption/toggles.js +18 -0
- package/dist/lib/encryption/toggles.js.map +7 -0
- package/dist/lib/entities/naming.js +9 -0
- package/dist/lib/entities/naming.js.map +7 -0
- package/dist/lib/entities/system-entities.js +43 -0
- package/dist/lib/entities/system-entities.js.map +7 -0
- package/dist/lib/frontend/organizationEvents.js +41 -0
- package/dist/lib/frontend/organizationEvents.js.map +7 -0
- package/dist/lib/frontend/useOrganizationScope.js +32 -0
- package/dist/lib/frontend/useOrganizationScope.js.map +7 -0
- package/dist/lib/hotkeys/index.js +128 -0
- package/dist/lib/hotkeys/index.js.map +7 -0
- package/dist/lib/i18n/app-dictionaries.js +17 -0
- package/dist/lib/i18n/app-dictionaries.js.map +7 -0
- package/dist/lib/i18n/config.js +7 -0
- package/dist/lib/i18n/config.js.map +7 -0
- package/dist/lib/i18n/context.js +50 -0
- package/dist/lib/i18n/context.js.map +7 -0
- package/dist/lib/i18n/server.js +68 -0
- package/dist/lib/i18n/server.js.map +7 -0
- package/dist/lib/i18n/translate.js +45 -0
- package/dist/lib/i18n/translate.js.map +7 -0
- package/dist/lib/indexers/error-log.js +82 -0
- package/dist/lib/indexers/error-log.js.map +7 -0
- package/dist/lib/indexers/status-log.js +80 -0
- package/dist/lib/indexers/status-log.js.map +7 -0
- package/dist/lib/lib/auth/jwt.js +34 -0
- package/dist/lib/lib/auth/jwt.js.map +7 -0
- package/dist/lib/lib/auth/server.js +77 -0
- package/dist/lib/lib/auth/server.js.map +7 -0
- package/dist/lib/lib/email/send.js +12 -0
- package/dist/lib/lib/email/send.js.map +7 -0
- package/dist/lib/lib/i18n/config.js +7 -0
- package/dist/lib/lib/i18n/config.js.map +7 -0
- package/dist/lib/lib/i18n/context.js +31 -0
- package/dist/lib/lib/i18n/context.js.map +7 -0
- package/dist/lib/lib/utils.js +9 -0
- package/dist/lib/lib/utils.js.map +7 -0
- package/dist/lib/location/countries.js +68 -0
- package/dist/lib/location/countries.js.map +7 -0
- package/dist/lib/modules/index.js +6 -0
- package/dist/lib/modules/index.js.map +7 -0
- package/dist/lib/modules/registry.js +18 -0
- package/dist/lib/modules/registry.js.map +7 -0
- package/dist/lib/openapi/crud.js +137 -0
- package/dist/lib/openapi/crud.js.map +7 -0
- package/dist/lib/openapi/generator.js +1131 -0
- package/dist/lib/openapi/generator.js.map +7 -0
- package/dist/lib/openapi/index.js +10 -0
- package/dist/lib/openapi/index.js.map +7 -0
- package/dist/lib/openapi/sanitize.js +110 -0
- package/dist/lib/openapi/sanitize.js.map +7 -0
- package/dist/lib/openapi/types.js +1 -0
- package/dist/lib/openapi/types.js.map +7 -0
- package/dist/lib/profiler/index.js +258 -0
- package/dist/lib/profiler/index.js.map +7 -0
- package/dist/lib/query/engine.js +729 -0
- package/dist/lib/query/engine.js.map +7 -0
- package/dist/lib/query/join-utils.js +195 -0
- package/dist/lib/query/join-utils.js.map +7 -0
- package/dist/lib/query/types.js +9 -0
- package/dist/lib/query/types.js.map +7 -0
- package/dist/lib/search/config.js +32 -0
- package/dist/lib/search/config.js.map +7 -0
- package/dist/lib/search/tokenize.js +34 -0
- package/dist/lib/search/tokenize.js.map +7 -0
- package/dist/lib/slugify.js +24 -0
- package/dist/lib/slugify.js.map +7 -0
- package/dist/lib/testing/bootstrap.js +51 -0
- package/dist/lib/testing/bootstrap.js.map +7 -0
- package/dist/lib/testing/index.js +17 -0
- package/dist/lib/testing/index.js.map +7 -0
- package/dist/lib/testing/renderWithProviders.js +15 -0
- package/dist/lib/testing/renderWithProviders.js.map +7 -0
- package/dist/lib/url.js +12 -0
- package/dist/lib/url.js.map +7 -0
- package/dist/lib/utils.js +13 -0
- package/dist/lib/utils.js.map +7 -0
- package/dist/lib/version.js +7 -0
- package/dist/lib/version.js.map +7 -0
- package/dist/modules/dashboard/widgets.js +1 -0
- package/dist/modules/dashboard/widgets.js.map +7 -0
- package/dist/modules/dsl.js +30 -0
- package/dist/modules/dsl.js.map +7 -0
- package/dist/modules/entities/kinds.js +22 -0
- package/dist/modules/entities/kinds.js.map +7 -0
- package/dist/modules/entities/options.js +26 -0
- package/dist/modules/entities/options.js.map +7 -0
- package/dist/modules/entities/validation.js +102 -0
- package/dist/modules/entities/validation.js.map +7 -0
- package/dist/modules/entities/validators.js +88 -0
- package/dist/modules/entities/validators.js.map +7 -0
- package/dist/modules/entities.js +1 -0
- package/dist/modules/entities.js.map +7 -0
- package/dist/modules/navigation/sidebarPreferences.js +50 -0
- package/dist/modules/navigation/sidebarPreferences.js.map +7 -0
- package/dist/modules/perspectives/types.js +1 -0
- package/dist/modules/perspectives/types.js.map +7 -0
- package/dist/modules/registry.js +96 -0
- package/dist/modules/registry.js.map +7 -0
- package/dist/modules/search.js +15 -0
- package/dist/modules/search.js.map +7 -0
- package/dist/modules/vector.js +1 -0
- package/dist/modules/vector.js.map +7 -0
- package/dist/modules/widgets/injection-loader.js +180 -0
- package/dist/modules/widgets/injection-loader.js.map +7 -0
- package/dist/modules/widgets/injection.js +1 -0
- package/dist/modules/widgets/injection.js.map +7 -0
- package/dist/security/features.js +23 -0
- package/dist/security/features.js.map +7 -0
- package/dist/types/pg.d.js +1 -0
- package/dist/types/pg.d.js.map +7 -0
- package/dist/types/react-email.d.js +1 -0
- package/dist/types/react-email.d.js.map +7 -0
- package/dist/types/resend.d.js +1 -0
- package/dist/types/resend.d.js.map +7 -0
- package/jest.config.cjs +22 -0
- package/package.json +88 -0
- package/src/index.ts +0 -0
- package/src/lib/api/__tests__/scoped.test.ts +38 -0
- package/src/lib/api/crud.ts +59 -0
- package/src/lib/api/scoped.ts +239 -0
- package/src/lib/auth/jwt.ts +39 -0
- package/src/lib/auth/server.ts +199 -0
- package/src/lib/boolean.ts +17 -0
- package/src/lib/bootstrap/appResolver.ts +85 -0
- package/src/lib/bootstrap/dynamicLoader.ts +177 -0
- package/src/lib/bootstrap/factory.ts +108 -0
- package/src/lib/bootstrap/index.ts +23 -0
- package/src/lib/bootstrap/types.ts +31 -0
- package/src/lib/cache/segments.ts +56 -0
- package/src/lib/cli/progress.ts +55 -0
- package/src/lib/commands/__tests__/command-bus.test.ts +84 -0
- package/src/lib/commands/__tests__/helpers.test.ts +42 -0
- package/src/lib/commands/command-bus.ts +349 -0
- package/src/lib/commands/customFieldSnapshots.ts +86 -0
- package/src/lib/commands/helpers.ts +143 -0
- package/src/lib/commands/index.ts +4 -0
- package/src/lib/commands/operationMetadata.ts +40 -0
- package/src/lib/commands/registry.ts +46 -0
- package/src/lib/commands/scope.ts +59 -0
- package/src/lib/commands/types.ts +63 -0
- package/src/lib/crud/__tests__/crud-factory.test.ts +333 -0
- package/src/lib/crud/__tests__/custom-fields.test.ts +150 -0
- package/src/lib/crud/cache-stats.ts +127 -0
- package/src/lib/crud/cache.ts +205 -0
- package/src/lib/crud/custom-fields-client.ts +54 -0
- package/src/lib/crud/custom-fields.ts +607 -0
- package/src/lib/crud/errors.ts +23 -0
- package/src/lib/crud/exporters.ts +188 -0
- package/src/lib/crud/factory.ts +1622 -0
- package/src/lib/crud/types.ts +29 -0
- package/src/lib/custom-fields/normalize.ts +45 -0
- package/src/lib/data/engine.ts +562 -0
- package/src/lib/db/escapeLikePattern.ts +2 -0
- package/src/lib/db/mikro.ts +100 -0
- package/src/lib/di/container.ts +105 -0
- package/src/lib/email/send.ts +18 -0
- package/src/lib/encryption/__tests__/customFieldValues.test.ts +63 -0
- package/src/lib/encryption/__tests__/indexDoc.test.ts +115 -0
- package/src/lib/encryption/aes.ts +64 -0
- package/src/lib/encryption/customFieldValues.ts +67 -0
- package/src/lib/encryption/entityFields.ts +39 -0
- package/src/lib/encryption/entityIds.ts +107 -0
- package/src/lib/encryption/find.ts +81 -0
- package/src/lib/encryption/indexDoc.ts +104 -0
- package/src/lib/encryption/kms.ts +337 -0
- package/src/lib/encryption/subscriber.ts +416 -0
- package/src/lib/encryption/tenantDataEncryptionService.ts +313 -0
- package/src/lib/encryption/toggles.ts +15 -0
- package/src/lib/entities/naming.ts +6 -0
- package/src/lib/entities/system-entities.ts +43 -0
- package/src/lib/frontend/organizationEvents.ts +55 -0
- package/src/lib/frontend/useOrganizationScope.ts +30 -0
- package/src/lib/hotkeys/index.ts +168 -0
- package/src/lib/i18n/app-dictionaries.ts +18 -0
- package/src/lib/i18n/config.ts +4 -0
- package/src/lib/i18n/context.tsx +66 -0
- package/src/lib/i18n/server.ts +74 -0
- package/src/lib/i18n/translate.ts +54 -0
- package/src/lib/indexers/error-log.ts +106 -0
- package/src/lib/indexers/status-log.ts +119 -0
- package/src/lib/lib/auth/jwt.ts +39 -0
- package/src/lib/lib/auth/server.ts +94 -0
- package/src/lib/lib/email/send.ts +18 -0
- package/src/lib/lib/i18n/config.ts +4 -0
- package/src/lib/lib/i18n/context.tsx +38 -0
- package/src/lib/lib/utils.ts +6 -0
- package/src/lib/location/countries.ts +97 -0
- package/src/lib/modules/index.ts +1 -0
- package/src/lib/modules/registry.ts +18 -0
- package/src/lib/openapi/crud.ts +218 -0
- package/src/lib/openapi/generator.ts +1311 -0
- package/src/lib/openapi/index.ts +4 -0
- package/src/lib/openapi/sanitize.ts +137 -0
- package/src/lib/openapi/types.ts +79 -0
- package/src/lib/profiler/index.ts +371 -0
- package/src/lib/query/__tests__/engine.test.ts +274 -0
- package/src/lib/query/engine.ts +837 -0
- package/src/lib/query/join-utils.ts +238 -0
- package/src/lib/query/types.ts +121 -0
- package/src/lib/search/config.ts +49 -0
- package/src/lib/search/tokenize.ts +45 -0
- package/src/lib/slugify.ts +28 -0
- package/src/lib/testing/bootstrap.ts +124 -0
- package/src/lib/testing/index.ts +15 -0
- package/src/lib/testing/renderWithProviders.tsx +31 -0
- package/src/lib/url.ts +12 -0
- package/src/lib/utils.ts +17 -0
- package/src/lib/version.ts +5 -0
- package/src/modules/__tests__/dsl.test.ts +35 -0
- package/src/modules/__tests__/registry.test.ts +300 -0
- package/src/modules/dashboard/widgets.ts +57 -0
- package/src/modules/dsl.ts +32 -0
- package/src/modules/entities/__tests__/validation.test.ts +52 -0
- package/src/modules/entities/kinds.ts +20 -0
- package/src/modules/entities/options.ts +36 -0
- package/src/modules/entities/validation.ts +118 -0
- package/src/modules/entities/validators.ts +93 -0
- package/src/modules/entities.ts +102 -0
- package/src/modules/navigation/sidebarPreferences.ts +62 -0
- package/src/modules/perspectives/types.ts +40 -0
- package/src/modules/registry.ts +249 -0
- package/src/modules/search.ts +325 -0
- package/src/modules/vector.ts +122 -0
- package/src/modules/widgets/__tests__/injection.test.ts +48 -0
- package/src/modules/widgets/injection-loader.ts +235 -0
- package/src/modules/widgets/injection.ts +120 -0
- package/src/security/features.ts +22 -0
- package/src/types/pg.d.ts +2 -0
- package/src/types/react-email.d.ts +2 -0
- package/src/types/resend.d.ts +2 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +9 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
function findAppRoot(startDir = process.cwd()) {
|
|
4
|
+
let current = startDir;
|
|
5
|
+
while (current !== path.dirname(current)) {
|
|
6
|
+
const configTs = path.join(current, "next.config.ts");
|
|
7
|
+
const configJs = path.join(current, "next.config.js");
|
|
8
|
+
const configMjs = path.join(current, "next.config.mjs");
|
|
9
|
+
if (fs.existsSync(configTs) || fs.existsSync(configJs) || fs.existsSync(configMjs)) {
|
|
10
|
+
const mercatoDir = path.join(current, ".mercato");
|
|
11
|
+
const generatedDir = path.join(mercatoDir, "generated");
|
|
12
|
+
if (fs.existsSync(generatedDir)) {
|
|
13
|
+
return { appDir: current, mercatoDir, generatedDir };
|
|
14
|
+
}
|
|
15
|
+
return { appDir: current, mercatoDir, generatedDir };
|
|
16
|
+
}
|
|
17
|
+
current = path.dirname(current);
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function findAllApps(rootDir) {
|
|
22
|
+
const appsDir = path.join(rootDir, "apps");
|
|
23
|
+
if (!fs.existsSync(appsDir)) return [];
|
|
24
|
+
const apps = [];
|
|
25
|
+
const entries = fs.readdirSync(appsDir, { withFileTypes: true });
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
if (!entry.isDirectory()) continue;
|
|
28
|
+
const appDir = path.join(appsDir, entry.name);
|
|
29
|
+
const hasNextConfig = fs.existsSync(path.join(appDir, "next.config.ts")) || fs.existsSync(path.join(appDir, "next.config.js")) || fs.existsSync(path.join(appDir, "next.config.mjs"));
|
|
30
|
+
if (!hasNextConfig) continue;
|
|
31
|
+
const mercatoDir = path.join(appDir, ".mercato");
|
|
32
|
+
const generatedDir = path.join(mercatoDir, "generated");
|
|
33
|
+
if (fs.existsSync(generatedDir)) {
|
|
34
|
+
apps.push({ appDir, mercatoDir, generatedDir });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return apps;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
findAllApps,
|
|
41
|
+
findAppRoot
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=appResolver.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/bootstrap/appResolver.ts"],
|
|
4
|
+
"sourcesContent": ["import path from 'node:path'\nimport fs from 'node:fs'\n\nexport interface AppRoot {\n appDir: string\n mercatoDir: string\n generatedDir: string\n}\n\n/**\n * Find the Next.js app root by searching for next.config.ts/js/mjs.\n *\n * Starts from the given directory (defaults to cwd) and walks up the\n * directory tree until it finds a Next.js config file with a .mercato/generated\n * directory.\n *\n * @param startDir - Directory to start searching from (defaults to process.cwd())\n * @returns The resolved app root paths, or null if not found\n */\nexport function findAppRoot(startDir: string = process.cwd()): AppRoot | null {\n let current = startDir\n\n while (current !== path.dirname(current)) {\n const configTs = path.join(current, 'next.config.ts')\n const configJs = path.join(current, 'next.config.js')\n const configMjs = path.join(current, 'next.config.mjs')\n\n if (fs.existsSync(configTs) || fs.existsSync(configJs) || fs.existsSync(configMjs)) {\n const mercatoDir = path.join(current, '.mercato')\n const generatedDir = path.join(mercatoDir, 'generated')\n\n // Only return if .mercato/generated exists\n if (fs.existsSync(generatedDir)) {\n return { appDir: current, mercatoDir, generatedDir }\n }\n\n // Found Next.js config but no .mercato/generated - return anyway for generate command\n // The caller can decide whether to create the directory\n return { appDir: current, mercatoDir, generatedDir }\n }\n\n current = path.dirname(current)\n }\n\n return null\n}\n\n/**\n * Find all apps with .mercato directories in a monorepo.\n *\n * Scans the apps/ directory for Next.js apps with .mercato/generated directories.\n *\n * @param rootDir - The monorepo root directory\n * @returns Array of app root paths\n */\nexport function findAllApps(rootDir: string): AppRoot[] {\n const appsDir = path.join(rootDir, 'apps')\n if (!fs.existsSync(appsDir)) return []\n\n const apps: AppRoot[] = []\n const entries = fs.readdirSync(appsDir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n\n const appDir = path.join(appsDir, entry.name)\n\n // Check for Next.js config\n const hasNextConfig =\n fs.existsSync(path.join(appDir, 'next.config.ts')) ||\n fs.existsSync(path.join(appDir, 'next.config.js')) ||\n fs.existsSync(path.join(appDir, 'next.config.mjs'))\n\n if (!hasNextConfig) continue\n\n const mercatoDir = path.join(appDir, '.mercato')\n const generatedDir = path.join(mercatoDir, 'generated')\n\n if (fs.existsSync(generatedDir)) {\n apps.push({ appDir, mercatoDir, generatedDir })\n }\n }\n\n return apps\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAkBR,SAAS,YAAY,WAAmB,QAAQ,IAAI,GAAmB;AAC5E,MAAI,UAAU;AAEd,SAAO,YAAY,KAAK,QAAQ,OAAO,GAAG;AACxC,UAAM,WAAW,KAAK,KAAK,SAAS,gBAAgB;AACpD,UAAM,WAAW,KAAK,KAAK,SAAS,gBAAgB;AACpD,UAAM,YAAY,KAAK,KAAK,SAAS,iBAAiB;AAEtD,QAAI,GAAG,WAAW,QAAQ,KAAK,GAAG,WAAW,QAAQ,KAAK,GAAG,WAAW,SAAS,GAAG;AAClF,YAAM,aAAa,KAAK,KAAK,SAAS,UAAU;AAChD,YAAM,eAAe,KAAK,KAAK,YAAY,WAAW;AAGtD,UAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,eAAO,EAAE,QAAQ,SAAS,YAAY,aAAa;AAAA,MACrD;AAIA,aAAO,EAAE,QAAQ,SAAS,YAAY,aAAa;AAAA,IACrD;AAEA,cAAU,KAAK,QAAQ,OAAO;AAAA,EAChC;AAEA,SAAO;AACT;AAUO,SAAS,YAAY,SAA4B;AACtD,QAAM,UAAU,KAAK,KAAK,SAAS,MAAM;AACzC,MAAI,CAAC,GAAG,WAAW,OAAO,EAAG,QAAO,CAAC;AAErC,QAAM,OAAkB,CAAC;AACzB,QAAM,UAAU,GAAG,YAAY,SAAS,EAAE,eAAe,KAAK,CAAC;AAE/D,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,UAAM,SAAS,KAAK,KAAK,SAAS,MAAM,IAAI;AAG5C,UAAM,gBACJ,GAAG,WAAW,KAAK,KAAK,QAAQ,gBAAgB,CAAC,KACjD,GAAG,WAAW,KAAK,KAAK,QAAQ,gBAAgB,CAAC,KACjD,GAAG,WAAW,KAAK,KAAK,QAAQ,iBAAiB,CAAC;AAEpD,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,KAAK,KAAK,QAAQ,UAAU;AAC/C,UAAM,eAAe,KAAK,KAAK,YAAY,WAAW;AAEtD,QAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,WAAK,KAAK,EAAE,QAAQ,YAAY,aAAa,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { findAppRoot } from "./appResolver.js";
|
|
2
|
+
import { registerEntityIds } from "../encryption/entityIds.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
async function compileAndImport(tsPath) {
|
|
7
|
+
const jsPath = tsPath.replace(/\.ts$/, ".mjs");
|
|
8
|
+
const tsExists = fs.existsSync(tsPath);
|
|
9
|
+
const jsExists = fs.existsSync(jsPath);
|
|
10
|
+
if (!tsExists) {
|
|
11
|
+
throw new Error(`Generated file not found: ${tsPath}`);
|
|
12
|
+
}
|
|
13
|
+
const needsCompile = !jsExists || fs.statSync(tsPath).mtimeMs > fs.statSync(jsPath).mtimeMs;
|
|
14
|
+
if (needsCompile) {
|
|
15
|
+
const esbuild = await import("esbuild");
|
|
16
|
+
const appRoot = path.dirname(path.dirname(path.dirname(tsPath)));
|
|
17
|
+
const aliasPlugin = {
|
|
18
|
+
name: "alias-resolver",
|
|
19
|
+
setup(build) {
|
|
20
|
+
build.onResolve({ filter: /^@\// }, (args) => {
|
|
21
|
+
const resolved = path.join(appRoot, args.path.slice(2));
|
|
22
|
+
if (!fs.existsSync(resolved) && fs.existsSync(resolved + ".ts")) {
|
|
23
|
+
return { path: resolved + ".ts" };
|
|
24
|
+
}
|
|
25
|
+
if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory() && fs.existsSync(path.join(resolved, "index.ts"))) {
|
|
26
|
+
return { path: path.join(resolved, "index.ts") };
|
|
27
|
+
}
|
|
28
|
+
return { path: resolved };
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const externalNonJsonPlugin = {
|
|
33
|
+
name: "external-non-json",
|
|
34
|
+
setup(build) {
|
|
35
|
+
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
36
|
+
if (args.path.endsWith(".json")) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return { path: args.path, external: true };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
await esbuild.build({
|
|
44
|
+
entryPoints: [tsPath],
|
|
45
|
+
outfile: jsPath,
|
|
46
|
+
bundle: true,
|
|
47
|
+
format: "esm",
|
|
48
|
+
platform: "node",
|
|
49
|
+
target: "node18",
|
|
50
|
+
plugins: [aliasPlugin, externalNonJsonPlugin],
|
|
51
|
+
// Allow JSON imports
|
|
52
|
+
loader: { ".json": "json" }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const fileUrl = pathToFileURL(jsPath).href;
|
|
56
|
+
return import(fileUrl);
|
|
57
|
+
}
|
|
58
|
+
async function loadBootstrapData(appRoot) {
|
|
59
|
+
const resolved = appRoot ? {
|
|
60
|
+
generatedDir: path.join(appRoot, ".mercato", "generated"),
|
|
61
|
+
appDir: appRoot,
|
|
62
|
+
mercatoDir: path.join(appRoot, ".mercato")
|
|
63
|
+
} : findAppRoot();
|
|
64
|
+
if (!resolved) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
'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.'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const { generatedDir } = resolved;
|
|
70
|
+
const entityIdsModule = await compileAndImport(path.join(generatedDir, "entities.ids.generated.ts"));
|
|
71
|
+
registerEntityIds(entityIdsModule.E);
|
|
72
|
+
const [
|
|
73
|
+
modulesModule,
|
|
74
|
+
entitiesModule,
|
|
75
|
+
diModule,
|
|
76
|
+
searchModule
|
|
77
|
+
] = await Promise.all([
|
|
78
|
+
compileAndImport(path.join(generatedDir, "modules.cli.generated.ts")),
|
|
79
|
+
compileAndImport(path.join(generatedDir, "entities.generated.ts")),
|
|
80
|
+
compileAndImport(path.join(generatedDir, "di.generated.ts")),
|
|
81
|
+
compileAndImport(path.join(generatedDir, "search.generated.ts")).catch(() => ({ searchModuleConfigs: [] }))
|
|
82
|
+
]);
|
|
83
|
+
return {
|
|
84
|
+
modules: modulesModule.modules,
|
|
85
|
+
entities: entitiesModule.entities,
|
|
86
|
+
diRegistrars: diModule.diRegistrars,
|
|
87
|
+
entityIds: entityIdsModule.E,
|
|
88
|
+
// Search configs are needed by workers for indexing
|
|
89
|
+
searchModuleConfigs: searchModule.searchModuleConfigs ?? [],
|
|
90
|
+
// Empty UI-related data - not needed for CLI
|
|
91
|
+
dashboardWidgetEntries: [],
|
|
92
|
+
injectionWidgetEntries: [],
|
|
93
|
+
injectionTables: []
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function bootstrapFromAppRoot(appRoot) {
|
|
97
|
+
const { createBootstrap, waitForAsyncRegistration } = await import("./factory.js");
|
|
98
|
+
const data = await loadBootstrapData(appRoot);
|
|
99
|
+
const bootstrap = createBootstrap(data);
|
|
100
|
+
bootstrap();
|
|
101
|
+
await waitForAsyncRegistration();
|
|
102
|
+
return data;
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
bootstrapFromAppRoot,
|
|
106
|
+
loadBootstrapData
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=dynamicLoader.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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 path from 'node:path'\nimport fs from 'node:fs'\nimport { pathToFileURL } from 'node:url'\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): Promise<Record<string, unknown>> {\n const jsPath = tsPath.replace(/\\.ts$/, '.mjs')\n\n // Check if we need to recompile (source newer than compiled)\n const tsExists = fs.existsSync(tsPath)\n const jsExists = fs.existsSync(jsPath)\n\n if (!tsExists) {\n throw new Error(`Generated file not found: ${tsPath}`)\n }\n\n const needsCompile = !jsExists ||\n fs.statSync(tsPath).mtimeMs > fs.statSync(jsPath).mtimeMs\n\n if (needsCompile) {\n // Dynamically import esbuild only when needed\n const esbuild = await import('esbuild')\n\n // The app root is 2 levels up from .mercato/generated/\n const appRoot = path.dirname(path.dirname(path.dirname(tsPath)))\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 build.onResolve({ filter: /^[^./]/ }, (args) => {\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 await esbuild.build({\n entryPoints: [tsPath],\n outfile: jsPath,\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n plugins: [aliasPlugin, externalNonJsonPlugin],\n // Allow JSON imports\n loader: { '.json': 'json' },\n })\n }\n\n // Import the compiled JavaScript\n const fileUrl = pathToFileURL(jsPath).href\n return import(fileUrl)\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 // 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 ] = 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 ])\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 // Empty UI-related data - not needed for CLI\n dashboardWidgetEntries: [],\n injectionWidgetEntries: [],\n injectionTables: [],\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": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { registerOrmEntities } from "../db/mikro.js";
|
|
2
|
+
import { registerDiRegistrars } from "../di/container.js";
|
|
3
|
+
import { registerModules } from "../modules/registry.js";
|
|
4
|
+
import { registerEntityIds } from "../encryption/entityIds.js";
|
|
5
|
+
import { registerEntityFields } from "../encryption/entityFields.js";
|
|
6
|
+
import { registerSearchModuleConfigs } from "../../modules/search.js";
|
|
7
|
+
let _bootstrapped = false;
|
|
8
|
+
let _asyncRegistrationPromise = null;
|
|
9
|
+
function createBootstrap(data, options = {}) {
|
|
10
|
+
return function bootstrap() {
|
|
11
|
+
if (_bootstrapped && process.env.NODE_ENV !== "development") return;
|
|
12
|
+
_bootstrapped = true;
|
|
13
|
+
registerOrmEntities(data.entities);
|
|
14
|
+
registerDiRegistrars(data.diRegistrars.filter((r) => r != null));
|
|
15
|
+
registerModules(data.modules);
|
|
16
|
+
registerEntityIds(data.entityIds);
|
|
17
|
+
if (data.entityFieldsRegistry) {
|
|
18
|
+
registerEntityFields(data.entityFieldsRegistry);
|
|
19
|
+
}
|
|
20
|
+
if (data.searchModuleConfigs) {
|
|
21
|
+
registerSearchModuleConfigs(data.searchModuleConfigs);
|
|
22
|
+
}
|
|
23
|
+
_asyncRegistrationPromise = registerWidgetsAndOptionalPackages(data, options);
|
|
24
|
+
void _asyncRegistrationPromise;
|
|
25
|
+
options.onRegistrationComplete?.();
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async function waitForAsyncRegistration() {
|
|
29
|
+
if (_asyncRegistrationPromise) {
|
|
30
|
+
await _asyncRegistrationPromise;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function registerWidgetsAndOptionalPackages(data, options) {
|
|
34
|
+
try {
|
|
35
|
+
const [dashboardRegistry, injectionRegistry, coreInjection] = await Promise.all([
|
|
36
|
+
import("@open-mercato/ui/backend/dashboard/widgetRegistry"),
|
|
37
|
+
import("@open-mercato/ui/backend/injection/widgetRegistry"),
|
|
38
|
+
import("@open-mercato/core/modules/widgets/lib/injection")
|
|
39
|
+
]);
|
|
40
|
+
dashboardRegistry.registerDashboardWidgets(data.dashboardWidgetEntries);
|
|
41
|
+
injectionRegistry.registerInjectionWidgets(data.injectionWidgetEntries);
|
|
42
|
+
coreInjection.registerCoreInjectionWidgets(data.injectionWidgetEntries);
|
|
43
|
+
coreInjection.registerCoreInjectionTables(data.injectionTables);
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function isBootstrapped() {
|
|
48
|
+
return _bootstrapped;
|
|
49
|
+
}
|
|
50
|
+
function resetBootstrapState() {
|
|
51
|
+
_bootstrapped = false;
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
createBootstrap,
|
|
55
|
+
isBootstrapped,
|
|
56
|
+
resetBootstrapState,
|
|
57
|
+
waitForAsyncRegistration
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/bootstrap/factory.ts"],
|
|
4
|
+
"sourcesContent": ["import type { BootstrapData, BootstrapOptions } from './types'\nimport { registerOrmEntities } from '../db/mikro'\nimport { registerDiRegistrars } from '../di/container'\nimport { registerModules } from '../modules/registry'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport { registerEntityFields } from '../encryption/entityFields'\nimport { registerSearchModuleConfigs } from '../../modules/search'\n\nlet _bootstrapped = false\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 // In development, always re-run registrations to handle HMR\n // (Module state may be reset when Turbopack reloads packages)\n if (_bootstrapped && process.env.NODE_ENV !== 'development') return\n _bootstrapped = true\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\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-7. 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 UI widgets (dynamic imports to avoid circular deps with ui/core packages)\n try {\n const [dashboardRegistry, injectionRegistry, coreInjection] = await Promise.all([\n import('@open-mercato/ui/backend/dashboard/widgetRegistry'),\n import('@open-mercato/ui/backend/injection/widgetRegistry'),\n import('@open-mercato/core/modules/widgets/lib/injection'),\n ])\n\n dashboardRegistry.registerDashboardWidgets(data.dashboardWidgetEntries)\n injectionRegistry.registerInjectionWidgets(data.injectionWidgetEntries)\n coreInjection.registerCoreInjectionWidgets(data.injectionWidgetEntries)\n coreInjection.registerCoreInjectionTables(data.injectionTables)\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 _bootstrapped\n}\n\n/**\n * Reset bootstrap state. Useful for testing.\n */\nexport function resetBootstrapState(): void {\n _bootstrapped = false\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,mCAAmC;AAE5C,IAAI,gBAAgB;AAGpB,IAAI,4BAAkD;AAY/C,SAAS,gBAAgB,MAAqB,UAA4B,CAAC,GAAG;AACnF,SAAO,SAAS,YAAkB;AAGhC,QAAI,iBAAiB,QAAQ,IAAI,aAAa,cAAe;AAC7D,oBAAgB;AAGhB,wBAAoB,KAAK,QAAQ;AACjC,yBAAqB,KAAK,aAAa,OAAO,CAAC,MAAkC,KAAK,IAAI,CAAC;AAG3F,oBAAgB,KAAK,OAAO;AAG5B,sBAAkB,KAAK,SAAS;AAGhC,QAAI,KAAK,sBAAsB;AAC7B,2BAAqB,KAAK,oBAAoB;AAAA,IAChD;AAGA,QAAI,KAAK,qBAAqB;AAC5B,kCAA4B,KAAK,mBAAmB;AAAA,IACtD;AAIA,gCAA4B,mCAAmC,MAAM,OAAO;AAC5E,SAAK;AAEL,YAAQ,yBAAyB;AAAA,EACnC;AACF;AAMA,eAAsB,2BAA0C;AAC9D,MAAI,2BAA2B;AAC7B,UAAM;AAAA,EACR;AACF;AAEA,eAAe,mCAAmC,MAAqB,SAA0C;AAE/G,MAAI;AACF,UAAM,CAAC,mBAAmB,mBAAmB,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9E,OAAO,mDAAmD;AAAA,MAC1D,OAAO,mDAAmD;AAAA,MAC1D,OAAO,kDAAkD;AAAA,IAC3D,CAAC;AAED,sBAAkB,yBAAyB,KAAK,sBAAsB;AACtE,sBAAkB,yBAAyB,KAAK,sBAAsB;AACtE,kBAAc,6BAA6B,KAAK,sBAAsB;AACtE,kBAAc,4BAA4B,KAAK,eAAe;AAAA,EAChE,QAAQ;AAAA,EAER;AASF;AAKO,SAAS,iBAA0B;AACxC,SAAO;AACT;AAKO,SAAS,sBAA4B;AAC1C,kBAAgB;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
import { createBootstrap, isBootstrapped, resetBootstrapState } from "./factory.js";
|
|
3
|
+
import { findAppRoot, findAllApps } from "./appResolver.js";
|
|
4
|
+
export {
|
|
5
|
+
createBootstrap,
|
|
6
|
+
findAllApps,
|
|
7
|
+
findAppRoot,
|
|
8
|
+
isBootstrapped,
|
|
9
|
+
resetBootstrapState
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/bootstrap/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Bootstrap module for Open Mercato applications.\n *\n * This module provides utilities for bootstrapping the application:\n *\n * - `createBootstrap(data)` - Factory to create a bootstrap function from generated data\n * - `isBootstrapped()` - Check if bootstrap has been called\n * - `resetBootstrapState()` - Reset bootstrap state (for testing)\n * - `findAppRoot()` - Find the Next.js app root directory\n *\n * For CLI/dynamic contexts, import the dynamic loader directly:\n * ```ts\n * import { bootstrapFromAppRoot } from '@open-mercato/shared/lib/bootstrap/dynamicLoader'\n * ```\n */\n\nexport * from './types'\nexport { createBootstrap, isBootstrapped, resetBootstrapState } from './factory'\nexport { findAppRoot, findAllApps, type AppRoot } from './appResolver'\n\n// Note: dynamicLoader is intentionally NOT exported from index\n// It should be imported directly when needed to make it clear\n// that it only works in unbundled contexts (CLI, tsx)\n"],
|
|
5
|
+
"mappings": "AAgBA,cAAc;AACd,SAAS,iBAAiB,gBAAgB,2BAA2B;AACrE,SAAS,aAAa,mBAAiC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
async function analyzeCacheSegments(cache, options) {
|
|
2
|
+
const keys = await cache.keys(options.keysPattern);
|
|
3
|
+
const segments = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const key of keys) {
|
|
5
|
+
if (options.filterKey && !options.filterKey(key)) continue;
|
|
6
|
+
const segment = options.deriveSegment(key);
|
|
7
|
+
if (!segment) continue;
|
|
8
|
+
if (!segments.has(segment)) segments.set(segment, /* @__PURE__ */ new Set());
|
|
9
|
+
segments.get(segment).add(key);
|
|
10
|
+
}
|
|
11
|
+
const results = [];
|
|
12
|
+
for (const [segment, keySet] of segments.entries()) {
|
|
13
|
+
results.push({
|
|
14
|
+
segment,
|
|
15
|
+
keys: Array.from(keySet).sort()
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
results.sort((a, b) => a.segment.localeCompare(b.segment));
|
|
19
|
+
return results;
|
|
20
|
+
}
|
|
21
|
+
async function purgeCacheSegment(cache, options, segment) {
|
|
22
|
+
const analyses = await analyzeCacheSegments(cache, options);
|
|
23
|
+
const target = analyses.find((entry) => entry.segment === segment);
|
|
24
|
+
if (!target) return { deleted: 0, keys: [] };
|
|
25
|
+
let deleted = 0;
|
|
26
|
+
for (const key of target.keys) {
|
|
27
|
+
const removed = await cache.delete(key);
|
|
28
|
+
if (removed) deleted += 1;
|
|
29
|
+
}
|
|
30
|
+
return { deleted, keys: target.keys };
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
analyzeCacheSegments,
|
|
34
|
+
purgeCacheSegment
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=segments.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/cache/segments.ts"],
|
|
4
|
+
"sourcesContent": ["import type { CacheStrategy } from '@open-mercato/cache'\n\nexport type CacheSegmentAnalysisOptions = {\n keysPattern: string\n deriveSegment: (key: string) => string | null\n filterKey?: (key: string) => boolean\n}\n\nexport type CacheSegmentInfo = {\n segment: string\n keys: string[]\n}\n\nexport async function analyzeCacheSegments(\n cache: CacheStrategy,\n options: CacheSegmentAnalysisOptions\n): Promise<CacheSegmentInfo[]> {\n const keys = await cache.keys(options.keysPattern)\n const segments = new Map<string, Set<string>>()\n\n for (const key of keys) {\n if (options.filterKey && !options.filterKey(key)) continue\n const segment = options.deriveSegment(key)\n if (!segment) continue\n if (!segments.has(segment)) segments.set(segment, new Set<string>())\n segments.get(segment)!.add(key)\n }\n\n const results: CacheSegmentInfo[] = []\n for (const [segment, keySet] of segments.entries()) {\n results.push({\n segment,\n keys: Array.from(keySet).sort(),\n })\n }\n results.sort((a, b) => a.segment.localeCompare(b.segment))\n return results\n}\n\nexport async function purgeCacheSegment(\n cache: CacheStrategy,\n options: CacheSegmentAnalysisOptions,\n segment: string\n): Promise<{ deleted: number; keys: string[] }> {\n const analyses = await analyzeCacheSegments(cache, options)\n const target = analyses.find((entry) => entry.segment === segment)\n if (!target) return { deleted: 0, keys: [] }\n\n let deleted = 0\n for (const key of target.keys) {\n const removed = await cache.delete(key)\n if (removed) deleted += 1\n }\n\n return { deleted, keys: target.keys }\n}\n"],
|
|
5
|
+
"mappings": "AAaA,eAAsB,qBACpB,OACA,SAC6B;AAC7B,QAAM,OAAO,MAAM,MAAM,KAAK,QAAQ,WAAW;AACjD,QAAM,WAAW,oBAAI,IAAyB;AAE9C,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,GAAG,EAAG;AAClD,UAAM,UAAU,QAAQ,cAAc,GAAG;AACzC,QAAI,CAAC,QAAS;AACd,QAAI,CAAC,SAAS,IAAI,OAAO,EAAG,UAAS,IAAI,SAAS,oBAAI,IAAY,CAAC;AACnE,aAAS,IAAI,OAAO,EAAG,IAAI,GAAG;AAAA,EAChC;AAEA,QAAM,UAA8B,CAAC;AACrC,aAAW,CAAC,SAAS,MAAM,KAAK,SAAS,QAAQ,GAAG;AAClD,YAAQ,KAAK;AAAA,MACX;AAAA,MACA,MAAM,MAAM,KAAK,MAAM,EAAE,KAAK;AAAA,IAChC,CAAC;AAAA,EACH;AACA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,OAAO,CAAC;AACzD,SAAO;AACT;AAEA,eAAsB,kBACpB,OACA,SACA,SAC8C;AAC9C,QAAM,WAAW,MAAM,qBAAqB,OAAO,OAAO;AAC1D,QAAM,SAAS,SAAS,KAAK,CAAC,UAAU,MAAM,YAAY,OAAO;AACjE,MAAI,CAAC,OAAQ,QAAO,EAAE,SAAS,GAAG,MAAM,CAAC,EAAE;AAE3C,MAAI,UAAU;AACd,aAAW,OAAO,OAAO,MAAM;AAC7B,UAAM,UAAU,MAAM,MAAM,OAAO,GAAG;AACtC,QAAI,QAAS,YAAW;AAAA,EAC1B;AAEA,SAAO,EAAE,SAAS,MAAM,OAAO,KAAK;AACtC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
function createProgressBar(label, total) {
|
|
2
|
+
const width = 28;
|
|
3
|
+
let lastPercent = -1;
|
|
4
|
+
let lastCompleted = -1;
|
|
5
|
+
let finished = false;
|
|
6
|
+
const startedAt = Date.now();
|
|
7
|
+
const minPercentStep = total >= 1e6 ? 0.01 : total >= 1e5 ? 0.05 : total >= 1e4 ? 0.1 : 0.5;
|
|
8
|
+
const minCompletedStep = Math.max(1, Math.floor(total / 1e3));
|
|
9
|
+
const render = (completed) => {
|
|
10
|
+
if (total <= 0 || finished) return;
|
|
11
|
+
const ratio = Math.min(1, Math.max(0, completed / total));
|
|
12
|
+
const percentRaw = ratio * 100;
|
|
13
|
+
if (completed < total && percentRaw - lastPercent < minPercentStep && completed - lastCompleted < minCompletedStep) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
lastPercent = percentRaw;
|
|
17
|
+
lastCompleted = completed;
|
|
18
|
+
const filled = Math.round(ratio * width);
|
|
19
|
+
const bar = "#".repeat(filled).padEnd(width, "-");
|
|
20
|
+
const percentLabel = (percentRaw >= 10 ? percentRaw.toFixed(1) : percentRaw.toFixed(2)).padStart(6, " ");
|
|
21
|
+
const countsLabel = `${completed.toLocaleString()}/${total.toLocaleString()}`;
|
|
22
|
+
const elapsedMs = Math.max(1, Date.now() - startedAt);
|
|
23
|
+
const recordsPerSecond = completed > 0 ? completed / elapsedMs * 1e3 : 0;
|
|
24
|
+
const rateLabel = `${recordsPerSecond.toFixed(1)} r/s`;
|
|
25
|
+
process.stdout.write(`\r${label} [${bar}] ${percentLabel}% (${countsLabel}) ${rateLabel}`);
|
|
26
|
+
if (completed >= total) {
|
|
27
|
+
finished = true;
|
|
28
|
+
process.stdout.write("\n");
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
update: render,
|
|
33
|
+
complete() {
|
|
34
|
+
if (!finished && total > 0) {
|
|
35
|
+
render(total);
|
|
36
|
+
} else if (!finished) {
|
|
37
|
+
finished = true;
|
|
38
|
+
process.stdout.write("\n");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
createProgressBar
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/cli/progress.ts"],
|
|
4
|
+
"sourcesContent": ["export type ProgressBar = {\n update(completed: number): void\n complete(): void\n}\n\nexport function createProgressBar(label: string, total: number): ProgressBar {\n const width = 28\n let lastPercent = -1\n let lastCompleted = -1\n let finished = false\n const startedAt = Date.now()\n const minPercentStep =\n total >= 1_000_000 ? 0.01 : total >= 100_000 ? 0.05 : total >= 10_000 ? 0.1 : 0.5\n const minCompletedStep = Math.max(1, Math.floor(total / 1000))\n\n const render = (completed: number) => {\n if (total <= 0 || finished) return\n const ratio = Math.min(1, Math.max(0, completed / total))\n const percentRaw = ratio * 100\n if (\n completed < total &&\n percentRaw - lastPercent < minPercentStep &&\n completed - lastCompleted < minCompletedStep\n ) {\n return\n }\n lastPercent = percentRaw\n lastCompleted = completed\n const filled = Math.round(ratio * width)\n const bar = '#'.repeat(filled).padEnd(width, '-')\n const percentLabel =\n (percentRaw >= 10 ? percentRaw.toFixed(1) : percentRaw.toFixed(2)).padStart(6, ' ')\n const countsLabel = `${completed.toLocaleString()}/${total.toLocaleString()}`\n const elapsedMs = Math.max(1, Date.now() - startedAt)\n const recordsPerSecond = completed > 0 ? (completed / elapsedMs) * 1000 : 0\n const rateLabel = `${recordsPerSecond.toFixed(1)} r/s`\n process.stdout.write(`\\r${label} [${bar}] ${percentLabel}% (${countsLabel}) ${rateLabel}`)\n if (completed >= total) {\n finished = true\n process.stdout.write('\\n')\n }\n }\n\n return {\n update: render,\n complete() {\n if (!finished && total > 0) {\n render(total)\n } else if (!finished) {\n finished = true\n process.stdout.write('\\n')\n }\n },\n }\n}\n"],
|
|
5
|
+
"mappings": "AAKO,SAAS,kBAAkB,OAAe,OAA4B;AAC3E,QAAM,QAAQ;AACd,MAAI,cAAc;AAClB,MAAI,gBAAgB;AACpB,MAAI,WAAW;AACf,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,iBACJ,SAAS,MAAY,OAAO,SAAS,MAAU,OAAO,SAAS,MAAS,MAAM;AAChF,QAAM,mBAAmB,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,GAAI,CAAC;AAE7D,QAAM,SAAS,CAAC,cAAsB;AACpC,QAAI,SAAS,KAAK,SAAU;AAC5B,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,YAAY,KAAK,CAAC;AACxD,UAAM,aAAa,QAAQ;AAC3B,QACE,YAAY,SACZ,aAAa,cAAc,kBAC3B,YAAY,gBAAgB,kBAC5B;AACA;AAAA,IACF;AACA,kBAAc;AACd,oBAAgB;AAChB,UAAM,SAAS,KAAK,MAAM,QAAQ,KAAK;AACvC,UAAM,MAAM,IAAI,OAAO,MAAM,EAAE,OAAO,OAAO,GAAG;AAChD,UAAM,gBACH,cAAc,KAAK,WAAW,QAAQ,CAAC,IAAI,WAAW,QAAQ,CAAC,GAAG,SAAS,GAAG,GAAG;AACpF,UAAM,cAAc,GAAG,UAAU,eAAe,CAAC,IAAI,MAAM,eAAe,CAAC;AAC3E,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS;AACpD,UAAM,mBAAmB,YAAY,IAAK,YAAY,YAAa,MAAO;AAC1E,UAAM,YAAY,GAAG,iBAAiB,QAAQ,CAAC,CAAC;AAChD,YAAQ,OAAO,MAAM,KAAK,KAAK,KAAK,GAAG,KAAK,YAAY,MAAM,WAAW,KAAK,SAAS,EAAE;AACzF,QAAI,aAAa,OAAO;AACtB,iBAAW;AACX,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AACT,UAAI,CAAC,YAAY,QAAQ,GAAG;AAC1B,eAAO,KAAK;AAAA,MACd,WAAW,CAAC,UAAU;AACpB,mBAAW;AACX,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|