@forinda/kickjs 5.16.0 → 5.18.0-alpha.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.
- package/dist/adapter-D_uzU-QA.d.mts +2121 -0
- package/dist/adapter-D_uzU-QA.d.mts.map +1 -0
- package/dist/{context-decorator-DDZ30BIW.d.mts → app-module-CuAS6hJC.d.mts} +184 -4
- package/dist/app-module-CuAS6hJC.d.mts.map +1 -0
- package/dist/application-BU5N6o_M.mjs +12 -0
- package/dist/application-BU5N6o_M.mjs.map +1 -0
- package/dist/{application-CAnpDQ8d.d.mts → application-pbx53JnX.d.mts} +31 -5
- package/dist/application-pbx53JnX.d.mts.map +1 -0
- package/dist/{bootstrap-CFK2aAjA.mjs → bootstrap-CFog4v_L.mjs} +3 -3
- package/dist/{bootstrap-CFK2aAjA.mjs.map → bootstrap-CFog4v_L.mjs.map} +1 -1
- package/dist/{bootstrap-8DDzBjhx.d.mts → bootstrap-DzfBj6Ja.d.mts} +2 -2
- package/dist/{bootstrap-8DDzBjhx.d.mts.map → bootstrap-DzfBj6Ja.d.mts.map} +1 -1
- package/dist/config/index.mjs +2 -2
- package/dist/{config-BW5taOVX.mjs → config-Di3HlRTS.mjs} +3 -3
- package/dist/{config-BW5taOVX.mjs.map → config-Di3HlRTS.mjs.map} +1 -1
- package/dist/{container-D1gfs6__.mjs → container-BiGimG12.mjs} +3 -3
- package/dist/{container-D1gfs6__.mjs.map → container-BiGimG12.mjs.map} +1 -1
- package/dist/context-leZajQAj.mjs +12 -0
- package/dist/context-leZajQAj.mjs.map +1 -0
- package/dist/core/adapter.d.mts +1 -1
- package/dist/core/adapter.mjs +1 -1
- package/dist/core/app-module.d.mts +1 -1
- package/dist/core/app-module.mjs +1 -1
- package/dist/core/cache.mjs +1 -1
- package/dist/core/container.mjs +2 -2
- package/dist/core/cron.mjs +2 -2
- package/dist/core/decorators.mjs +2 -2
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/errors.mjs +2 -2
- package/dist/core/errors.mjs.map +1 -1
- package/dist/core/interfaces.mjs +1 -1
- package/dist/core/logger.mjs +1 -1
- package/dist/core/path.mjs +1 -1
- package/dist/core/plugin.d.mts +1 -1
- package/dist/core/plugin.mjs +1 -1
- package/dist/core/reactivity.mjs +1 -1
- package/dist/{core-Db2uyqtM.mjs → core-Y_xSqZ7v.mjs} +3 -3
- package/dist/{core-Db2uyqtM.mjs.map → core-Y_xSqZ7v.mjs.map} +1 -1
- package/dist/{env-nwsfCpdy.mjs → env-BoMBrGWs.mjs} +3 -3
- package/dist/{env-nwsfCpdy.mjs.map → env-BoMBrGWs.mjs.map} +1 -1
- package/dist/{errors-CRCTjEUK.d.mts → errors-n0H96eEz.d.mts} +3 -1
- package/dist/errors-n0H96eEz.d.mts.map +1 -0
- package/dist/http/application.d.mts +1 -1
- package/dist/http/application.mjs +2 -2
- package/dist/http/bootstrap.d.mts +1 -1
- package/dist/http/bootstrap.mjs +2 -2
- package/dist/http/context.d.mts +2 -2
- package/dist/http/context.mjs +2 -2
- package/dist/http/middleware/cors.mjs +1 -1
- package/dist/http/middleware/csrf.mjs +1 -1
- package/dist/http/middleware/error-handler.mjs +2 -2
- package/dist/http/middleware/helmet.mjs +1 -1
- package/dist/http/middleware/rate-limit.mjs +1 -1
- package/dist/http/middleware/request-id.mjs +1 -1
- package/dist/http/middleware/request-logger.mjs +2 -2
- package/dist/http/middleware/session.mjs +1 -1
- package/dist/http/middleware/spa.d.mts +1 -1
- package/dist/http/middleware/spa.mjs +2 -2
- package/dist/http/middleware/upload.d.mts +2 -2
- package/dist/http/middleware/upload.mjs +3 -3
- package/dist/http/middleware/upload.mjs.map +1 -1
- package/dist/http/middleware/validate.mjs +2 -2
- package/dist/http/middleware/views.d.mts +1 -1
- package/dist/http/middleware/views.mjs +2 -2
- package/dist/http/query/index.d.mts +2 -2
- package/dist/http/query/index.mjs +2 -2
- package/dist/http/router-builder.d.mts +2 -2
- package/dist/http/router-builder.mjs +2 -2
- package/dist/http/router-builder.mjs.map +1 -1
- package/dist/http/runtimes/fastify.d.mts +66 -0
- package/dist/http/runtimes/fastify.d.mts.map +1 -0
- package/dist/http/runtimes/fastify.mjs +13 -0
- package/dist/http/runtimes/fastify.mjs.map +1 -0
- package/dist/http/runtimes/h3.d.mts +29 -0
- package/dist/http/runtimes/h3.d.mts.map +1 -0
- package/dist/http/runtimes/h3.mjs +12 -0
- package/dist/http/runtimes/h3.mjs.map +1 -0
- package/dist/{index-kEmG8nWU.d.mts → index-BtWJ9SLP.d.mts} +53 -7
- package/dist/{index-kEmG8nWU.d.mts.map → index-BtWJ9SLP.d.mts.map} +1 -1
- package/dist/index.d.mts +12 -17
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{metadata-Cll3P0N0.mjs → metadata-Pvgc-K8a.mjs} +2 -2
- package/dist/{metadata-Cll3P0N0.mjs.map → metadata-Pvgc-K8a.mjs.map} +1 -1
- package/dist/query-B3PhfU6M.mjs +12 -0
- package/dist/query-B3PhfU6M.mjs.map +1 -0
- package/dist/request-scope-BaM8_e_8.mjs +12 -0
- package/dist/request-scope-BaM8_e_8.mjs.map +1 -0
- package/dist/router-builder-Bh3qSiDz.d.mts +39 -0
- package/dist/router-builder-Bh3qSiDz.d.mts.map +1 -0
- package/dist/{spa-IRFC2eMN.d.mts → spa-BdvZFXJz.d.mts} +3 -2
- package/dist/spa-BdvZFXJz.d.mts.map +1 -0
- package/dist/{upload-D6edAELH.d.mts → upload-Bc_rBRtE.d.mts} +37 -2
- package/dist/upload-Bc_rBRtE.d.mts.map +1 -0
- package/dist/{views-BCl-mETX.d.mts → views-DcTVDiOh.d.mts} +31 -7
- package/dist/views-DcTVDiOh.d.mts.map +1 -0
- package/package.json +29 -1
- package/dist/adapter-CkpcZwzZ.d.mts +0 -407
- package/dist/adapter-CkpcZwzZ.d.mts.map +0 -1
- package/dist/app-module-BTzb-Vd6.d.mts +0 -92
- package/dist/app-module-BTzb-Vd6.d.mts.map +0 -1
- package/dist/application-CAnpDQ8d.d.mts.map +0 -1
- package/dist/application-DnnqoDWx.mjs +0 -12
- package/dist/application-DnnqoDWx.mjs.map +0 -1
- package/dist/context-Dnt2Di7p.d.mts +0 -434
- package/dist/context-Dnt2Di7p.d.mts.map +0 -1
- package/dist/context-MD7Mc_o_.mjs +0 -12
- package/dist/context-MD7Mc_o_.mjs.map +0 -1
- package/dist/context-decorator-DDZ30BIW.d.mts.map +0 -1
- package/dist/errors-CRCTjEUK.d.mts.map +0 -1
- package/dist/execution-context-B4cfhivz.d.mts +0 -98
- package/dist/execution-context-B4cfhivz.d.mts.map +0 -1
- package/dist/index-frSEHiL_.d.mts +0 -796
- package/dist/index-frSEHiL_.d.mts.map +0 -1
- package/dist/plugin-BQCn6zyj.d.mts +0 -260
- package/dist/plugin-BQCn6zyj.d.mts.map +0 -1
- package/dist/query-D-FiLfmd.mjs +0 -12
- package/dist/query-D-FiLfmd.mjs.map +0 -1
- package/dist/router-builder-oQpcQMWl.d.mts +0 -31
- package/dist/router-builder-oQpcQMWl.d.mts.map +0 -1
- package/dist/spa-IRFC2eMN.d.mts.map +0 -1
- package/dist/upload-D6edAELH.d.mts.map +0 -1
- package/dist/views-BCl-mETX.d.mts.map +0 -1
|
@@ -1,796 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { s as InjectionToken, t as Container } from "./container-TWOUyR_0.mjs";
|
|
3
|
-
import { r as ExecutionContext } from "./execution-context-B4cfhivz.mjs";
|
|
4
|
-
import { t as AnyContributorRegistration } from "./context-decorator-DDZ30BIW.mjs";
|
|
5
|
-
import { r as AppAdapter } from "./adapter-CkpcZwzZ.mjs";
|
|
6
|
-
import { r as AppModuleEntry, t as AppModule } from "./app-module-BTzb-Vd6.mjs";
|
|
7
|
-
import { t as KickPlugin } from "./plugin-BQCn6zyj.mjs";
|
|
8
|
-
//#region src/core/define-plugin.d.ts
|
|
9
|
-
/**
|
|
10
|
-
* Options passed to {@link definePlugin}. Mirrors the spec in
|
|
11
|
-
* `architecture.md` §21.3.1 + §21.2.2 (Phase A "lite").
|
|
12
|
-
*/
|
|
13
|
-
interface DefinePluginOptions<TConfig> {
|
|
14
|
-
/** Stable identity used for logging, `dependsOn` lookups, and `.scoped()` namespacing. */
|
|
15
|
-
name: string;
|
|
16
|
-
/** Optional plugin version — surfaced to DevTools and `kick add` compatibility checks (Phase B). */
|
|
17
|
-
version?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Peer-version ranges this plugin needs from the framework or other
|
|
20
|
-
* plugins. Recorded as metadata; runtime enforcement lands in §21.4.4.
|
|
21
|
-
*/
|
|
22
|
-
requires?: {
|
|
23
|
-
kickjs?: string;
|
|
24
|
-
};
|
|
25
|
-
/** Default config merged under any caller overrides. */
|
|
26
|
-
defaults?: Partial<TConfig>;
|
|
27
|
-
/** Builds the underlying {@link KickPlugin} from the resolved config. */
|
|
28
|
-
build(config: TConfig, ctx: BuildContext): Omit<KickPlugin, 'name'>;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Hook context handed to a plugin/adapter `build` function. `name` is the
|
|
32
|
-
* resolved instance name (the bare definition name for the bare call,
|
|
33
|
-
* or `${defName}:${scope}` for `.scoped()`). `scoped` is the discriminator
|
|
34
|
-
* authors use to namespace DI tokens or resource keys.
|
|
35
|
-
*/
|
|
36
|
-
interface BuildContext {
|
|
37
|
-
name: string;
|
|
38
|
-
scoped: boolean;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Async-config form of a plugin or adapter — `inject` lists DI tokens to
|
|
42
|
-
* resolve from the container, then `useFactory` produces the config.
|
|
43
|
-
*
|
|
44
|
-
* Plugins resolve this lazily inside `onReady`, so any module/adapter/
|
|
45
|
-
* middleware/contributor a plugin contributes via `build` is **not
|
|
46
|
-
* available** when `.async()` is used. Use the bare/`.scoped()` form for
|
|
47
|
-
* plugins that need to register modules or middleware.
|
|
48
|
-
*/
|
|
49
|
-
interface PluginAsyncOptions<TConfig> {
|
|
50
|
-
inject?: ReadonlyArray<unknown>;
|
|
51
|
-
useFactory(...deps: any[]): TConfig | Promise<TConfig>;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Factory returned by {@link definePlugin}. Callable form is the singleton
|
|
55
|
-
* (`AuthPlugin(config)`); `.scoped()` and `.async()` are the multi-instance
|
|
56
|
-
* and deferred-config forms.
|
|
57
|
-
*/
|
|
58
|
-
interface PluginFactory<TConfig> {
|
|
59
|
-
(config?: Partial<TConfig>): KickPlugin;
|
|
60
|
-
scoped(scopeName: string, config?: Partial<TConfig>): KickPlugin;
|
|
61
|
-
async(opts: PluginAsyncOptions<TConfig>): KickPlugin;
|
|
62
|
-
/** Read-only access to the original definition — useful for DevTools introspection. */
|
|
63
|
-
readonly definition: Readonly<DefinePluginOptions<TConfig>>;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Build a {@link KickPlugin} factory from a typed definition. See
|
|
67
|
-
* `architecture.md` §21.2.2 for the design rationale.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* const FlagsPlugin = definePlugin<FlagsConfig>({
|
|
72
|
-
* name: 'FlagsPlugin',
|
|
73
|
-
* defaults: { defaultTtl: 60_000 },
|
|
74
|
-
* build(config) {
|
|
75
|
-
* return {
|
|
76
|
-
* register(container) {
|
|
77
|
-
* container.registerInstance(FLAGS, makeProvider(config))
|
|
78
|
-
* },
|
|
79
|
-
* }
|
|
80
|
-
* },
|
|
81
|
-
* })
|
|
82
|
-
*
|
|
83
|
-
* bootstrap({ plugins: [FlagsPlugin({ provider: launchDarkly })] })
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
declare function definePlugin<TConfig = Record<string, unknown>>(options: DefinePluginOptions<TConfig>): PluginFactory<TConfig>;
|
|
87
|
-
//#endregion
|
|
88
|
-
//#region src/core/define-module.d.ts
|
|
89
|
-
/**
|
|
90
|
-
* Options passed to {@link defineModule}. Mirrors {@link DefineAdapterOptions}
|
|
91
|
-
* and {@link DefinePluginOptions} so adopters learn one mental model
|
|
92
|
-
* across all three primitives.
|
|
93
|
-
*
|
|
94
|
-
* The optional `TExtra` generic lets a module ship public methods
|
|
95
|
-
* beyond the standard {@link AppModule} contract — they're preserved
|
|
96
|
-
* on the returned module instance so external callers (tests, sibling
|
|
97
|
-
* modules) can invoke them directly.
|
|
98
|
-
*/
|
|
99
|
-
interface DefineModuleOptions<TConfig, TExtra = unknown> {
|
|
100
|
-
/**
|
|
101
|
-
* Stable identity surfaced in diagnostics, route logs, and
|
|
102
|
-
* `.scoped()` namespacing. Required because boot-time error
|
|
103
|
-
* messages reference modules by name — anonymous modules make
|
|
104
|
-
* cycles + missing-dep errors hard to localize.
|
|
105
|
-
*/
|
|
106
|
-
name: string;
|
|
107
|
-
/** Optional version string surfaced in diagnostics. */
|
|
108
|
-
version?: string;
|
|
109
|
-
/**
|
|
110
|
-
* Optional kickjs version constraint. Enforced by the framework
|
|
111
|
-
* when implemented; today it lives on the definition for
|
|
112
|
-
* documentation and forward compatibility.
|
|
113
|
-
*/
|
|
114
|
-
requires?: {
|
|
115
|
-
kickjs?: string;
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* Default config merged with overrides at instantiation time
|
|
119
|
-
* (`MyModule({ field: x })`). Call-site overrides win.
|
|
120
|
-
*/
|
|
121
|
-
defaults?: Partial<TConfig>;
|
|
122
|
-
/**
|
|
123
|
-
* Build the AppModule shape from the resolved config and context.
|
|
124
|
-
* `ctx.name` is the resolved instance name (the bare definition
|
|
125
|
-
* name for the default call, or `${name}:${scope}` for
|
|
126
|
-
* `.scoped()`); `ctx.scoped` discriminates so the build function
|
|
127
|
-
* can branch on namespacing if needed.
|
|
128
|
-
*
|
|
129
|
-
* Return any extension methods alongside the standard
|
|
130
|
-
* {@link AppModule} surface — they're typed via `TExtra` and stay
|
|
131
|
-
* accessible on the resulting instance.
|
|
132
|
-
*/
|
|
133
|
-
build(config: TConfig, ctx: BuildContext): AppModule & TExtra;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Factory returned by {@link defineModule}. Mirrors {@link AdapterFactory}
|
|
137
|
-
* — call (`MyModule({...})`), scope (`MyModule.scoped('public', {...})`),
|
|
138
|
-
* inspect (`MyModule.definition`).
|
|
139
|
-
*
|
|
140
|
-
* `.async()` is intentionally **not** part of the module factory
|
|
141
|
-
* surface. Module config has no async-resolution window: `register()`
|
|
142
|
-
* and `routes()` both run synchronously during bootstrap, before any
|
|
143
|
-
* adapter `beforeStart` hook fires. Adopters that need async-resolved
|
|
144
|
-
* config push it into an adapter (which has `beforeStart`), then
|
|
145
|
-
* inject the resolved value into the module via DI tokens.
|
|
146
|
-
*/
|
|
147
|
-
interface ModuleFactory<TConfig, TExtra = unknown> {
|
|
148
|
-
(config?: Partial<TConfig>): AppModule & TExtra;
|
|
149
|
-
scoped(scopeName: string, config?: Partial<TConfig>): AppModule & TExtra;
|
|
150
|
-
readonly definition: Readonly<DefineModuleOptions<TConfig, TExtra>>;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Build an {@link AppModule} factory from a typed definition. Pairs
|
|
154
|
-
* with {@link defineAdapter}, {@link definePlugin}, and
|
|
155
|
-
* {@link defineContextDecorator} as the fourth `define*` primitive
|
|
156
|
-
* — adopters write modules the same way they write adapters and
|
|
157
|
-
* plugins.
|
|
158
|
-
*
|
|
159
|
-
* The returned factory produces real {@link AppModule} instances
|
|
160
|
-
* that drop into `bootstrap({ modules })` directly. The legacy
|
|
161
|
-
* class form (`class TasksModule implements AppModule { ... }`) keeps
|
|
162
|
-
* working — `bootstrap` accepts either shape.
|
|
163
|
-
*
|
|
164
|
-
* @example
|
|
165
|
-
* ```ts
|
|
166
|
-
* interface TasksConfig {
|
|
167
|
-
* scope: 'public' | 'admin'
|
|
168
|
-
* }
|
|
169
|
-
*
|
|
170
|
-
* const TasksModule = defineModule<TasksConfig>({
|
|
171
|
-
* name: 'TasksModule',
|
|
172
|
-
* defaults: { scope: 'public' },
|
|
173
|
-
* build: (config, { name }) => ({
|
|
174
|
-
* register(container) {
|
|
175
|
-
* container.registerInstance(`tasks:scope:${name}`, config.scope)
|
|
176
|
-
* },
|
|
177
|
-
* routes() {
|
|
178
|
-
* return { path: `/${config.scope}/tasks`, router: buildTasksRouter() }
|
|
179
|
-
* },
|
|
180
|
-
* contributors() {
|
|
181
|
-
* return [LoadTenant.registration]
|
|
182
|
-
* },
|
|
183
|
-
* }),
|
|
184
|
-
* })
|
|
185
|
-
*
|
|
186
|
-
* bootstrap({
|
|
187
|
-
* modules: [
|
|
188
|
-
* TasksModule(), // public scope (defaults)
|
|
189
|
-
* TasksModule.scoped('admin', { scope: 'admin' }),
|
|
190
|
-
* ],
|
|
191
|
-
* })
|
|
192
|
-
* ```
|
|
193
|
-
*/
|
|
194
|
-
declare function defineModule<TConfig = Record<string, unknown>, TExtra = unknown>(options: DefineModuleOptions<TConfig, TExtra>): ModuleFactory<TConfig, TExtra>;
|
|
195
|
-
//#endregion
|
|
196
|
-
//#region src/core/define-modules.d.ts
|
|
197
|
-
/**
|
|
198
|
-
* Chainable registry returned by {@link defineModules}. Extends
|
|
199
|
-
* `Array<AppModuleEntry>` so it drops into `bootstrap({ modules })`
|
|
200
|
-
* unchanged — the framework loader already iterates the array, so a
|
|
201
|
-
* `ModuleList` IS a valid `modules` value with no special handling.
|
|
202
|
-
*
|
|
203
|
-
* The added affordance is `.mount(module)` returning `this` so
|
|
204
|
-
* adopters can build the list fluently:
|
|
205
|
-
*
|
|
206
|
-
* ```ts
|
|
207
|
-
* const modules = defineModules()
|
|
208
|
-
* .mount(HelloModule())
|
|
209
|
-
* .mount(AdminModule())
|
|
210
|
-
*
|
|
211
|
-
* bootstrap({ modules })
|
|
212
|
-
* ```
|
|
213
|
-
*
|
|
214
|
-
* **Why not just use a plain array?** Two reasons. First, the
|
|
215
|
-
* fluent shape reads more naturally for module-list construction —
|
|
216
|
-
* adopters used to `definePlugin().scoped(...)` / `defineAdapter(...)`
|
|
217
|
-
* see the same call-then-call pattern. Second, the registry is the
|
|
218
|
-
* stable extension point: a future `.use(module)` for non-HTTP
|
|
219
|
-
* modules (queues, cron, workers) lands as a method on `ModuleList`
|
|
220
|
-
* without breaking the `Array<AppModuleEntry>` superclass contract.
|
|
221
|
-
*/
|
|
222
|
-
declare class ModuleList extends Array<AppModuleEntry> {
|
|
223
|
-
/**
|
|
224
|
-
* Append a module to the list. Returns `this` for chaining.
|
|
225
|
-
*
|
|
226
|
-
* Accepts both class form (`SomeModule extends AppModule`) and
|
|
227
|
-
* `defineModule` factory output — same as the underlying
|
|
228
|
-
* `bootstrap({ modules })` array. The framework loader
|
|
229
|
-
* discriminates `typeof entry === 'function'` at boot.
|
|
230
|
-
*/
|
|
231
|
-
mount(module: AppModuleEntry): this;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Build a {@link ModuleList} for the application. Optional vararg
|
|
235
|
-
* lets adopters seed the list inline; subsequent `.mount()` calls
|
|
236
|
-
* append.
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* ```ts
|
|
240
|
-
* import { bootstrap, defineModules } from '@forinda/kickjs'
|
|
241
|
-
* import { HelloModule } from './modules/hello/hello.module'
|
|
242
|
-
* import { AdminModule } from './modules/admin/admin.module'
|
|
243
|
-
*
|
|
244
|
-
* // Fluent — most common
|
|
245
|
-
* const modules = defineModules()
|
|
246
|
-
* .mount(HelloModule())
|
|
247
|
-
* .mount(AdminModule())
|
|
248
|
-
*
|
|
249
|
-
* // Or seeded inline + chained
|
|
250
|
-
* const modules2 = defineModules(HelloModule()).mount(AdminModule())
|
|
251
|
-
*
|
|
252
|
-
* await bootstrap({ modules })
|
|
253
|
-
* ```
|
|
254
|
-
*
|
|
255
|
-
* The returned value is an `AppModuleEntry[]` subclass — `bootstrap`
|
|
256
|
-
* accepts it directly without any special-casing. For conditional /
|
|
257
|
-
* dynamic registration at bootstrap time (env flags, runtime config,
|
|
258
|
-
* tenant lists), use the `setup(registry)` callback on `bootstrap`
|
|
259
|
-
* instead — both surfaces compose.
|
|
260
|
-
*/
|
|
261
|
-
declare function defineModules(...initial: AppModuleEntry[]): ModuleList;
|
|
262
|
-
//#endregion
|
|
263
|
-
//#region src/core/kick-error.d.ts
|
|
264
|
-
/**
|
|
265
|
-
* Structured framework error with code, cause, and actionable fix hint.
|
|
266
|
-
*
|
|
267
|
-
* The goal is "the developer who hits this knows what to do next." A
|
|
268
|
-
* cryptic `Error('No binding found for: UserService')` becomes a
|
|
269
|
-
* multi-line explanation pointing at the likely cause, the exact code
|
|
270
|
-
* change to apply, and a docs link.
|
|
271
|
-
*
|
|
272
|
-
* `.message` carries the full multi-line plain-text body so Node's
|
|
273
|
-
* default `Error.toString()` and unhandled-exception printing still
|
|
274
|
-
* surface the helpful version. Call {@link formatKickError} to render a
|
|
275
|
-
* colorized version for terminals.
|
|
276
|
-
*
|
|
277
|
-
* Per-error factories live in `kick-errors.ts` — those are the public
|
|
278
|
-
* entry points framework code uses. `KickError` is exported so adopters
|
|
279
|
-
* can build their own structured errors using the same shape.
|
|
280
|
-
*/
|
|
281
|
-
interface KickErrorInit {
|
|
282
|
-
/** Short stable identifier (e.g. `KICK001`, `NO_PROVIDER`). */
|
|
283
|
-
code: string;
|
|
284
|
-
/** One-line headline. */
|
|
285
|
-
summary: string;
|
|
286
|
-
/** Multi-line explanation of why this happened. */
|
|
287
|
-
cause?: string;
|
|
288
|
-
/** Multi-line actionable fix — show exact code if possible. */
|
|
289
|
-
fix?: string;
|
|
290
|
-
/** Absolute URL to the docs page that covers this error. */
|
|
291
|
-
docsUrl?: string;
|
|
292
|
-
/** Arbitrary structured fields for log consumers / debug tooling. */
|
|
293
|
-
context?: Record<string, unknown>;
|
|
294
|
-
}
|
|
295
|
-
declare class KickError extends Error {
|
|
296
|
-
readonly code: string;
|
|
297
|
-
readonly summary: string;
|
|
298
|
-
readonly cause?: string;
|
|
299
|
-
readonly fix?: string;
|
|
300
|
-
readonly docsUrl?: string;
|
|
301
|
-
readonly context?: Record<string, unknown>;
|
|
302
|
-
constructor(init: KickErrorInit);
|
|
303
|
-
}
|
|
304
|
-
interface FormatKickErrorOptions {
|
|
305
|
-
/**
|
|
306
|
-
* Render ANSI colour codes. Defaults to TTY detection (`NO_COLOR` /
|
|
307
|
-
* `FORCE_COLOR` env vars honoured). Pass `false` for log files,
|
|
308
|
-
* structured loggers, or HTTP response bodies.
|
|
309
|
-
*/
|
|
310
|
-
color?: boolean;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Render a {@link KickErrorInit} (or {@link KickError} instance) into a
|
|
314
|
-
* multi-line human-readable string. Identical layout regardless of
|
|
315
|
-
* colour — the colour flag only toggles ANSI codes.
|
|
316
|
-
*/
|
|
317
|
-
declare function formatKickError(err: KickErrorInit | KickError, options?: FormatKickErrorOptions): string;
|
|
318
|
-
//#endregion
|
|
319
|
-
//#region src/core/metadata.d.ts
|
|
320
|
-
/**
|
|
321
|
-
* Typed utilities for reflect-metadata operations.
|
|
322
|
-
*
|
|
323
|
-
* Replaces scattered Reflect.defineMetadata/getMetadata calls with a single
|
|
324
|
-
* source of truth. If we later move to Stage 3 decorators or a WeakMap-based
|
|
325
|
-
* store, only this file changes — all 24+ consumer files stay untouched.
|
|
326
|
-
*
|
|
327
|
-
* Keys may be symbols, strings, or `InjectionToken<T>` objects produced by
|
|
328
|
-
* `createToken()`. Using `createToken` is the preferred pattern because the
|
|
329
|
-
* token's phantom type flows through the helpers, enabling type-safe reads.
|
|
330
|
-
*/
|
|
331
|
-
type MetaKey = symbol | string | InjectionToken<unknown>;
|
|
332
|
-
/** Set metadata on a class (or prototype for property decorators) */
|
|
333
|
-
declare function setClassMeta<T>(key: MetaKey, value: T, target: object): void;
|
|
334
|
-
/** Set metadata on a specific method */
|
|
335
|
-
declare function setMethodMeta<T>(key: MetaKey, value: T, target: object, method: string): void;
|
|
336
|
-
/** Get metadata from a class, returning `fallback` if not set */
|
|
337
|
-
declare function getClassMeta<T>(key: MetaKey, target: object, fallback: T): T;
|
|
338
|
-
/** Get metadata from a specific method, returning `fallback` if not set */
|
|
339
|
-
declare function getMethodMeta<T>(key: MetaKey, target: object, method: string, fallback: T): T;
|
|
340
|
-
/** Check if metadata exists on a class */
|
|
341
|
-
declare function hasClassMeta(key: MetaKey, target: object): boolean;
|
|
342
|
-
/** Get metadata from a class with no default (returns undefined if absent) */
|
|
343
|
-
declare function getClassMetaOrUndefined<T>(key: MetaKey, target: object): T | undefined;
|
|
344
|
-
/** Get metadata from a method with no default (returns undefined if absent) */
|
|
345
|
-
declare function getMethodMetaOrUndefined<T>(key: MetaKey, target: object, method: string): T | undefined;
|
|
346
|
-
/** Append items to an array stored in class metadata */
|
|
347
|
-
declare function pushClassMeta<T>(key: MetaKey, target: object, ...items: T[]): void;
|
|
348
|
-
/** Append items to an array stored in method metadata */
|
|
349
|
-
declare function pushMethodMeta<T>(key: MetaKey, target: object, method: string, ...items: T[]): void;
|
|
350
|
-
/** Set a key/value in a Map stored in class metadata */
|
|
351
|
-
declare function setInMetaMap<K, V>(key: MetaKey, target: object, mapKey: K, mapValue: V): void;
|
|
352
|
-
/** Get a Map from class metadata (returns empty Map if absent) */
|
|
353
|
-
declare function getMetaMap<K, V>(key: MetaKey, target: object): Map<K, V>;
|
|
354
|
-
/** Set a key/value in a Record stored in class metadata */
|
|
355
|
-
declare function setInMetaRecord<V>(key: MetaKey, target: object, recKey: string | number, recValue: V): void;
|
|
356
|
-
/** Get a Record from class metadata (returns empty object if absent) */
|
|
357
|
-
declare function getMetaRecord<V>(key: MetaKey, target: object): Record<string | number, V>;
|
|
358
|
-
//#endregion
|
|
359
|
-
//#region src/core/circuit-breaker.d.ts
|
|
360
|
-
/**
|
|
361
|
-
* Circuit Breaker pattern for external service calls.
|
|
362
|
-
*
|
|
363
|
-
* Protects your application from cascading failures when downstream
|
|
364
|
-
* services are unhealthy by short-circuiting requests after a
|
|
365
|
-
* configurable failure threshold.
|
|
366
|
-
*
|
|
367
|
-
* @example
|
|
368
|
-
* ```ts
|
|
369
|
-
* const breaker = new CircuitBreaker('payment-api', {
|
|
370
|
-
* failureThreshold: 5,
|
|
371
|
-
* resetTimeout: 30_000,
|
|
372
|
-
* })
|
|
373
|
-
*
|
|
374
|
-
* const result = await breaker.execute(() => fetch('https://payment.example.com/charge'))
|
|
375
|
-
* ```
|
|
376
|
-
*/
|
|
377
|
-
type CircuitBreakerState = 'closed' | 'open' | 'half_open';
|
|
378
|
-
interface CircuitBreakerOptions {
|
|
379
|
-
/** Number of consecutive failures before the circuit opens. */
|
|
380
|
-
failureThreshold: number;
|
|
381
|
-
/** Milliseconds to wait before transitioning from OPEN to HALF_OPEN. */
|
|
382
|
-
resetTimeout: number;
|
|
383
|
-
/** Max requests allowed in HALF_OPEN state before deciding (default 1). */
|
|
384
|
-
halfOpenMax?: number;
|
|
385
|
-
}
|
|
386
|
-
interface CircuitBreakerStats {
|
|
387
|
-
failures: number;
|
|
388
|
-
successes: number;
|
|
389
|
-
state: CircuitBreakerState;
|
|
390
|
-
lastFailure?: Date;
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Error thrown when the circuit is open and calls are being rejected.
|
|
394
|
-
*/
|
|
395
|
-
declare class CircuitOpenError extends Error {
|
|
396
|
-
readonly breakerName: string;
|
|
397
|
-
constructor(breakerName: string);
|
|
398
|
-
}
|
|
399
|
-
declare class CircuitBreaker {
|
|
400
|
-
readonly name: string;
|
|
401
|
-
private state;
|
|
402
|
-
private failures;
|
|
403
|
-
private successes;
|
|
404
|
-
private halfOpenAttempts;
|
|
405
|
-
private lastFailure?;
|
|
406
|
-
private openedAt?;
|
|
407
|
-
private readonly failureThreshold;
|
|
408
|
-
private readonly resetTimeout;
|
|
409
|
-
private readonly halfOpenMax;
|
|
410
|
-
constructor(name: string, options: CircuitBreakerOptions);
|
|
411
|
-
/**
|
|
412
|
-
* Execute an async function through the circuit breaker.
|
|
413
|
-
* Throws `CircuitOpenError` if the circuit is open.
|
|
414
|
-
*/
|
|
415
|
-
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
416
|
-
/** Returns the current circuit state. */
|
|
417
|
-
getState(): CircuitBreakerState;
|
|
418
|
-
/** Returns current statistics. */
|
|
419
|
-
getStats(): CircuitBreakerStats;
|
|
420
|
-
/** Manually reset the circuit breaker to CLOSED state. */
|
|
421
|
-
reset(): void;
|
|
422
|
-
private onSuccess;
|
|
423
|
-
private onFailure;
|
|
424
|
-
private maybeTransitionToHalfOpen;
|
|
425
|
-
}
|
|
426
|
-
//#endregion
|
|
427
|
-
//#region src/core/context-errors.d.ts
|
|
428
|
-
/**
|
|
429
|
-
* Errors thrown by the Context Contributor pipeline.
|
|
430
|
-
*
|
|
431
|
-
* All three are startup-time errors raised during pipeline build (topo-sort
|
|
432
|
-
* + validation), not per-request — a misconfigured app fails to boot rather
|
|
433
|
-
* than fails a request. Per the locked design in `architecture.md` §20.4,
|
|
434
|
-
* the pipeline is validated once when each route is mounted and the
|
|
435
|
-
* resolved order is cached on the route.
|
|
436
|
-
*/
|
|
437
|
-
/**
|
|
438
|
-
* A contributor declared `dependsOn: ['<key>']` but no other contributor
|
|
439
|
-
* (at any precedence level) produces that key for the same route.
|
|
440
|
-
*
|
|
441
|
-
* @example
|
|
442
|
-
* ```text
|
|
443
|
-
* MissingContributorError: Missing context contributor 'tenant' required by 'project' on route GET /projects/:id
|
|
444
|
-
* declared at src/contributors/load-project.ts:42:18
|
|
445
|
-
* ```
|
|
446
|
-
*/
|
|
447
|
-
declare class MissingContributorError extends Error {
|
|
448
|
-
readonly key: string;
|
|
449
|
-
readonly dependent: string;
|
|
450
|
-
readonly route?: string;
|
|
451
|
-
readonly dependentDefinedAt?: string;
|
|
452
|
-
constructor(key: string, dependent: string, route?: string, dependentDefinedAt?: string);
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Topo-sort detected a cycle in `dependsOn` declarations. The `cycle` field
|
|
456
|
-
* lists the keys in the order they form the loop, with the first key
|
|
457
|
-
* repeated at the end so the path reads naturally.
|
|
458
|
-
*
|
|
459
|
-
* @example
|
|
460
|
-
* ```text
|
|
461
|
-
* ContributorCycleError: Cycle in context contributors on route GET /projects/:id: tenant → project → tenant
|
|
462
|
-
* ```
|
|
463
|
-
*/
|
|
464
|
-
declare class ContributorCycleError extends Error {
|
|
465
|
-
readonly cycle: readonly string[];
|
|
466
|
-
readonly route?: string;
|
|
467
|
-
constructor(cycle: readonly string[], route?: string);
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Two contributors at the same precedence level both produce the same key
|
|
471
|
-
* for the same route. Precedence resolution (method > class > module >
|
|
472
|
-
* adapter > global, per architecture.md §20.4) silently drops
|
|
473
|
-
* lower-precedence duplicates; this error fires only when ties occur
|
|
474
|
-
* within a single level — e.g., two method-level decorators declaring
|
|
475
|
-
* `key: 'tenant'`.
|
|
476
|
-
*
|
|
477
|
-
* `sources` is best-effort identifying labels for each conflicting
|
|
478
|
-
* registration (typically the decorator's call site or registering
|
|
479
|
-
* module/adapter name).
|
|
480
|
-
*
|
|
481
|
-
* @example
|
|
482
|
-
* ```text
|
|
483
|
-
* DuplicateContributorError: Duplicate context contributor for key 'tenant' at the same precedence level. Sources: LoadTenantFromHeader, LoadTenantFromSubdomain
|
|
484
|
-
* ```
|
|
485
|
-
*/
|
|
486
|
-
declare class DuplicateContributorError extends Error {
|
|
487
|
-
readonly key: string;
|
|
488
|
-
readonly sources: readonly string[];
|
|
489
|
-
constructor(key: string, sources: readonly string[]);
|
|
490
|
-
}
|
|
491
|
-
//#endregion
|
|
492
|
-
//#region src/core/contributor-pipeline.d.ts
|
|
493
|
-
/**
|
|
494
|
-
* Where a contributor was registered, ordered by precedence
|
|
495
|
-
* (lower index wins). Mirrors `architecture.md` §20.4.
|
|
496
|
-
*
|
|
497
|
-
* Levels (highest → lowest precedence):
|
|
498
|
-
* - `'method'` — `@LoadX` on a controller method.
|
|
499
|
-
* - `'class'` — `@LoadX` on a controller class.
|
|
500
|
-
* - `'module'` — returned by `AppModule.contributors?()`. Per-module scope.
|
|
501
|
-
* - `'adapter'` — returned by `AppAdapter.contributors?()`. Cross-cutting, applies
|
|
502
|
-
* to every module's routes.
|
|
503
|
-
* - `'global'` — `ApplicationOptions.contributors`. App-wide default.
|
|
504
|
-
*/
|
|
505
|
-
type ContributorSource = 'method' | 'class' | 'module' | 'adapter' | 'global';
|
|
506
|
-
/**
|
|
507
|
-
* Input row to {@link buildPipeline}. Pairs a registration with its origin
|
|
508
|
-
* so dedup can apply the precedence rule and diagnostic errors can name
|
|
509
|
-
* the offending site.
|
|
510
|
-
*
|
|
511
|
-
* `registration` is the type-erased {@link AnyContributorRegistration}
|
|
512
|
-
* — the runner doesn't care about each registration's narrow `D` /
|
|
513
|
-
* `Ctx` shape, and adopters frequently mix HTTP / transport-agnostic
|
|
514
|
-
* contributors in the same `externalSources` / `contributors()`
|
|
515
|
-
* array. The narrow generics from `defineContextDecorator` survive
|
|
516
|
-
* at the *definition* site (where `resolve` is typed); they're erased
|
|
517
|
-
* here so collections compose without `as any` casts.
|
|
518
|
-
*/
|
|
519
|
-
interface SourcedRegistration {
|
|
520
|
-
registration: AnyContributorRegistration;
|
|
521
|
-
source: ContributorSource;
|
|
522
|
-
/** Human label surfaced in DuplicateContributorError messages. */
|
|
523
|
-
label?: string;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Resolved, validated, topo-sorted pipeline ready for execution.
|
|
527
|
-
*
|
|
528
|
-
* `contributors` is in execution order — every entry's `dependsOn`
|
|
529
|
-
* keys appear earlier. `keys` is the set of all keys this pipeline
|
|
530
|
-
* produces; the runner uses it for fast existence checks and the
|
|
531
|
-
* builder uses it for missing-dep validation.
|
|
532
|
-
*/
|
|
533
|
-
interface ContributorPipeline {
|
|
534
|
-
readonly contributors: readonly AnyContributorRegistration[];
|
|
535
|
-
readonly keys: ReadonlySet<string>;
|
|
536
|
-
}
|
|
537
|
-
interface BuildPipelineOptions {
|
|
538
|
-
/** Optional route identifier surfaced in diagnostic errors (e.g., 'GET /projects/:id'). */
|
|
539
|
-
route?: string;
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Build, validate, and topo-sort a contributor pipeline.
|
|
543
|
-
*
|
|
544
|
-
* Pipeline:
|
|
545
|
-
*
|
|
546
|
-
* 1. Group sources by precedence (method > class > module > adapter > global).
|
|
547
|
-
* 2. Within each precedence level, two contributors with the same `key`
|
|
548
|
-
* raise {@link DuplicateContributorError}.
|
|
549
|
-
* 3. Across levels, the highest-precedence contributor wins each key
|
|
550
|
-
* (lower-precedence duplicates are silently dropped — that is the
|
|
551
|
-
* documented override mechanism, not an error).
|
|
552
|
-
* 4. Every key referenced by `dependsOn` must be produced by the
|
|
553
|
-
* surviving set, otherwise {@link MissingContributorError}.
|
|
554
|
-
* 5. Kahn's algorithm topo-sorts the survivors. Any nodes left after
|
|
555
|
-
* the queue drains form a cycle → {@link ContributorCycleError}
|
|
556
|
-
* with a reconstructed path.
|
|
557
|
-
*
|
|
558
|
-
* Pure function — no DI, no I/O. Safe to call once at startup per
|
|
559
|
-
* route and cache the result.
|
|
560
|
-
*/
|
|
561
|
-
declare function buildPipeline(sources: readonly SourcedRegistration[], options?: BuildPipelineOptions): ContributorPipeline;
|
|
562
|
-
//#endregion
|
|
563
|
-
//#region src/core/contributor-runner.d.ts
|
|
564
|
-
interface RunContributorsOptions {
|
|
565
|
-
/** Pre-built, validated, topo-sorted pipeline. */
|
|
566
|
-
pipeline: ContributorPipeline;
|
|
567
|
-
/** The execution context contributors read from and write into. */
|
|
568
|
-
ctx: ExecutionContext;
|
|
569
|
-
/** DI container used to resolve declared `deps`. */
|
|
570
|
-
container: Container;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Execute a built {@link ContributorPipeline} against an {@link ExecutionContext}.
|
|
574
|
-
*
|
|
575
|
-
* Sequential — one contributor at a time, in the topo order chosen at
|
|
576
|
-
* pipeline-build time. Per `architecture.md` §20.10, V1 does not run
|
|
577
|
-
* contributors in parallel even within the same topo level; that is a
|
|
578
|
-
* V2 follow-up gated on profiling.
|
|
579
|
-
*
|
|
580
|
-
* ## Error matrix (architecture.md §20.9)
|
|
581
|
-
*
|
|
582
|
-
* | resolve outcome | optional | onError defined | runner behaviour |
|
|
583
|
-
* |-----------------|----------|-----------------|--------------------------------------------------|
|
|
584
|
-
* | throws | true | — | skip; `ctx.get(key)` remains undefined |
|
|
585
|
-
* | throws | false | yes | call hook; returned value (if any) stored |
|
|
586
|
-
* | throws | false | no | propagate the original error |
|
|
587
|
-
* | hook throws | — | yes | propagate the new error |
|
|
588
|
-
* | hook returns | — | yes | undefined/void → skip; value → `ctx.set(key, v)` |
|
|
589
|
-
* | resolves | — | — | `ctx.set(key, value)` |
|
|
590
|
-
*
|
|
591
|
-
* Container.resolve() throwing while building `deps` is treated as a
|
|
592
|
-
* resolve-side throw and flows through the same matrix — adopters who
|
|
593
|
-
* need different behaviour for missing-DI vs. data-lookup failures can
|
|
594
|
-
* wrap the container access inside their own `resolve()`.
|
|
595
|
-
*/
|
|
596
|
-
declare function runContributors(options: RunContributorsOptions): Promise<void>;
|
|
597
|
-
//#endregion
|
|
598
|
-
//#region src/core/mount-sort.d.ts
|
|
599
|
-
/**
|
|
600
|
-
* Topological sort for plugins and adapters with `dependsOn` declarations.
|
|
601
|
-
*
|
|
602
|
-
* Mirrors the algorithm used by the Context Contributor pipeline
|
|
603
|
-
* (`contributor-pipeline.ts:topoSort`) but operates on a name-keyed
|
|
604
|
-
* `MountSortItem` shape rather than a `ContributorRegistration`. Kept
|
|
605
|
-
* standalone instead of factored generic so that:
|
|
606
|
-
*
|
|
607
|
-
* 1. The contributor pipeline doesn't need refactoring (risk reduction).
|
|
608
|
-
* 2. The error classes can carry plugin/adapter-specific diagnostic
|
|
609
|
-
* fields (`kind`, `dependent`) without bending the contributor types.
|
|
610
|
-
*/
|
|
611
|
-
/**
|
|
612
|
-
* A plugin or adapter that participates in dependency-ordered mounting.
|
|
613
|
-
* Both `KickPlugin` and `AppAdapter` satisfy this shape via their `name`
|
|
614
|
-
* and `dependsOn` fields.
|
|
615
|
-
*/
|
|
616
|
-
interface MountSortItem {
|
|
617
|
-
/** Unique mount name within the plugin/adapter set being sorted. */
|
|
618
|
-
name: string;
|
|
619
|
-
/**
|
|
620
|
-
* Other plugin/adapter names that must mount before this one. Cycles
|
|
621
|
-
* and missing names fail at boot — same fail-fast contract as the
|
|
622
|
-
* Context Contributor pipeline (architecture.md §20.4).
|
|
623
|
-
*/
|
|
624
|
-
dependsOn?: readonly string[];
|
|
625
|
-
}
|
|
626
|
-
/** What kind of mount set the sort is operating on — surfaces in error messages. */
|
|
627
|
-
type MountKind = 'plugin' | 'adapter';
|
|
628
|
-
/**
|
|
629
|
-
* Two items in the same mount set declared the same `name`. Plugin/adapter
|
|
630
|
-
* names must be unique so `dependsOn` references resolve unambiguously.
|
|
631
|
-
*/
|
|
632
|
-
declare class DuplicateMountNameError extends Error {
|
|
633
|
-
readonly kind: MountKind;
|
|
634
|
-
readonly mountName: string;
|
|
635
|
-
constructor(kind: MountKind, mountName: string);
|
|
636
|
-
}
|
|
637
|
-
/**
|
|
638
|
-
* A `dependsOn` entry references a plugin/adapter that isn't in the
|
|
639
|
-
* current set. The dependency might not be installed, might be misspelled,
|
|
640
|
-
* or might live in a different mount set (plugin referencing an adapter,
|
|
641
|
-
* or vice versa — they sort independently).
|
|
642
|
-
*/
|
|
643
|
-
declare class MissingMountDepError extends Error {
|
|
644
|
-
readonly kind: MountKind;
|
|
645
|
-
readonly missing: string;
|
|
646
|
-
readonly dependent: string;
|
|
647
|
-
constructor(kind: MountKind, missing: string, dependent: string);
|
|
648
|
-
}
|
|
649
|
-
/**
|
|
650
|
-
* The `dependsOn` declarations form a cycle. Boot fails so the cycle
|
|
651
|
-
* can't poison live traffic. The `cycle` field reports one path through
|
|
652
|
-
* the offending nodes for diagnostics — formatted `A → B → C → A`.
|
|
653
|
-
*/
|
|
654
|
-
declare class MountCycleError extends Error {
|
|
655
|
-
readonly kind: MountKind;
|
|
656
|
-
readonly cycle: readonly string[];
|
|
657
|
-
constructor(kind: MountKind, cycle: readonly string[]);
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Topologically sort `items` so every item with `dependsOn: ['X']` mounts
|
|
661
|
-
* after `X`. Items without `dependsOn` keep their input order via Kahn's
|
|
662
|
-
* algorithm with a FIFO queue seeded in input order — preserves the
|
|
663
|
-
* historical "plugins/adapters mount in declaration order" behaviour for
|
|
664
|
-
* any set that doesn't use `dependsOn`.
|
|
665
|
-
*
|
|
666
|
-
* @param items - mountable items, e.g. plugins or adapters
|
|
667
|
-
* @param kind - 'plugin' | 'adapter', used in error messages
|
|
668
|
-
* @returns a new array in valid mount order
|
|
669
|
-
* @throws {DuplicateMountNameError} two items share a name
|
|
670
|
-
* @throws {MissingMountDepError} a `dependsOn` references an unknown name
|
|
671
|
-
* @throws {MountCycleError} the dep graph contains a cycle
|
|
672
|
-
*/
|
|
673
|
-
declare function mountSort<T extends MountSortItem>(items: readonly T[], kind: MountKind): T[];
|
|
674
|
-
//#endregion
|
|
675
|
-
//#region src/core/define-adapter.d.ts
|
|
676
|
-
/**
|
|
677
|
-
* Options passed to {@link defineAdapter}. Mirrors {@link DefinePluginOptions}
|
|
678
|
-
* exactly — see `architecture.md` §21.3.4 for the definePlugin/defineAdapter
|
|
679
|
-
* symmetry rationale.
|
|
680
|
-
*
|
|
681
|
-
* The optional `TExtra` generic lets an adapter ship public methods
|
|
682
|
-
* beyond the standard {@link AppAdapter} contract — they're preserved
|
|
683
|
-
* on the returned adapter instance so external callers (tests, peer
|
|
684
|
-
* adapters) can invoke them directly. See `OtelAdapter.applyRedaction`
|
|
685
|
-
* for the canonical use case.
|
|
686
|
-
*/
|
|
687
|
-
interface DefineAdapterOptions<TConfig, TExtra = unknown> {
|
|
688
|
-
/**
|
|
689
|
-
* Stable identity used for logging, `dependsOn` lookups, and `.scoped()`
|
|
690
|
-
* namespacing. Required for adapters that participate in `dependsOn`
|
|
691
|
-
* sort — error messages reference adapters by name.
|
|
692
|
-
*/
|
|
693
|
-
name: string;
|
|
694
|
-
version?: string;
|
|
695
|
-
requires?: {
|
|
696
|
-
kickjs?: string;
|
|
697
|
-
};
|
|
698
|
-
defaults?: Partial<TConfig>;
|
|
699
|
-
build(config: TConfig, ctx: BuildContext): Omit<AppAdapter, 'name'> & TExtra;
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Async-config form of an adapter. Identical shape to `PluginAsyncOptions`
|
|
703
|
-
* but resolved during `beforeStart` (the earliest async hook in
|
|
704
|
-
* `AppAdapter`) — meaning `middleware()` and `contributors()` from the inner
|
|
705
|
-
* adapter are **not** picked up. Use the bare/`.scoped()` form when you need
|
|
706
|
-
* those.
|
|
707
|
-
*/
|
|
708
|
-
interface AdapterAsyncOptions<TConfig> {
|
|
709
|
-
inject?: ReadonlyArray<unknown>;
|
|
710
|
-
useFactory(...deps: any[]): TConfig | Promise<TConfig>;
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Factory returned by {@link defineAdapter}. Same surface as
|
|
714
|
-
* {@link PluginFactory} (call / `.scoped()` / `.async()`) so adopters learn
|
|
715
|
-
* one mental model for both primitives. Returned instances carry both
|
|
716
|
-
* the standard {@link AppAdapter} contract and any `TExtra` extension
|
|
717
|
-
* methods the `build` function exposed.
|
|
718
|
-
*/
|
|
719
|
-
interface AdapterFactory<TConfig, TExtra = unknown> {
|
|
720
|
-
(config?: Partial<TConfig>): AppAdapter & TExtra;
|
|
721
|
-
scoped(scopeName: string, config?: Partial<TConfig>): AppAdapter & TExtra;
|
|
722
|
-
async(opts: AdapterAsyncOptions<TConfig>): AppAdapter;
|
|
723
|
-
readonly definition: Readonly<DefineAdapterOptions<TConfig, TExtra>>;
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
* Build an {@link AppAdapter} factory from a typed definition. See
|
|
727
|
-
* `architecture.md` §21.3.4 for migration guidance — most first-party
|
|
728
|
-
* adapter packages collapse to a single `defineAdapter()` call after this
|
|
729
|
-
* lands.
|
|
730
|
-
*
|
|
731
|
-
* @example
|
|
732
|
-
* ```ts
|
|
733
|
-
* const TenantAdapter = defineAdapter<TenantConfig>({
|
|
734
|
-
* name: 'TenantAdapter',
|
|
735
|
-
* defaults: { strategy: 'header', required: true },
|
|
736
|
-
* build: (config) => ({
|
|
737
|
-
* middleware: () => [tenantResolverMiddleware(config)],
|
|
738
|
-
* beforeStart: ({ container }) => registerTenantFactory(container, config),
|
|
739
|
-
* }),
|
|
740
|
-
* })
|
|
741
|
-
*
|
|
742
|
-
* bootstrap({
|
|
743
|
-
* adapters: [
|
|
744
|
-
* TenantAdapter({ strategy: 'subdomain' }),
|
|
745
|
-
* TenantAdapter.scoped('shard-eu', { headerName: 'x-eu-tenant' }),
|
|
746
|
-
* ],
|
|
747
|
-
* })
|
|
748
|
-
* ```
|
|
749
|
-
*/
|
|
750
|
-
declare function defineAdapter<TConfig = Record<string, unknown>, TExtra = unknown>(options: DefineAdapterOptions<TConfig, TExtra>): AdapterFactory<TConfig, TExtra>;
|
|
751
|
-
//#endregion
|
|
752
|
-
//#region src/core/asset-keys.d.ts
|
|
753
|
-
type AssetKeyStrategy = 'auto' | 'strip' | 'with-extension';
|
|
754
|
-
interface AssetKeyPair {
|
|
755
|
-
/** Source-relative path the file was discovered at. */
|
|
756
|
-
rel: string;
|
|
757
|
-
/** Final logical key for the manifest, including the namespace prefix. */
|
|
758
|
-
key: string;
|
|
759
|
-
}
|
|
760
|
-
interface GroupAssetKeysOptions {
|
|
761
|
-
/**
|
|
762
|
-
* Strategy applied to this namespace. Default `'auto'`.
|
|
763
|
-
*
|
|
764
|
-
* Adopters override per-namespace via `assetMap.<ns>.keys` in
|
|
765
|
-
* kick.config.ts when they want uniform behaviour (e.g. always
|
|
766
|
-
* include the extension regardless of collisions).
|
|
767
|
-
*/
|
|
768
|
-
strategy?: AssetKeyStrategy;
|
|
769
|
-
}
|
|
770
|
-
interface GroupAssetKeysResult {
|
|
771
|
-
pairs: AssetKeyPair[];
|
|
772
|
-
/**
|
|
773
|
-
* Number of collision groups resolved by keeping extensions.
|
|
774
|
-
* Surfaces as an informational log ("auto-resolved N collisions")
|
|
775
|
-
* so adopters know whether they're relying on auto-mode or not.
|
|
776
|
-
* Always 0 for `'strip'` (overwrites) and `'with-extension'`
|
|
777
|
-
* (extensions always preserved, no collision possible).
|
|
778
|
-
*/
|
|
779
|
-
collisionGroupsResolved: number;
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* Compute final manifest keys for a namespace's discovered paths,
|
|
783
|
-
* given the chosen strategy. Pure function — no fs / config / globals
|
|
784
|
-
* involved.
|
|
785
|
-
*
|
|
786
|
-
* @param namespace assetMap key — e.g. `'mails'`, `'pages'`.
|
|
787
|
-
* @param paths source-relative file paths (POSIX separators) discovered
|
|
788
|
-
* under the namespace's `src` directory.
|
|
789
|
-
* @param opts grouping options.
|
|
790
|
-
*/
|
|
791
|
-
declare function groupAssetKeys(namespace: string, paths: readonly string[], opts?: GroupAssetKeysOptions): GroupAssetKeysResult;
|
|
792
|
-
/** Strip the final extension from a path. `'mails/welcome.ejs'` → `'mails/welcome'`. */
|
|
793
|
-
declare function stripExt(path: string): string;
|
|
794
|
-
//#endregion
|
|
795
|
-
export { defineModule as $, CircuitBreakerStats as A, pushMethodMeta as B, buildPipeline as C, CircuitBreaker as D, MissingContributorError as E, getMetaRecord as F, FormatKickErrorOptions as G, setInMetaMap as H, getMethodMeta as I, formatKickError as J, KickError as K, getMethodMetaOrUndefined as L, getClassMeta as M, getClassMetaOrUndefined as N, CircuitBreakerOptions as O, getMetaMap as P, ModuleFactory as Q, hasClassMeta as R, SourcedRegistration as S, DuplicateContributorError as T, setInMetaRecord as U, setClassMeta as V, setMethodMeta as W, defineModules as X, ModuleList as Y, DefineModuleOptions as Z, RunContributorsOptions as _, groupAssetKeys as a, ContributorPipeline as b, AdapterFactory as c, DuplicateMountNameError as d, BuildContext as et, MissingMountDepError as f, mountSort as g, MountSortItem as h, GroupAssetKeysResult as i, definePlugin as it, CircuitOpenError as j, CircuitBreakerState as k, DefineAdapterOptions as l, MountKind as m, AssetKeyStrategy as n, PluginAsyncOptions as nt, stripExt as o, MountCycleError as p, KickErrorInit as q, GroupAssetKeysOptions as r, PluginFactory as rt, AdapterAsyncOptions as s, AssetKeyPair as t, DefinePluginOptions as tt, defineAdapter as u, runContributors as v, ContributorCycleError as w, ContributorSource as x, BuildPipelineOptions as y, pushClassMeta as z };
|
|
796
|
-
//# sourceMappingURL=index-frSEHiL_.d.mts.map
|