@kuckit/sdk 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/config/define-config.d.ts +3 -0
  2. package/dist/config/define-config.js +3 -0
  3. package/dist/config/index.d.ts +5 -0
  4. package/dist/config/index.js +5 -0
  5. package/dist/config/loader.d.ts +3 -0
  6. package/dist/config/loader.js +3 -0
  7. package/dist/config/types.d.ts +2 -0
  8. package/dist/config/types.js +1 -0
  9. package/dist/config-BeiJJZGf.js +1 -0
  10. package/dist/container-D0DK003A.js +50 -0
  11. package/dist/container-D0DK003A.js.map +1 -0
  12. package/dist/container-Ngzcb6LI.d.ts +49 -0
  13. package/dist/core/container.d.ts +3 -0
  14. package/dist/core/container.js +4 -0
  15. package/dist/core/core.module.d.ts +3 -0
  16. package/dist/core/core.module.js +3 -0
  17. package/dist/core.module-Ckt9iPWn.d.ts +22 -0
  18. package/dist/core.module-Ctm2stcL.js +48 -0
  19. package/dist/core.module-Ctm2stcL.js.map +1 -0
  20. package/dist/define-config-GYI_W9K6.js +34 -0
  21. package/dist/define-config-GYI_W9K6.js.map +1 -0
  22. package/dist/define-config-yzb59aTs.d.ts +34 -0
  23. package/dist/define-module-B83hUzJz.js +58 -0
  24. package/dist/define-module-B83hUzJz.js.map +1 -0
  25. package/dist/define-module-Cw7q13EE.d.ts +56 -0
  26. package/dist/index-CDDzqahH.d.ts +1 -0
  27. package/dist/index-Dfcz46Ma.d.ts +2 -0
  28. package/dist/index-Dw5cCt-A.d.ts +1 -0
  29. package/dist/index.d.ts +15 -616
  30. package/dist/index.js +12 -633
  31. package/dist/loader-Ct4ZivZz.js +177 -0
  32. package/dist/loader-Ct4ZivZz.js.map +1 -0
  33. package/dist/loader-DCNm6pZB.d.ts +73 -0
  34. package/dist/loader-YEqdtcKI.d.ts +29 -0
  35. package/dist/loader-lCPWCMYx.js +75 -0
  36. package/dist/loader-lCPWCMYx.js.map +1 -0
  37. package/dist/modules/define-module.d.ts +4 -0
  38. package/dist/modules/define-module.js +3 -0
  39. package/dist/modules/index.d.ts +7 -0
  40. package/dist/modules/index.js +8 -0
  41. package/dist/modules/loader.d.ts +4 -0
  42. package/dist/modules/loader.js +6 -0
  43. package/dist/modules/registry.d.ts +4 -0
  44. package/dist/modules/registry.js +3 -0
  45. package/dist/modules/types.d.ts +3 -0
  46. package/dist/modules/types.js +1 -0
  47. package/dist/modules-BDQBjAbp.js +1 -0
  48. package/dist/registry-BPYpBtYx.js +83 -0
  49. package/dist/registry-BPYpBtYx.js.map +1 -0
  50. package/dist/registry-CL_5erME.js +132 -0
  51. package/dist/registry-CL_5erME.js.map +1 -0
  52. package/dist/registry-CfpVCPcW.d.ts +68 -0
  53. package/dist/registry-DrTkgmtH.d.ts +90 -0
  54. package/dist/schema/index.d.ts +3 -0
  55. package/dist/schema/index.js +4 -0
  56. package/dist/schema/registry.d.ts +2 -0
  57. package/dist/schema/registry.js +3 -0
  58. package/dist/schema-BuA2HF_H.js +1 -0
  59. package/dist/types-ByO301S-.d.ts +112 -0
  60. package/dist/types-DKCy16X1.d.ts +51 -0
  61. package/dist/types-DxaDmkQo.d.ts +87 -0
  62. package/dist/types.d.ts +2 -0
  63. package/dist/types.js +1 -0
  64. package/package.json +8 -8
@@ -0,0 +1,177 @@
1
+ import { n as getModuleRegistry } from "./registry-CL_5erME.js";
2
+ import { n as getSchemaRegistry } from "./registry-BPYpBtYx.js";
3
+
4
+ //#region src/modules/loader.ts
5
+ /**
6
+ * Validates that a module has the correct shape
7
+ */
8
+ const validateModule = (candidate, packageName) => {
9
+ if (!candidate || typeof candidate !== "object") throw new Error(`Invalid Kuckit module from "${packageName}": expected an object with module definition`);
10
+ const mod = candidate;
11
+ if (!mod.id || typeof mod.id !== "string") throw new Error(`Invalid Kuckit module from "${packageName}": missing or invalid 'id' property`);
12
+ for (const hookName of [
13
+ "register",
14
+ "registerApi",
15
+ "onBootstrap",
16
+ "onShutdown"
17
+ ]) if (mod[hookName] !== void 0 && typeof mod[hookName] !== "function") throw new Error(`Invalid Kuckit module from "${packageName}": '${hookName}' must be a function`);
18
+ return mod;
19
+ };
20
+ /**
21
+ * Load and initialize Kuckit modules
22
+ *
23
+ * This function orchestrates the module loading lifecycle:
24
+ *
25
+ * 1. **Import Phase**: Dynamic import each module package
26
+ * 2. **Register Phase**: Run register() hooks (DI bindings)
27
+ * 3. **API Phase**: Run registerApi() hooks (API routes)
28
+ * 4. **Wire Phase**: Call onApiRegistrations callback
29
+ * 5. **Bootstrap Phase**: Run onBootstrap() hooks
30
+ * 6. **Complete Phase**: Call onComplete callback
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * await loadKuckitModules({
35
+ * container,
36
+ * env: 'production',
37
+ * modules: [
38
+ * { package: '@kuckit/users-module' },
39
+ * { package: '@acme/billing-module', config: { currency: 'USD' } },
40
+ * { package: './src/modules/custom', disabled: process.env.DISABLE_CUSTOM === 'true' },
41
+ * ],
42
+ * onApiRegistrations: (registrations) => {
43
+ * // Wire up oRPC routers, REST routes, etc.
44
+ * for (const reg of registrations) {
45
+ * if (reg.type === 'rpc-router') {
46
+ * rootRouter.merge(reg.name, reg.router)
47
+ * }
48
+ * }
49
+ * },
50
+ * onComplete: () => {
51
+ * console.log('All modules loaded!')
52
+ * },
53
+ * })
54
+ * ```
55
+ */
56
+ const loadKuckitModules = async (opts) => {
57
+ const { container, env, modules, onApiRegistrations, onComplete } = opts;
58
+ const apiRegistrations = [];
59
+ const loadedModules = [];
60
+ const registry = getModuleRegistry();
61
+ for (const spec of modules) {
62
+ if (spec.disabled) continue;
63
+ let validated;
64
+ if (spec.module) validated = validateModule(spec.module, spec.module.id ?? "direct-module");
65
+ else if (spec.package) {
66
+ let imported;
67
+ try {
68
+ imported = await import(spec.package);
69
+ } catch (error) {
70
+ const message = error instanceof Error ? error.message : String(error);
71
+ throw new Error(`Failed to import module "${spec.package}": ${message}`);
72
+ }
73
+ validated = validateModule(imported.kuckitModule ?? imported.default, spec.package);
74
+ } else throw new Error("ModuleSpec must have either \"module\" or \"package\" property");
75
+ registry.register(validated);
76
+ loadedModules.push({
77
+ ...validated,
78
+ _config: spec.config
79
+ });
80
+ }
81
+ for (const mod of loadedModules) if (mod.register) {
82
+ const schemaRegistry = getSchemaRegistry();
83
+ const ctx = {
84
+ container,
85
+ env,
86
+ config: mod._config ?? {},
87
+ registerSchema: (tableName, schema) => {
88
+ schemaRegistry.register(mod.id, tableName, schema);
89
+ }
90
+ };
91
+ try {
92
+ await mod.register(ctx);
93
+ } catch (error) {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ throw new Error(`Module "${mod.id}" register() failed: ${message}`);
96
+ }
97
+ }
98
+ for (const mod of loadedModules) if (mod.registerApi) {
99
+ const schemaRegistry = getSchemaRegistry();
100
+ const ctx = {
101
+ container,
102
+ env,
103
+ config: mod._config ?? {},
104
+ registerSchema: (tableName, schema) => {
105
+ schemaRegistry.register(mod.id, tableName, schema);
106
+ },
107
+ addApiRegistration: (reg) => {
108
+ apiRegistrations.push(reg);
109
+ }
110
+ };
111
+ try {
112
+ await mod.registerApi(ctx);
113
+ } catch (error) {
114
+ const message = error instanceof Error ? error.message : String(error);
115
+ throw new Error(`Module "${mod.id}" registerApi() failed: ${message}`);
116
+ }
117
+ }
118
+ if (onApiRegistrations && apiRegistrations.length > 0) await onApiRegistrations(apiRegistrations);
119
+ for (const mod of loadedModules) if (mod.onBootstrap) {
120
+ const schemaRegistry = getSchemaRegistry();
121
+ const ctx = {
122
+ container,
123
+ env,
124
+ config: mod._config ?? {},
125
+ registerSchema: (tableName, schema) => {
126
+ schemaRegistry.register(mod.id, tableName, schema);
127
+ }
128
+ };
129
+ try {
130
+ await mod.onBootstrap(ctx);
131
+ } catch (error) {
132
+ const message = error instanceof Error ? error.message : String(error);
133
+ throw new Error(`Module "${mod.id}" onBootstrap() failed: ${message}`);
134
+ }
135
+ }
136
+ if (onComplete) await onComplete();
137
+ };
138
+ /**
139
+ * Create a shutdown handler for loaded modules
140
+ *
141
+ * Returns a function that calls onShutdown() on all modules in reverse order.
142
+ * Call this during graceful shutdown.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * const shutdown = createModuleShutdownHandler(loadedModules, container, env)
147
+ *
148
+ * process.on('SIGTERM', async () => {
149
+ * await shutdown()
150
+ * process.exit(0)
151
+ * })
152
+ * ```
153
+ */
154
+ const createModuleShutdownHandler = (modules, container, env) => {
155
+ return async () => {
156
+ for (const mod of [...modules].reverse()) if (mod.onShutdown) {
157
+ const schemaRegistry = getSchemaRegistry();
158
+ const ctx = {
159
+ container,
160
+ env,
161
+ config: {},
162
+ registerSchema: (tableName, schema) => {
163
+ schemaRegistry.register(mod.id, tableName, schema);
164
+ }
165
+ };
166
+ try {
167
+ await mod.onShutdown(ctx);
168
+ } catch (error) {
169
+ console.error(`Module "${mod.id}" onShutdown() failed:`, error);
170
+ }
171
+ }
172
+ };
173
+ };
174
+
175
+ //#endregion
176
+ export { loadKuckitModules as n, createModuleShutdownHandler as t };
177
+ //# sourceMappingURL=loader-Ct4ZivZz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-Ct4ZivZz.js","names":["apiRegistrations: ApiRegistration[]","loadedModules: LoadedModule[]","validated: KuckitModuleDefinition","imported: Record<string, unknown>"],"sources":["../src/modules/loader.ts"],"sourcesContent":["import type { CoreContainer } from '../types'\nimport type { KuckitModuleDefinition, ApiRegistration, ModuleSpec, LoadedModule } from './types'\nimport { getModuleRegistry } from './registry'\nimport { getSchemaRegistry } from '../schema'\n\nexport interface LoadModulesOptions {\n\t/** DI container to register services into */\n\tcontainer: CoreContainer\n\t/** Environment name (development, production, etc.) */\n\tenv: string\n\t/** List of modules to load */\n\tmodules: ModuleSpec[]\n\t/** Hook to wire collected API registrations into your router */\n\tonApiRegistrations?: (regs: ApiRegistration[]) => void | Promise<void>\n\t/** Hook called when all modules are loaded and bootstrapped */\n\tonComplete?: () => void | Promise<void>\n}\n\n/**\n * Validates that a module has the correct shape\n */\nconst validateModule = (candidate: unknown, packageName: string): KuckitModuleDefinition => {\n\tif (!candidate || typeof candidate !== 'object') {\n\t\tthrow new Error(\n\t\t\t`Invalid Kuckit module from \"${packageName}\": expected an object with module definition`\n\t\t)\n\t}\n\n\tconst mod = candidate as Record<string, unknown>\n\n\tif (!mod.id || typeof mod.id !== 'string') {\n\t\tthrow new Error(`Invalid Kuckit module from \"${packageName}\": missing or invalid 'id' property`)\n\t}\n\n\t// Validate hook types if present\n\tconst hookNames = ['register', 'registerApi', 'onBootstrap', 'onShutdown']\n\tfor (const hookName of hookNames) {\n\t\tif (mod[hookName] !== undefined && typeof mod[hookName] !== 'function') {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid Kuckit module from \"${packageName}\": '${hookName}' must be a function`\n\t\t\t)\n\t\t}\n\t}\n\n\treturn mod as unknown as KuckitModuleDefinition\n}\n\n/**\n * Load and initialize Kuckit modules\n *\n * This function orchestrates the module loading lifecycle:\n *\n * 1. **Import Phase**: Dynamic import each module package\n * 2. **Register Phase**: Run register() hooks (DI bindings)\n * 3. **API Phase**: Run registerApi() hooks (API routes)\n * 4. **Wire Phase**: Call onApiRegistrations callback\n * 5. **Bootstrap Phase**: Run onBootstrap() hooks\n * 6. **Complete Phase**: Call onComplete callback\n *\n * @example\n * ```ts\n * await loadKuckitModules({\n * container,\n * env: 'production',\n * modules: [\n * { package: '@kuckit/users-module' },\n * { package: '@acme/billing-module', config: { currency: 'USD' } },\n * { package: './src/modules/custom', disabled: process.env.DISABLE_CUSTOM === 'true' },\n * ],\n * onApiRegistrations: (registrations) => {\n * // Wire up oRPC routers, REST routes, etc.\n * for (const reg of registrations) {\n * if (reg.type === 'rpc-router') {\n * rootRouter.merge(reg.name, reg.router)\n * }\n * }\n * },\n * onComplete: () => {\n * console.log('All modules loaded!')\n * },\n * })\n * ```\n */\nexport const loadKuckitModules = async (opts: LoadModulesOptions): Promise<void> => {\n\tconst { container, env, modules, onApiRegistrations, onComplete } = opts\n\n\tconst apiRegistrations: ApiRegistration[] = []\n\tconst loadedModules: LoadedModule[] = []\n\tconst registry = getModuleRegistry()\n\n\t// Phase 1: Import and validate all modules\n\tfor (const spec of modules) {\n\t\tif (spec.disabled) {\n\t\t\tcontinue\n\t\t}\n\n\t\tlet validated: KuckitModuleDefinition\n\n\t\t// Prefer direct module reference over dynamic import\n\t\tif (spec.module) {\n\t\t\tvalidated = validateModule(spec.module, spec.module.id ?? 'direct-module')\n\t\t} else if (spec.package) {\n\t\t\tlet imported: Record<string, unknown>\n\t\t\ttry {\n\t\t\t\timported = await import(spec.package)\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tthrow new Error(`Failed to import module \"${spec.package}\": ${message}`)\n\t\t\t}\n\n\t\t\t// Look for kuckitModule export (preferred) or default export\n\t\t\tconst candidate = imported.kuckitModule ?? imported.default\n\t\t\tvalidated = validateModule(candidate, spec.package)\n\t\t} else {\n\t\t\tthrow new Error('ModuleSpec must have either \"module\" or \"package\" property')\n\t\t}\n\n\t\t// Register module in the global registry (validates capabilities)\n\t\tregistry.register(validated)\n\n\t\tloadedModules.push({ ...validated, _config: spec.config })\n\t}\n\n\t// Phase 2: Run register() hooks\n\tfor (const mod of loadedModules) {\n\t\tif (mod.register) {\n\t\t\tconst schemaRegistry = getSchemaRegistry()\n\t\t\tconst ctx = {\n\t\t\t\tcontainer,\n\t\t\t\tenv,\n\t\t\t\tconfig: mod._config ?? {},\n\t\t\t\tregisterSchema: (tableName: string, schema: unknown) => {\n\t\t\t\t\tschemaRegistry.register(\n\t\t\t\t\t\tmod.id,\n\t\t\t\t\t\ttableName,\n\t\t\t\t\t\tschema as import('drizzle-orm/pg-core').PgTable\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait mod.register(ctx)\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tthrow new Error(`Module \"${mod.id}\" register() failed: ${message}`)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Phase 3: Run registerApi() hooks\n\tfor (const mod of loadedModules) {\n\t\tif (mod.registerApi) {\n\t\t\tconst schemaRegistry = getSchemaRegistry()\n\t\t\tconst ctx = {\n\t\t\t\tcontainer,\n\t\t\t\tenv,\n\t\t\t\tconfig: mod._config ?? {},\n\t\t\t\tregisterSchema: (tableName: string, schema: unknown) => {\n\t\t\t\t\tschemaRegistry.register(\n\t\t\t\t\t\tmod.id,\n\t\t\t\t\t\ttableName,\n\t\t\t\t\t\tschema as import('drizzle-orm/pg-core').PgTable\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\taddApiRegistration: (reg: ApiRegistration) => {\n\t\t\t\t\tapiRegistrations.push(reg)\n\t\t\t\t},\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait mod.registerApi(ctx)\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tthrow new Error(`Module \"${mod.id}\" registerApi() failed: ${message}`)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Phase 4: Wire API registrations\n\tif (onApiRegistrations && apiRegistrations.length > 0) {\n\t\tawait onApiRegistrations(apiRegistrations)\n\t}\n\n\t// Phase 5: Run onBootstrap() hooks\n\tfor (const mod of loadedModules) {\n\t\tif (mod.onBootstrap) {\n\t\t\tconst schemaRegistry = getSchemaRegistry()\n\t\t\tconst ctx = {\n\t\t\t\tcontainer,\n\t\t\t\tenv,\n\t\t\t\tconfig: mod._config ?? {},\n\t\t\t\tregisterSchema: (tableName: string, schema: unknown) => {\n\t\t\t\t\tschemaRegistry.register(\n\t\t\t\t\t\tmod.id,\n\t\t\t\t\t\ttableName,\n\t\t\t\t\t\tschema as import('drizzle-orm/pg-core').PgTable\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait mod.onBootstrap(ctx)\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tthrow new Error(`Module \"${mod.id}\" onBootstrap() failed: ${message}`)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Phase 6: Complete\n\tif (onComplete) {\n\t\tawait onComplete()\n\t}\n}\n\n/**\n * Create a shutdown handler for loaded modules\n *\n * Returns a function that calls onShutdown() on all modules in reverse order.\n * Call this during graceful shutdown.\n *\n * @example\n * ```ts\n * const shutdown = createModuleShutdownHandler(loadedModules, container, env)\n *\n * process.on('SIGTERM', async () => {\n * await shutdown()\n * process.exit(0)\n * })\n * ```\n */\nexport const createModuleShutdownHandler = (\n\tmodules: KuckitModuleDefinition[],\n\tcontainer: CoreContainer,\n\tenv: string\n): (() => Promise<void>) => {\n\treturn async () => {\n\t\t// Shutdown in reverse order\n\t\tfor (const mod of [...modules].reverse()) {\n\t\t\tif (mod.onShutdown) {\n\t\t\t\tconst schemaRegistry = getSchemaRegistry()\n\t\t\t\tconst ctx = {\n\t\t\t\t\tcontainer,\n\t\t\t\t\tenv,\n\t\t\t\t\tconfig: {},\n\t\t\t\t\tregisterSchema: (tableName: string, schema: unknown) => {\n\t\t\t\t\t\tschemaRegistry.register(\n\t\t\t\t\t\t\tmod.id,\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tschema as import('drizzle-orm/pg-core').PgTable\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tawait mod.onShutdown(ctx)\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Log but don't throw during shutdown\n\t\t\t\t\tconsole.error(`Module \"${mod.id}\" onShutdown() failed:`, error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { n as CoreContainer } from "./types-DKCy16X1.js";
2
+ import { i as KuckitModuleDefinition, l as ModuleSpec, t as ApiRegistration } from "./types-ByO301S-.js";
3
+
4
+ //#region src/modules/loader.d.ts
5
+ interface LoadModulesOptions {
6
+ /** DI container to register services into */
7
+ container: CoreContainer;
8
+ /** Environment name (development, production, etc.) */
9
+ env: string;
10
+ /** List of modules to load */
11
+ modules: ModuleSpec[];
12
+ /** Hook to wire collected API registrations into your router */
13
+ onApiRegistrations?: (regs: ApiRegistration[]) => void | Promise<void>;
14
+ /** Hook called when all modules are loaded and bootstrapped */
15
+ onComplete?: () => void | Promise<void>;
16
+ }
17
+ /**
18
+ * Load and initialize Kuckit modules
19
+ *
20
+ * This function orchestrates the module loading lifecycle:
21
+ *
22
+ * 1. **Import Phase**: Dynamic import each module package
23
+ * 2. **Register Phase**: Run register() hooks (DI bindings)
24
+ * 3. **API Phase**: Run registerApi() hooks (API routes)
25
+ * 4. **Wire Phase**: Call onApiRegistrations callback
26
+ * 5. **Bootstrap Phase**: Run onBootstrap() hooks
27
+ * 6. **Complete Phase**: Call onComplete callback
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * await loadKuckitModules({
32
+ * container,
33
+ * env: 'production',
34
+ * modules: [
35
+ * { package: '@kuckit/users-module' },
36
+ * { package: '@acme/billing-module', config: { currency: 'USD' } },
37
+ * { package: './src/modules/custom', disabled: process.env.DISABLE_CUSTOM === 'true' },
38
+ * ],
39
+ * onApiRegistrations: (registrations) => {
40
+ * // Wire up oRPC routers, REST routes, etc.
41
+ * for (const reg of registrations) {
42
+ * if (reg.type === 'rpc-router') {
43
+ * rootRouter.merge(reg.name, reg.router)
44
+ * }
45
+ * }
46
+ * },
47
+ * onComplete: () => {
48
+ * console.log('All modules loaded!')
49
+ * },
50
+ * })
51
+ * ```
52
+ */
53
+ declare const loadKuckitModules: (opts: LoadModulesOptions) => Promise<void>;
54
+ /**
55
+ * Create a shutdown handler for loaded modules
56
+ *
57
+ * Returns a function that calls onShutdown() on all modules in reverse order.
58
+ * Call this during graceful shutdown.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const shutdown = createModuleShutdownHandler(loadedModules, container, env)
63
+ *
64
+ * process.on('SIGTERM', async () => {
65
+ * await shutdown()
66
+ * process.exit(0)
67
+ * })
68
+ * ```
69
+ */
70
+ declare const createModuleShutdownHandler: (modules: KuckitModuleDefinition[], container: CoreContainer, env: string) => (() => Promise<void>);
71
+ //#endregion
72
+ export { createModuleShutdownHandler as n, loadKuckitModules as r, LoadModulesOptions as t };
73
+ //# sourceMappingURL=loader-DCNm6pZB.d.ts.map
@@ -0,0 +1,29 @@
1
+ import { o as LoadedKuckitConfig } from "./types-DxaDmkQo.js";
2
+
3
+ //#region src/config/loader.d.ts
4
+
5
+ /**
6
+ * Find the config file path by searching from cwd upward
7
+ */
8
+ declare function findConfigFile(cwd?: string): string | null;
9
+ /**
10
+ * Check if a unified config file exists
11
+ */
12
+ declare function hasUnifiedConfig(cwd?: string): boolean;
13
+ /**
14
+ * Load Kuckit configuration from file
15
+ *
16
+ * Uses jiti for TypeScript support at runtime.
17
+ * Falls back to dynamic import for JS/MJS files.
18
+ *
19
+ * @param cwd - Directory to start searching from (default: process.cwd())
20
+ * @throws Error if config file not found or invalid
21
+ */
22
+ declare function loadKuckitConfig(cwd?: string): Promise<LoadedKuckitConfig>;
23
+ /**
24
+ * Try to load config, returning null if not found
25
+ */
26
+ declare function tryLoadKuckitConfig(cwd?: string): Promise<LoadedKuckitConfig | null>;
27
+ //#endregion
28
+ export { tryLoadKuckitConfig as i, hasUnifiedConfig as n, loadKuckitConfig as r, findConfigFile as t };
29
+ //# sourceMappingURL=loader-YEqdtcKI.d.ts.map
@@ -0,0 +1,75 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+
4
+ //#region src/config/loader.ts
5
+ const CONFIG_FILES = [
6
+ "kuckit.config.ts",
7
+ "kuckit.config.js",
8
+ "kuckit.config.mjs"
9
+ ];
10
+ /**
11
+ * Find the config file path by searching from cwd upward
12
+ */
13
+ function findConfigFile(cwd = process.cwd()) {
14
+ let dir = cwd;
15
+ while (dir !== dirname(dir)) {
16
+ for (const file of CONFIG_FILES) {
17
+ const configPath = resolve(dir, file);
18
+ if (existsSync(configPath)) return configPath;
19
+ }
20
+ dir = dirname(dir);
21
+ }
22
+ for (const file of CONFIG_FILES) {
23
+ const configPath = resolve(dir, file);
24
+ if (existsSync(configPath)) return configPath;
25
+ }
26
+ return null;
27
+ }
28
+ /**
29
+ * Check if a unified config file exists
30
+ */
31
+ function hasUnifiedConfig(cwd = process.cwd()) {
32
+ return findConfigFile(cwd) !== null;
33
+ }
34
+ /**
35
+ * Load Kuckit configuration from file
36
+ *
37
+ * Uses jiti for TypeScript support at runtime.
38
+ * Falls back to dynamic import for JS/MJS files.
39
+ *
40
+ * @param cwd - Directory to start searching from (default: process.cwd())
41
+ * @throws Error if config file not found or invalid
42
+ */
43
+ async function loadKuckitConfig(cwd = process.cwd()) {
44
+ const configPath = findConfigFile(cwd);
45
+ if (!configPath) throw new Error(`No Kuckit config file found. Create a kuckit.config.ts at your project root.\nSearched from: ${cwd}`);
46
+ let config;
47
+ if (configPath.endsWith(".ts")) {
48
+ const { createJiti } = await import("jiti");
49
+ const loaded = await createJiti(cwd, { interopDefault: true }).import(configPath);
50
+ config = loaded.default ?? loaded;
51
+ } else {
52
+ const loaded = await import(configPath);
53
+ config = loaded.default ?? loaded;
54
+ }
55
+ if (!config || typeof config !== "object") throw new Error(`Invalid Kuckit config at ${configPath}: expected an object`);
56
+ if (!Array.isArray(config.modules)) throw new Error(`Invalid Kuckit config at ${configPath}: 'modules' must be an array`);
57
+ return {
58
+ ...config,
59
+ _configPath: configPath
60
+ };
61
+ }
62
+ /**
63
+ * Try to load config, returning null if not found
64
+ */
65
+ async function tryLoadKuckitConfig(cwd = process.cwd()) {
66
+ try {
67
+ return await loadKuckitConfig(cwd);
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+
73
+ //#endregion
74
+ export { tryLoadKuckitConfig as i, hasUnifiedConfig as n, loadKuckitConfig as r, findConfigFile as t };
75
+ //# sourceMappingURL=loader-lCPWCMYx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-lCPWCMYx.js","names":["config: KuckitConfig"],"sources":["../src/config/loader.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport type { KuckitConfig, LoadedKuckitConfig } from './types'\n\nconst CONFIG_FILES = ['kuckit.config.ts', 'kuckit.config.js', 'kuckit.config.mjs']\n\n/**\n * Find the config file path by searching from cwd upward\n */\nexport function findConfigFile(cwd: string = process.cwd()): string | null {\n\tlet dir = cwd\n\n\twhile (dir !== dirname(dir)) {\n\t\tfor (const file of CONFIG_FILES) {\n\t\t\tconst configPath = resolve(dir, file)\n\t\t\tif (existsSync(configPath)) {\n\t\t\t\treturn configPath\n\t\t\t}\n\t\t}\n\t\tdir = dirname(dir)\n\t}\n\n\t// Check root directory\n\tfor (const file of CONFIG_FILES) {\n\t\tconst configPath = resolve(dir, file)\n\t\tif (existsSync(configPath)) {\n\t\t\treturn configPath\n\t\t}\n\t}\n\n\treturn null\n}\n\n/**\n * Check if a unified config file exists\n */\nexport function hasUnifiedConfig(cwd: string = process.cwd()): boolean {\n\treturn findConfigFile(cwd) !== null\n}\n\n/**\n * Load Kuckit configuration from file\n *\n * Uses jiti for TypeScript support at runtime.\n * Falls back to dynamic import for JS/MJS files.\n *\n * @param cwd - Directory to start searching from (default: process.cwd())\n * @throws Error if config file not found or invalid\n */\nexport async function loadKuckitConfig(cwd: string = process.cwd()): Promise<LoadedKuckitConfig> {\n\tconst configPath = findConfigFile(cwd)\n\n\tif (!configPath) {\n\t\tthrow new Error(\n\t\t\t`No Kuckit config file found. Create a kuckit.config.ts at your project root.\\n` +\n\t\t\t\t`Searched from: ${cwd}`\n\t\t)\n\t}\n\n\tlet config: KuckitConfig\n\n\tif (configPath.endsWith('.ts')) {\n\t\t// Use jiti for TypeScript files\n\t\tconst { createJiti } = await import('jiti')\n\t\tconst jiti = createJiti(cwd, {\n\t\t\tinteropDefault: true,\n\t\t})\n\t\tconst loaded = await jiti.import(configPath)\n\t\tconfig = (loaded as { default?: KuckitConfig }).default ?? (loaded as KuckitConfig)\n\t} else {\n\t\t// Use dynamic import for JS/MJS\n\t\tconst loaded = await import(configPath)\n\t\tconfig = loaded.default ?? loaded\n\t}\n\n\t// Validate config\n\tif (!config || typeof config !== 'object') {\n\t\tthrow new Error(`Invalid Kuckit config at ${configPath}: expected an object`)\n\t}\n\n\tif (!Array.isArray(config.modules)) {\n\t\tthrow new Error(`Invalid Kuckit config at ${configPath}: 'modules' must be an array`)\n\t}\n\n\treturn {\n\t\t...config,\n\t\t_configPath: configPath,\n\t}\n}\n\n/**\n * Try to load config, returning null if not found\n */\nexport async function tryLoadKuckitConfig(\n\tcwd: string = process.cwd()\n): Promise<LoadedKuckitConfig | null> {\n\ttry {\n\t\treturn await loadKuckitConfig(cwd)\n\t} catch {\n\t\treturn null\n\t}\n}\n"],"mappings":";;;;AAIA,MAAM,eAAe;CAAC;CAAoB;CAAoB;CAAoB;;;;AAKlF,SAAgB,eAAe,MAAc,QAAQ,KAAK,EAAiB;CAC1E,IAAI,MAAM;AAEV,QAAO,QAAQ,QAAQ,IAAI,EAAE;AAC5B,OAAK,MAAM,QAAQ,cAAc;GAChC,MAAM,aAAa,QAAQ,KAAK,KAAK;AACrC,OAAI,WAAW,WAAW,CACzB,QAAO;;AAGT,QAAM,QAAQ,IAAI;;AAInB,MAAK,MAAM,QAAQ,cAAc;EAChC,MAAM,aAAa,QAAQ,KAAK,KAAK;AACrC,MAAI,WAAW,WAAW,CACzB,QAAO;;AAIT,QAAO;;;;;AAMR,SAAgB,iBAAiB,MAAc,QAAQ,KAAK,EAAW;AACtE,QAAO,eAAe,IAAI,KAAK;;;;;;;;;;;AAYhC,eAAsB,iBAAiB,MAAc,QAAQ,KAAK,EAA+B;CAChG,MAAM,aAAa,eAAe,IAAI;AAEtC,KAAI,CAAC,WACJ,OAAM,IAAI,MACT,gGACmB,MACnB;CAGF,IAAIA;AAEJ,KAAI,WAAW,SAAS,MAAM,EAAE;EAE/B,MAAM,EAAE,eAAe,MAAM,OAAO;EAIpC,MAAM,SAAS,MAHF,WAAW,KAAK,EAC5B,gBAAgB,MAChB,CAAC,CACwB,OAAO,WAAW;AAC5C,WAAU,OAAsC,WAAY;QACtD;EAEN,MAAM,SAAS,MAAM,OAAO;AAC5B,WAAS,OAAO,WAAW;;AAI5B,KAAI,CAAC,UAAU,OAAO,WAAW,SAChC,OAAM,IAAI,MAAM,4BAA4B,WAAW,sBAAsB;AAG9E,KAAI,CAAC,MAAM,QAAQ,OAAO,QAAQ,CACjC,OAAM,IAAI,MAAM,4BAA4B,WAAW,8BAA8B;AAGtF,QAAO;EACN,GAAG;EACH,aAAa;EACb;;;;;AAMF,eAAsB,oBACrB,MAAc,QAAQ,KAAK,EACU;AACrC,KAAI;AACH,SAAO,MAAM,iBAAiB,IAAI;SAC3B;AACP,SAAO"}
@@ -0,0 +1,4 @@
1
+ import "../types-DKCy16X1.js";
2
+ import "../types-ByO301S-.js";
3
+ import { t as defineKuckitModule } from "../define-module-Cw7q13EE.js";
4
+ export { defineKuckitModule };
@@ -0,0 +1,3 @@
1
+ import { t as defineKuckitModule } from "../define-module-B83hUzJz.js";
2
+
3
+ export { defineKuckitModule };
@@ -0,0 +1,7 @@
1
+ import "../types-DKCy16X1.js";
2
+ import { a as KuckitModuleHooks, c as ModuleCapability, i as KuckitModuleDefinition, l as ModuleSpec, n as BuiltInCapability, o as KuckitModuleMeta, r as KuckitModuleContext, t as ApiRegistration } from "../types-ByO301S-.js";
3
+ import { t as defineKuckitModule } from "../define-module-Cw7q13EE.js";
4
+ import { n as createModuleShutdownHandler, r as loadKuckitModules, t as LoadModulesOptions } from "../loader-DCNm6pZB.js";
5
+ import { a as resetModuleRegistry, i as getModulesWithCapability, n as ModuleRegistry, r as getModuleRegistry, t as LoadedModuleInfo } from "../registry-DrTkgmtH.js";
6
+ import "../index-Dw5cCt-A.js";
7
+ export { ApiRegistration, BuiltInCapability, KuckitModuleContext, KuckitModuleDefinition, KuckitModuleHooks, KuckitModuleMeta, LoadModulesOptions, LoadedModuleInfo, ModuleCapability, ModuleRegistry, ModuleSpec, createModuleShutdownHandler, defineKuckitModule, getModuleRegistry, getModulesWithCapability, loadKuckitModules, resetModuleRegistry };
@@ -0,0 +1,8 @@
1
+ import { t as defineKuckitModule } from "../define-module-B83hUzJz.js";
2
+ import { i as resetModuleRegistry, n as getModuleRegistry, r as getModulesWithCapability, t as ModuleRegistry } from "../registry-CL_5erME.js";
3
+ import "../registry-BPYpBtYx.js";
4
+ import "../schema-BuA2HF_H.js";
5
+ import { n as loadKuckitModules, t as createModuleShutdownHandler } from "../loader-Ct4ZivZz.js";
6
+ import "../modules-BDQBjAbp.js";
7
+
8
+ export { ModuleRegistry, createModuleShutdownHandler, defineKuckitModule, getModuleRegistry, getModulesWithCapability, loadKuckitModules, resetModuleRegistry };
@@ -0,0 +1,4 @@
1
+ import "../types-DKCy16X1.js";
2
+ import "../types-ByO301S-.js";
3
+ import { n as createModuleShutdownHandler, r as loadKuckitModules, t as LoadModulesOptions } from "../loader-DCNm6pZB.js";
4
+ export { LoadModulesOptions, createModuleShutdownHandler, loadKuckitModules };
@@ -0,0 +1,6 @@
1
+ import "../registry-CL_5erME.js";
2
+ import "../registry-BPYpBtYx.js";
3
+ import "../schema-BuA2HF_H.js";
4
+ import { n as loadKuckitModules, t as createModuleShutdownHandler } from "../loader-Ct4ZivZz.js";
5
+
6
+ export { createModuleShutdownHandler, loadKuckitModules };
@@ -0,0 +1,4 @@
1
+ import "../types-DKCy16X1.js";
2
+ import "../types-ByO301S-.js";
3
+ import { a as resetModuleRegistry, i as getModulesWithCapability, n as ModuleRegistry, r as getModuleRegistry, t as LoadedModuleInfo } from "../registry-DrTkgmtH.js";
4
+ export { LoadedModuleInfo, ModuleRegistry, getModuleRegistry, getModulesWithCapability, resetModuleRegistry };
@@ -0,0 +1,3 @@
1
+ import { i as resetModuleRegistry, n as getModuleRegistry, r as getModulesWithCapability, t as ModuleRegistry } from "../registry-CL_5erME.js";
2
+
3
+ export { ModuleRegistry, getModuleRegistry, getModulesWithCapability, resetModuleRegistry };
@@ -0,0 +1,3 @@
1
+ import "../types-DKCy16X1.js";
2
+ import { a as KuckitModuleHooks, c as ModuleCapability, i as KuckitModuleDefinition, l as ModuleSpec, n as BuiltInCapability, o as KuckitModuleMeta, r as KuckitModuleContext, s as LoadedModule, t as ApiRegistration } from "../types-ByO301S-.js";
3
+ export { ApiRegistration, BuiltInCapability, KuckitModuleContext, KuckitModuleDefinition, KuckitModuleHooks, KuckitModuleMeta, LoadedModule, ModuleCapability, ModuleSpec };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,83 @@
1
+ //#region src/schema/registry.ts
2
+ /**
3
+ * Registry for module-owned database schemas
4
+ *
5
+ * Allows modules to register their Drizzle schemas during the register() hook.
6
+ * The CLI uses this registry to aggregate schemas for drizzle-kit operations.
7
+ */
8
+ var SchemaRegistry = class {
9
+ schemas = /* @__PURE__ */ new Map();
10
+ /**
11
+ * Register a schema from a module
12
+ * @param moduleId - Module identifier (e.g., 'acme.billing')
13
+ * @param tableName - Table name identifier (e.g., 'invoices')
14
+ * @param schema - Drizzle PgTable schema
15
+ */
16
+ register(moduleId, tableName, schema) {
17
+ const key = `${moduleId}:${tableName}`;
18
+ if (this.schemas.has(key)) throw new Error(`Schema "${tableName}" already registered by module "${moduleId}"`);
19
+ this.schemas.set(key, {
20
+ moduleId,
21
+ tableName,
22
+ schema
23
+ });
24
+ }
25
+ /**
26
+ * Get all registered schemas
27
+ */
28
+ getAll() {
29
+ return new Map(this.schemas);
30
+ }
31
+ /**
32
+ * Get schemas registered by a specific module
33
+ */
34
+ getByModule(moduleId) {
35
+ return Array.from(this.schemas.values()).filter((entry) => entry.moduleId === moduleId);
36
+ }
37
+ /**
38
+ * Get all schemas as a flat object for drizzle-kit
39
+ * Keys are table names, values are PgTable schemas
40
+ */
41
+ getAllSchemas() {
42
+ const result = {};
43
+ for (const entry of this.schemas.values()) result[entry.tableName] = entry.schema;
44
+ return result;
45
+ }
46
+ /**
47
+ * Check if any schemas are registered
48
+ */
49
+ hasSchemas() {
50
+ return this.schemas.size > 0;
51
+ }
52
+ /**
53
+ * Get the count of registered schemas
54
+ */
55
+ get size() {
56
+ return this.schemas.size;
57
+ }
58
+ /**
59
+ * Clear all schemas (mainly for testing)
60
+ */
61
+ clear() {
62
+ this.schemas.clear();
63
+ }
64
+ };
65
+ let globalSchemaRegistry = null;
66
+ /**
67
+ * Get the global schema registry
68
+ * Creates one if it doesn't exist
69
+ */
70
+ function getSchemaRegistry() {
71
+ if (!globalSchemaRegistry) globalSchemaRegistry = new SchemaRegistry();
72
+ return globalSchemaRegistry;
73
+ }
74
+ /**
75
+ * Reset the global schema registry (mainly for testing)
76
+ */
77
+ function resetSchemaRegistry() {
78
+ globalSchemaRegistry = null;
79
+ }
80
+
81
+ //#endregion
82
+ export { getSchemaRegistry as n, resetSchemaRegistry as r, SchemaRegistry as t };
83
+ //# sourceMappingURL=registry-BPYpBtYx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-BPYpBtYx.js","names":["result: Record<string, PgTable>","globalSchemaRegistry: SchemaRegistry | null"],"sources":["../src/schema/registry.ts"],"sourcesContent":["import type { PgTable } from 'drizzle-orm/pg-core'\n\n/**\n * Entry for a registered schema\n */\nexport interface SchemaEntry {\n\t/** Module that owns this schema */\n\tmoduleId: string\n\t/** Table name identifier */\n\ttableName: string\n\t/** Drizzle table schema */\n\tschema: PgTable\n}\n\n/**\n * Registry for module-owned database schemas\n *\n * Allows modules to register their Drizzle schemas during the register() hook.\n * The CLI uses this registry to aggregate schemas for drizzle-kit operations.\n */\nexport class SchemaRegistry {\n\tprivate schemas = new Map<string, SchemaEntry>()\n\n\t/**\n\t * Register a schema from a module\n\t * @param moduleId - Module identifier (e.g., 'acme.billing')\n\t * @param tableName - Table name identifier (e.g., 'invoices')\n\t * @param schema - Drizzle PgTable schema\n\t */\n\tregister(moduleId: string, tableName: string, schema: PgTable): void {\n\t\tconst key = `${moduleId}:${tableName}`\n\t\tif (this.schemas.has(key)) {\n\t\t\tthrow new Error(`Schema \"${tableName}\" already registered by module \"${moduleId}\"`)\n\t\t}\n\t\tthis.schemas.set(key, { moduleId, tableName, schema })\n\t}\n\n\t/**\n\t * Get all registered schemas\n\t */\n\tgetAll(): Map<string, SchemaEntry> {\n\t\treturn new Map(this.schemas)\n\t}\n\n\t/**\n\t * Get schemas registered by a specific module\n\t */\n\tgetByModule(moduleId: string): SchemaEntry[] {\n\t\treturn Array.from(this.schemas.values()).filter((entry) => entry.moduleId === moduleId)\n\t}\n\n\t/**\n\t * Get all schemas as a flat object for drizzle-kit\n\t * Keys are table names, values are PgTable schemas\n\t */\n\tgetAllSchemas(): Record<string, PgTable> {\n\t\tconst result: Record<string, PgTable> = {}\n\t\tfor (const entry of this.schemas.values()) {\n\t\t\tresult[entry.tableName] = entry.schema\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Check if any schemas are registered\n\t */\n\thasSchemas(): boolean {\n\t\treturn this.schemas.size > 0\n\t}\n\n\t/**\n\t * Get the count of registered schemas\n\t */\n\tget size(): number {\n\t\treturn this.schemas.size\n\t}\n\n\t/**\n\t * Clear all schemas (mainly for testing)\n\t */\n\tclear(): void {\n\t\tthis.schemas.clear()\n\t}\n}\n\n// Global schema registry instance\nlet globalSchemaRegistry: SchemaRegistry | null = null\n\n/**\n * Get the global schema registry\n * Creates one if it doesn't exist\n */\nexport function getSchemaRegistry(): SchemaRegistry {\n\tif (!globalSchemaRegistry) {\n\t\tglobalSchemaRegistry = new SchemaRegistry()\n\t}\n\treturn globalSchemaRegistry\n}\n\n/**\n * Reset the global schema registry (mainly for testing)\n */\nexport function resetSchemaRegistry(): void {\n\tglobalSchemaRegistry = null\n}\n"],"mappings":";;;;;;;AAoBA,IAAa,iBAAb,MAA4B;CAC3B,AAAQ,0BAAU,IAAI,KAA0B;;;;;;;CAQhD,SAAS,UAAkB,WAAmB,QAAuB;EACpE,MAAM,MAAM,GAAG,SAAS,GAAG;AAC3B,MAAI,KAAK,QAAQ,IAAI,IAAI,CACxB,OAAM,IAAI,MAAM,WAAW,UAAU,kCAAkC,SAAS,GAAG;AAEpF,OAAK,QAAQ,IAAI,KAAK;GAAE;GAAU;GAAW;GAAQ,CAAC;;;;;CAMvD,SAAmC;AAClC,SAAO,IAAI,IAAI,KAAK,QAAQ;;;;;CAM7B,YAAY,UAAiC;AAC5C,SAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,CAAC,QAAQ,UAAU,MAAM,aAAa,SAAS;;;;;;CAOxF,gBAAyC;EACxC,MAAMA,SAAkC,EAAE;AAC1C,OAAK,MAAM,SAAS,KAAK,QAAQ,QAAQ,CACxC,QAAO,MAAM,aAAa,MAAM;AAEjC,SAAO;;;;;CAMR,aAAsB;AACrB,SAAO,KAAK,QAAQ,OAAO;;;;;CAM5B,IAAI,OAAe;AAClB,SAAO,KAAK,QAAQ;;;;;CAMrB,QAAc;AACb,OAAK,QAAQ,OAAO;;;AAKtB,IAAIC,uBAA8C;;;;;AAMlD,SAAgB,oBAAoC;AACnD,KAAI,CAAC,qBACJ,wBAAuB,IAAI,gBAAgB;AAE5C,QAAO;;;;;AAMR,SAAgB,sBAA4B;AAC3C,wBAAuB"}