@zapier/kitcore 0.20.0 → 0.21.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/CHANGELOG.md +98 -0
- package/README.md +1 -1
- package/dist/index.cjs +2121 -2382
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +855 -1519
- package/dist/index.d.ts +855 -1519
- package/dist/index.mjs +2109 -2361
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,139 @@ declare module "zod" {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Per-call context threaded explicitly through the method boundary in place of
|
|
13
|
+
* ambient AsyncLocalStorage. It carries call identity, nesting depth, and a
|
|
14
|
+
* per-invocation annotation bag. Because it travels as data, correlation and
|
|
15
|
+
* nested-call dedup work without `async_hooks` — including in browsers, where
|
|
16
|
+
* the old ALS store was inert and nested calls all looked top-level.
|
|
17
|
+
*
|
|
18
|
+
* Framework-neutral: heads surface `callId` under their own name (e.g. a
|
|
19
|
+
* correlation id) and own their annotation field names.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* A private brand (a fresh `Symbol()`, never `Symbol.for`) makes a CallContext
|
|
23
|
+
* unforgeable: no outside code can name the symbol to synthesize an id-bearing
|
|
24
|
+
* context, and the brand never collides across bundled copies. This is the same
|
|
25
|
+
* unforgeability the `INTERNAL_CALL` sentinel relies on.
|
|
26
|
+
*/
|
|
27
|
+
declare const CALL_CONTEXT_BRAND: unique symbol;
|
|
28
|
+
/**
|
|
29
|
+
* The per-invocation annotation bag: an open string-keyed map a head fills with
|
|
30
|
+
* telemetry-shaping fields (via the boundary annotator, a method's pre-run
|
|
31
|
+
* `annotator`, or the run bag's mid-`run` `annotate`) and reads back on the
|
|
32
|
+
* method-lifecycle hook context. Framework-neutral: kitcore does not know or
|
|
33
|
+
* constrain the keys.
|
|
34
|
+
*/
|
|
35
|
+
type Annotations = Record<string, unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Origin of a call's root. `"surface"` = entered through the SDK surface, or a
|
|
38
|
+
* parent-less runtime delegation that still represents real user work;
|
|
39
|
+
* `"internal"` = a framework-internal root minted by kitcore's own machinery,
|
|
40
|
+
* which a head can suppress from telemetry.
|
|
41
|
+
*/
|
|
42
|
+
type CallOrigin = "surface" | "internal";
|
|
43
|
+
interface CallContext {
|
|
44
|
+
/**
|
|
45
|
+
* Minted once at the root call; copied verbatim to every nested (child) call.
|
|
46
|
+
* `readonly`: method code owns only the `annotations` bag. A child copies this
|
|
47
|
+
* off the live parent when the delegated call fires, so mutating it mid-run
|
|
48
|
+
* would corrupt the child's correlation id.
|
|
49
|
+
*/
|
|
50
|
+
readonly callId: string | null;
|
|
51
|
+
/**
|
|
52
|
+
* 0 at the outermost call; `parent.depth + 1` for a delegated call. `readonly`
|
|
53
|
+
* for the same reason as `callId` — a mutated depth would mis-nest children
|
|
54
|
+
* and, where ALS can't correct it (browsers), duplicate telemetry.
|
|
55
|
+
*/
|
|
56
|
+
readonly depth: number;
|
|
57
|
+
/**
|
|
58
|
+
* Per-invocation scratch space. Never forwarded to callees — a child call
|
|
59
|
+
* gets a fresh bag — so annotations describe one method's own invocation.
|
|
60
|
+
* Method `run` code contributes through the run bag's `annotate` function
|
|
61
|
+
* rather than writing here directly; the bag reference is fixed, only its
|
|
62
|
+
* contents change.
|
|
63
|
+
*/
|
|
64
|
+
readonly annotations: Annotations;
|
|
65
|
+
/**
|
|
66
|
+
* Origin of the call's root, copied verbatim to every child. `"surface"`
|
|
67
|
+
* (the default) marks a surface-origin root — a call that entered through the
|
|
68
|
+
* SDK surface, or a parent-less runtime delegation that still represents real
|
|
69
|
+
* user work (e.g. a delegation proxy reaching another method). `"internal"`
|
|
70
|
+
* marks a framework-internal root minted by kitcore's own build-time machinery
|
|
71
|
+
* (resolver/formatter/dispose/observer twins, `resolvePlugin`), which a head
|
|
72
|
+
* can suppress from telemetry. Orthogonal to `depth`: an internal root is
|
|
73
|
+
* still `depth 0`. `readonly` so a child can't inherit a mutated origin.
|
|
74
|
+
*/
|
|
75
|
+
readonly callOrigin: CallOrigin;
|
|
76
|
+
readonly [CALL_CONTEXT_BRAND]: true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Method-call lifecycle hooks. Plugins contribute `onMethodStart` and/or
|
|
81
|
+
* `onMethodEnd` observers, plus an optional pre-run `annotator` that returns
|
|
82
|
+
* fields merged into the call's annotation bag; `buildHooks` composes each
|
|
83
|
+
* across plugins so multiple contributors coexist. Composition is right-additive
|
|
84
|
+
* (newer plugins fire — and `annotator` fields win — after earlier ones); a
|
|
85
|
+
* method triggers the hooks only when its boundary fires them, which is every
|
|
86
|
+
* `item` / `list` method and any raw method that opts in.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
interface OnMethodStartContext {
|
|
90
|
+
methodName: string;
|
|
91
|
+
args: unknown[];
|
|
92
|
+
isPaginated: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Depth of this method invocation in the SDK call tree. 0 = outermost
|
|
95
|
+
* (user-initiated) call; 1+ = called from inside another SDK method.
|
|
96
|
+
* Observers can use this to ignore nested calls if they only want
|
|
97
|
+
* top-level events.
|
|
98
|
+
*/
|
|
99
|
+
depth: number;
|
|
100
|
+
/** The call's correlation id, copied from the per-call context; `null` where
|
|
101
|
+
* id minting was unavailable. */
|
|
102
|
+
callId: string | null;
|
|
103
|
+
/**
|
|
104
|
+
* Origin of the call's root, copied from the per-call context. `"surface"` =
|
|
105
|
+
* surface-origin (an SDK-surface call or a runtime delegation — real user
|
|
106
|
+
* work); `"internal"` = a framework-internal call minted by kitcore's own
|
|
107
|
+
* machinery (resolver/formatter/dispose/observer twins, `resolvePlugin`).
|
|
108
|
+
* Orthogonal to `depth` (an internal call is still `depth 0`); a head can drop
|
|
109
|
+
* internal-origin calls from telemetry.
|
|
110
|
+
*/
|
|
111
|
+
callOrigin: CallOrigin;
|
|
112
|
+
/**
|
|
113
|
+
* The call's annotation bag, carried live from the per-call context. At
|
|
114
|
+
* `onMethodStart` it holds the early-knowable fields (boundary annotator +
|
|
115
|
+
* a method's pre-run `annotator`); by `onMethodEnd` any mid-`run` writes
|
|
116
|
+
* are visible too (same object reference throughout the call).
|
|
117
|
+
*/
|
|
118
|
+
annotations: Annotations;
|
|
119
|
+
}
|
|
120
|
+
type OnMethodStart = (ctx: OnMethodStartContext) => void;
|
|
121
|
+
interface OnMethodEndContext extends OnMethodStartContext {
|
|
122
|
+
durationMs: number;
|
|
123
|
+
error?: Error;
|
|
124
|
+
}
|
|
125
|
+
type OnMethodEnd = (ctx: OnMethodEndContext) => void;
|
|
126
|
+
/**
|
|
127
|
+
* A composed pre-run annotator: given a call's method name and (normalized,
|
|
128
|
+
* pre-validation) input, it returns {@link Annotations} the boundary merges into
|
|
129
|
+
* the call's bag before `onMethodStart`. Unlike the `void` lifecycle observers,
|
|
130
|
+
* this one returns a value; composition merges the returned bags rather than
|
|
131
|
+
* chaining side effects. A contributor with nothing to add returns an empty bag,
|
|
132
|
+
* so absence is modelled by no annotator rather than an `undefined` return.
|
|
133
|
+
*/
|
|
134
|
+
type ComposedAnnotator = (ctx: {
|
|
135
|
+
methodName: string;
|
|
136
|
+
input: unknown;
|
|
137
|
+
}) => Annotations;
|
|
138
|
+
interface MethodHooks {
|
|
139
|
+
onMethodStart?: OnMethodStart;
|
|
140
|
+
onMethodEnd?: OnMethodEnd;
|
|
141
|
+
annotator?: ComposedAnnotator;
|
|
142
|
+
}
|
|
143
|
+
|
|
11
144
|
/**
|
|
12
145
|
* What the framework reports about the output it produced.
|
|
13
146
|
*
|
|
@@ -140,292 +273,73 @@ interface PaginatedSdkResult<TItem> extends Promise<SdkPage<TItem>> {
|
|
|
140
273
|
type PaginatedSdkFunction<TOptions, TItem> = (options: TOptions) => PaginatedSdkResult<TItem>;
|
|
141
274
|
|
|
142
275
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* `Symbol.for`, not `Symbol()`: heads bundle kitcore (tsup `noExternal`), so
|
|
151
|
-
* an sdk built by one bundle's copy must still be readable by another copy's
|
|
152
|
-
* `getContext` / `resolvePlugin` (e.g. a CLI sdk inspected with helpers
|
|
153
|
-
* imported from `@zapier/zapier-sdk`). The global symbol registry makes every
|
|
154
|
-
* copy agree on the key.
|
|
155
|
-
*/
|
|
156
|
-
declare const CONTEXT: unique symbol;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Per-call context threaded explicitly through the method boundary in place of
|
|
160
|
-
* ambient AsyncLocalStorage. It carries call identity, nesting depth, and a
|
|
161
|
-
* per-invocation annotation bag. Because it travels as data, correlation and
|
|
162
|
-
* nested-call dedup work without `async_hooks` — including in browsers, where
|
|
163
|
-
* the old ALS store was inert and nested calls all looked top-level.
|
|
276
|
+
* Plugins with a required-parameter rename declare two schemas: a canonical one
|
|
277
|
+
* (new names only, carrying `.meta({ aliases })`) and a `z.union([canonical,
|
|
278
|
+
* deprecated])` for runtime input parsing (so callers passing old names still
|
|
279
|
+
* validate). The union has no object shape, so everything that reads parameter
|
|
280
|
+
* shape/requiredness — the registry projection, generated docs, and the
|
|
281
|
+
* resolution planner — must read the canonical variant, not the union.
|
|
164
282
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* A private brand (a fresh `Symbol()`, never `Symbol.for`) makes a CallContext
|
|
170
|
-
* unforgeable: no outside code can name the symbol to synthesize an id-bearing
|
|
171
|
-
* context, and the brand never collides across bundled copies. This is the same
|
|
172
|
-
* unforgeability the `INTERNAL_CALL` sentinel relies on.
|
|
173
|
-
*/
|
|
174
|
-
declare const CALL_CONTEXT_BRAND: unique symbol;
|
|
175
|
-
/**
|
|
176
|
-
* The per-invocation annotation bag: an open string-keyed map a head fills with
|
|
177
|
-
* telemetry-shaping fields (via the boundary annotator, a method's pre-run
|
|
178
|
-
* `annotator`, or the run bag's mid-`run` `annotate`) and reads back on the
|
|
179
|
-
* method-lifecycle hook context. Framework-neutral: kitcore does not know or
|
|
180
|
-
* constrain the keys.
|
|
283
|
+
* Convention: the FIRST union variant is the canonical schema. Every plugin
|
|
284
|
+
* that uses unions follows this; it's explicit and needs no extra metadata.
|
|
285
|
+
* Runtime validation still uses the full union; only shape reading canonicalizes.
|
|
181
286
|
*/
|
|
182
|
-
|
|
287
|
+
declare function canonicalInputSchema(schema: z.ZodSchema | undefined): z.ZodSchema | undefined;
|
|
288
|
+
/** Strip optional/default/nullable wrappers to the inner schema, tracking
|
|
289
|
+
* whether the wrappers made the field non-required. */
|
|
290
|
+
declare function unwrapSchema(schema: z.ZodType): {
|
|
291
|
+
inner: z.ZodType;
|
|
292
|
+
required: boolean;
|
|
293
|
+
};
|
|
183
294
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* `
|
|
187
|
-
*
|
|
295
|
+
* The object shape of a method's input schema, or undefined when the schema is
|
|
296
|
+
* absent or not a plain object. A required-rename union (`z.union([canonical,
|
|
297
|
+
* deprecated])`) is canonicalized to its first variant first, and
|
|
298
|
+
* optional/default/nullable wrappers are stripped, so a schema whose fields are
|
|
299
|
+
* readable at all is read rather than treated as shapeless.
|
|
188
300
|
*/
|
|
189
|
-
|
|
190
|
-
interface
|
|
191
|
-
|
|
192
|
-
* Minted once at the root call; copied verbatim to every nested (child) call.
|
|
193
|
-
* `readonly`: method code owns only the `annotations` bag. A child copies this
|
|
194
|
-
* off the live parent when the delegated call fires, so mutating it mid-run
|
|
195
|
-
* would corrupt the child's correlation id.
|
|
196
|
-
*/
|
|
197
|
-
readonly callId: string | null;
|
|
301
|
+
declare function objectShapeOf(schema: z.ZodSchema | undefined): Record<string, z.ZodType> | undefined;
|
|
302
|
+
interface FormattedItem {
|
|
303
|
+
title: string;
|
|
198
304
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
305
|
+
* Secondary identifying context shown dimmed after the title (ids, keys,
|
|
306
|
+
* slugs, ...). A dumb visual string a renderer shows verbatim, never
|
|
307
|
+
* structured data it has to interpret; the same role as a prompt choice's
|
|
308
|
+
* `hint`. An array is joined with ", ". Structured fields live on the
|
|
309
|
+
* response / `outputSchema`, not here, so the renderer stays dumb.
|
|
202
310
|
*/
|
|
203
|
-
|
|
311
|
+
hint?: string | string[];
|
|
312
|
+
/** @deprecated Use `hint` (the renderer no longer interprets ids). */
|
|
313
|
+
id?: string;
|
|
314
|
+
/** @deprecated Use `hint`. */
|
|
315
|
+
key?: string;
|
|
316
|
+
/** @deprecated Use `hint`. */
|
|
317
|
+
keys?: string[];
|
|
318
|
+
description?: string;
|
|
319
|
+
/** If provided, the renderer shows this raw (verbatim) instead of `details`. */
|
|
320
|
+
raw?: unknown;
|
|
321
|
+
details: Array<{
|
|
322
|
+
label?: string;
|
|
323
|
+
text: string;
|
|
324
|
+
style: "normal" | "dim" | "accent" | "warning" | "success";
|
|
325
|
+
}>;
|
|
326
|
+
}
|
|
327
|
+
declare function getOutputSchema(inputSchema: z.ZodType): z.ZodType | undefined;
|
|
328
|
+
declare function withOutputSchema<T extends z.ZodType>(inputSchema: T, outputSchema: z.ZodType): T & {
|
|
329
|
+
_def: T["_def"] & {
|
|
330
|
+
outputSchema: z.ZodType;
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
/** A selectable option in a prompt. `label` is the display text; `value` is
|
|
334
|
+
* what the resolver returns when picked. */
|
|
335
|
+
interface PromptConfigChoice {
|
|
336
|
+
label: string;
|
|
337
|
+
value: unknown;
|
|
204
338
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* contents change.
|
|
210
|
-
*/
|
|
211
|
-
readonly annotations: Annotations;
|
|
212
|
-
/**
|
|
213
|
-
* Origin of the call's root, copied verbatim to every child. `"surface"`
|
|
214
|
-
* (the default) marks a surface-origin root — a call that entered through the
|
|
215
|
-
* SDK surface, or a parent-less runtime delegation that still represents real
|
|
216
|
-
* user work (e.g. a delegation proxy reaching another method). `"internal"`
|
|
217
|
-
* marks a framework-internal root minted by kitcore's own build-time machinery
|
|
218
|
-
* (resolver/formatter/dispose/observer twins, `resolvePlugin`), which a head
|
|
219
|
-
* can suppress from telemetry. Orthogonal to `depth`: an internal root is
|
|
220
|
-
* still `depth 0`. `readonly` so a child can't inherit a mutated origin.
|
|
221
|
-
*/
|
|
222
|
-
readonly callOrigin: CallOrigin;
|
|
223
|
-
readonly [CALL_CONTEXT_BRAND]: true;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Method-call lifecycle hooks. Plugins contribute `onMethodStart` and/or
|
|
228
|
-
* `onMethodEnd` observers, plus an optional pre-run `annotator` that returns
|
|
229
|
-
* fields merged into the call's annotation bag; `buildHooks` composes each
|
|
230
|
-
* across plugins so multiple contributors coexist. Composition is right-additive
|
|
231
|
-
* (newer plugins fire — and `annotator` fields win — after earlier ones); only
|
|
232
|
-
* opt-in methods built through `createPluginMethod` /
|
|
233
|
-
* `createPaginatedPluginMethod` trigger the hooks.
|
|
234
|
-
*/
|
|
235
|
-
|
|
236
|
-
interface OnMethodStartContext {
|
|
237
|
-
methodName: string;
|
|
238
|
-
args: unknown[];
|
|
239
|
-
isPaginated: boolean;
|
|
240
|
-
/**
|
|
241
|
-
* Depth of this method invocation in the SDK call tree. 0 = outermost
|
|
242
|
-
* (user-initiated) call; 1+ = called from inside another SDK method.
|
|
243
|
-
* Observers can use this to ignore nested calls if they only want
|
|
244
|
-
* top-level events.
|
|
245
|
-
*/
|
|
246
|
-
depth: number;
|
|
247
|
-
/** The call's correlation id, copied from the per-call context; `null` where
|
|
248
|
-
* id minting was unavailable. */
|
|
249
|
-
callId: string | null;
|
|
250
|
-
/**
|
|
251
|
-
* Origin of the call's root, copied from the per-call context. `"surface"` =
|
|
252
|
-
* surface-origin (an SDK-surface call or a runtime delegation — real user
|
|
253
|
-
* work); `"internal"` = a framework-internal call minted by kitcore's own
|
|
254
|
-
* machinery (resolver/formatter/dispose/observer twins, `resolvePlugin`).
|
|
255
|
-
* Orthogonal to `depth` (an internal call is still `depth 0`); a head can drop
|
|
256
|
-
* internal-origin calls from telemetry.
|
|
257
|
-
*/
|
|
258
|
-
callOrigin: CallOrigin;
|
|
259
|
-
/**
|
|
260
|
-
* The call's annotation bag, carried live from the per-call context. At
|
|
261
|
-
* `onMethodStart` it holds the early-knowable fields (boundary annotator +
|
|
262
|
-
* a method's pre-run `annotator`); by `onMethodEnd` any mid-`run` writes
|
|
263
|
-
* are visible too (same object reference throughout the call).
|
|
264
|
-
*/
|
|
265
|
-
annotations: Annotations;
|
|
266
|
-
}
|
|
267
|
-
type OnMethodStart = (ctx: OnMethodStartContext) => void;
|
|
268
|
-
interface OnMethodEndContext extends OnMethodStartContext {
|
|
269
|
-
durationMs: number;
|
|
270
|
-
error?: Error;
|
|
271
|
-
}
|
|
272
|
-
type OnMethodEnd = (ctx: OnMethodEndContext) => void;
|
|
273
|
-
/**
|
|
274
|
-
* A composed pre-run annotator: given a call's method name and (normalized,
|
|
275
|
-
* pre-validation) input, it returns {@link Annotations} the boundary merges into
|
|
276
|
-
* the call's bag before `onMethodStart`. Unlike the `void` lifecycle observers,
|
|
277
|
-
* this one returns a value; composition merges the returned bags rather than
|
|
278
|
-
* chaining side effects. A contributor with nothing to add returns an empty bag,
|
|
279
|
-
* so absence is modelled by no annotator rather than an `undefined` return.
|
|
280
|
-
*/
|
|
281
|
-
type ComposedAnnotator = (ctx: {
|
|
282
|
-
methodName: string;
|
|
283
|
-
input: unknown;
|
|
284
|
-
}) => Annotations;
|
|
285
|
-
interface MethodHooks {
|
|
286
|
-
onMethodStart?: OnMethodStart;
|
|
287
|
-
onMethodEnd?: OnMethodEnd;
|
|
288
|
-
annotator?: ComposedAnnotator;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* API stability tiers.
|
|
293
|
-
*
|
|
294
|
-
* A plugin declares exactly one level via `PluginMeta.stability`; tier
|
|
295
|
-
* membership (which subpath aggregate exports the plugin) is structural,
|
|
296
|
-
* so nothing here compares levels ordinally. The array is the single
|
|
297
|
-
* source of truth: it derives the {@link StabilityLevel} type, gives the
|
|
298
|
-
* ladder tests their adjacent-tier iteration order, and gives docs a
|
|
299
|
-
* render order.
|
|
300
|
-
*/
|
|
301
|
-
declare const STABILITY_LEVELS: readonly ["stable", "beta", "experimental"];
|
|
302
|
-
type StabilityLevel = (typeof STABILITY_LEVELS)[number];
|
|
303
|
-
/**
|
|
304
|
-
* Title-case display names for each level, for section-level badges in
|
|
305
|
-
* generated docs (e.g. `Code Workflows (Beta)`). Inline description
|
|
306
|
-
* labels go through {@link applyStabilityLabel} instead.
|
|
307
|
-
*/
|
|
308
|
-
declare const STABILITY_TITLES: {
|
|
309
|
-
readonly stable: "Stable";
|
|
310
|
-
readonly beta: "Beta";
|
|
311
|
-
readonly experimental: "Experimental";
|
|
312
|
-
};
|
|
313
|
-
/**
|
|
314
|
-
* Normalize authored meta to a concrete level: absent means `"stable"`,
|
|
315
|
-
* and the deprecated `experimental: true` boolean means `"experimental"`.
|
|
316
|
-
* The registry projection runs every entry through this, so
|
|
317
|
-
* `FunctionRegistryEntry.stability` is always concrete and consumers
|
|
318
|
-
* never branch on `undefined`.
|
|
319
|
-
*
|
|
320
|
-
* The declared value can cross a JSON boundary from a hand-written
|
|
321
|
-
* plugin, so at runtime it may be any string. An unrecognized level
|
|
322
|
-
* clamps to `"experimental"` — the author declared the method not
|
|
323
|
-
* stable, and clamping keeps the raw string out of notices and labels.
|
|
324
|
-
* It doesn't throw because this also runs in the `getStability` live
|
|
325
|
-
* read on the call path, where a throw would break the observed call.
|
|
326
|
-
*/
|
|
327
|
-
declare function normalizeStability(meta: {
|
|
328
|
-
stability?: StabilityLevel;
|
|
329
|
-
experimental?: boolean;
|
|
330
|
-
}): StabilityLevel;
|
|
331
|
-
/**
|
|
332
|
-
* The shared label renderer: every consumer that renders a registry
|
|
333
|
-
* entry's description (CLI help, MCP tool descriptions) labels it
|
|
334
|
-
* through this function, so a new consumer cannot silently drop the
|
|
335
|
-
* label. `stability` stays structured data on the registry entry — the
|
|
336
|
-
* label is applied at render time, never baked into the stored
|
|
337
|
-
* description (docs badge at the section level, so baking it in would
|
|
338
|
-
* double-badge).
|
|
339
|
-
*
|
|
340
|
-
* The label follows the plugin's declared level, not the subpath that
|
|
341
|
-
* surfaced it: a beta method surfaced through an experimental-tier
|
|
342
|
-
* consumer still reads "(beta)".
|
|
343
|
-
*/
|
|
344
|
-
declare function applyStabilityLabel({ description, stability, placement, }: {
|
|
345
|
-
description: string;
|
|
346
|
-
/** Absent means stable (the value may arrive from outside the
|
|
347
|
-
* normalized registry projection, e.g. hand-built JSON). */
|
|
348
|
-
stability: StabilityLevel | undefined;
|
|
349
|
-
/**
|
|
350
|
-
* `"suffix"` renders `<description> (beta)` (CLI help);
|
|
351
|
-
* `"prefix"` renders `[Beta] <description>` (MCP tool descriptions,
|
|
352
|
-
* where the front of the string is what an LLM reads first).
|
|
353
|
-
*/
|
|
354
|
-
placement?: "suffix" | "prefix";
|
|
355
|
-
}): string;
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Plugins with a required-parameter rename declare two schemas: a canonical one
|
|
359
|
-
* (new names only, carrying `.meta({ aliases })`) and a `z.union([canonical,
|
|
360
|
-
* deprecated])` for runtime input parsing (so callers passing old names still
|
|
361
|
-
* validate). The union has no object shape, so everything that reads parameter
|
|
362
|
-
* shape/requiredness — the registry projection, generated docs, and the
|
|
363
|
-
* resolution planner — must read the canonical variant, not the union.
|
|
364
|
-
*
|
|
365
|
-
* Convention: the FIRST union variant is the canonical schema. Every plugin
|
|
366
|
-
* that uses unions follows this; it's explicit and needs no extra metadata.
|
|
367
|
-
* Runtime validation still uses the full union; only shape reading canonicalizes.
|
|
368
|
-
*/
|
|
369
|
-
declare function canonicalInputSchema(schema: z.ZodSchema | undefined): z.ZodSchema | undefined;
|
|
370
|
-
/** Strip optional/default/nullable wrappers to the inner schema, tracking
|
|
371
|
-
* whether the wrappers made the field non-required. */
|
|
372
|
-
declare function unwrapSchema(schema: z.ZodType): {
|
|
373
|
-
inner: z.ZodType;
|
|
374
|
-
required: boolean;
|
|
375
|
-
};
|
|
376
|
-
/**
|
|
377
|
-
* The object shape of a method's input schema, or undefined when the schema is
|
|
378
|
-
* absent or not a plain object. A required-rename union (`z.union([canonical,
|
|
379
|
-
* deprecated])`) is canonicalized to its first variant first, and
|
|
380
|
-
* optional/default/nullable wrappers are stripped, so a schema whose fields are
|
|
381
|
-
* readable at all is read rather than treated as shapeless.
|
|
382
|
-
*/
|
|
383
|
-
declare function objectShapeOf(schema: z.ZodSchema | undefined): Record<string, z.ZodType> | undefined;
|
|
384
|
-
interface FormattedItem {
|
|
385
|
-
title: string;
|
|
386
|
-
/**
|
|
387
|
-
* Secondary identifying context shown dimmed after the title (ids, keys,
|
|
388
|
-
* slugs, ...). A dumb visual string a renderer shows verbatim, never
|
|
389
|
-
* structured data it has to interpret; the same role as a prompt choice's
|
|
390
|
-
* `hint`. An array is joined with ", ". Structured fields live on the
|
|
391
|
-
* response / `outputSchema`, not here, so the renderer stays dumb.
|
|
392
|
-
*/
|
|
393
|
-
hint?: string | string[];
|
|
394
|
-
/** @deprecated Use `hint` (the renderer no longer interprets ids). */
|
|
395
|
-
id?: string;
|
|
396
|
-
/** @deprecated Use `hint`. */
|
|
397
|
-
key?: string;
|
|
398
|
-
/** @deprecated Use `hint`. */
|
|
399
|
-
keys?: string[];
|
|
400
|
-
description?: string;
|
|
401
|
-
/** If provided, the renderer shows this raw (verbatim) instead of `details`. */
|
|
402
|
-
raw?: unknown;
|
|
403
|
-
details: Array<{
|
|
404
|
-
label?: string;
|
|
405
|
-
text: string;
|
|
406
|
-
style: "normal" | "dim" | "accent" | "warning" | "success";
|
|
407
|
-
}>;
|
|
408
|
-
}
|
|
409
|
-
interface OutputFormatter<TSdk, TItem = unknown, TParams = Record<string, unknown>, TContext = unknown> {
|
|
410
|
-
fetch?: (sdk: TSdk, params: TParams, item: TItem, context: TContext | undefined) => Promise<TContext>;
|
|
411
|
-
format: (item: TItem, context?: TContext) => FormattedItem;
|
|
412
|
-
}
|
|
413
|
-
declare function getOutputSchema(inputSchema: z.ZodType): z.ZodType | undefined;
|
|
414
|
-
declare function withOutputSchema<T extends z.ZodType>(inputSchema: T, outputSchema: z.ZodType): T & {
|
|
415
|
-
_def: T["_def"] & {
|
|
416
|
-
outputSchema: z.ZodType;
|
|
417
|
-
};
|
|
418
|
-
};
|
|
419
|
-
/** A selectable option in a prompt. `label` is the display text; `value` is
|
|
420
|
-
* what the resolver returns when picked. */
|
|
421
|
-
interface PromptConfigChoice {
|
|
422
|
-
label: string;
|
|
423
|
-
value: unknown;
|
|
424
|
-
/**
|
|
425
|
-
* Optional secondary info shown after the label. The CLI wraps it in
|
|
426
|
-
* dimmed parens; an array is joined with ", ". Use for keys, ids, or
|
|
427
|
-
* other context that's useful but shouldn't compete visually with
|
|
428
|
-
* the primary label.
|
|
339
|
+
* Optional secondary info shown after the label. The CLI wraps it in
|
|
340
|
+
* dimmed parens; an array is joined with ", ". Use for keys, ids, or
|
|
341
|
+
* other context that's useful but shouldn't compete visually with
|
|
342
|
+
* the primary label.
|
|
429
343
|
*/
|
|
430
344
|
hint?: string | string[];
|
|
431
345
|
}
|
|
@@ -681,69 +595,288 @@ declare function openEnum<const T extends readonly [string, ...string[]]>(values
|
|
|
681
595
|
}>, z.ZodString]>;
|
|
682
596
|
|
|
683
597
|
/**
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
598
|
+
* The external escape-hatch key for an SDK's context. A Symbol,
|
|
599
|
+
* not a string, so it stays off the string surface (which is exactly the root's
|
|
600
|
+
* exports) and is collision-free and clearly internal. It is attached at
|
|
601
|
+
* runtime but kept OUT of the public SDK type (a `unique symbol` in an exported
|
|
602
|
+
* type can't be named in a consumer's emitted `.d.ts`); reach it through the
|
|
603
|
+
* typed `getContext(sdk)` accessor.
|
|
604
|
+
*
|
|
605
|
+
* `Symbol.for`, not `Symbol()`: heads bundle kitcore (tsup `noExternal`), so
|
|
606
|
+
* an sdk built by one bundle's copy must still be readable by another copy's
|
|
607
|
+
* `getContext` / `resolvePlugin` (e.g. a CLI sdk inspected with helpers
|
|
608
|
+
* imported from `@zapier/zapier-sdk`). The global symbol registry makes every
|
|
609
|
+
* copy agree on the key.
|
|
688
610
|
*/
|
|
689
|
-
|
|
611
|
+
declare const CONTEXT: unique symbol;
|
|
612
|
+
|
|
690
613
|
/**
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
614
|
+
* API stability tiers.
|
|
615
|
+
*
|
|
616
|
+
* A plugin declares exactly one level via `MethodMeta.stability`; tier
|
|
617
|
+
* membership (which subpath aggregate exports the plugin) is structural,
|
|
618
|
+
* so nothing here compares levels ordinally. The array is the single
|
|
619
|
+
* source of truth: it derives the {@link StabilityLevel} type, gives the
|
|
620
|
+
* ladder tests their adjacent-tier iteration order, and gives docs a
|
|
621
|
+
* render order.
|
|
697
622
|
*/
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
categories?: (string | CategoryDefinition)[];
|
|
701
|
-
type?: "list" | "item" | "create" | "update" | "delete" | "function";
|
|
702
|
-
itemType?: string;
|
|
703
|
-
returnType?: string;
|
|
704
|
-
outputSchema?: z.ZodSchema;
|
|
705
|
-
/** Behavioral opt-out that rides on this config for every `defineMethod`
|
|
706
|
-
* overload (all merge `LeafMetaFields`), the partner of `outputSchema`: when
|
|
707
|
-
* true, the materializer skips validating/stripping the output. It is
|
|
708
|
-
* consumed at build time and stored as a first-class plugin field, NOT folded
|
|
709
|
-
* into the projected meta (hence absent from `LEAF_META_KEYS`), so it stays
|
|
710
|
-
* off the registry / CLI / MCP surface, exactly like `skipInputValidation`. */
|
|
711
|
-
skipOutputValidation?: boolean;
|
|
712
|
-
packages?: string[];
|
|
713
|
-
stability?: StabilityLevel;
|
|
714
|
-
/** @deprecated Use `stability: "experimental"` instead. */
|
|
715
|
-
experimental?: boolean;
|
|
716
|
-
confirm?: "create-secret" | "delete";
|
|
717
|
-
deprecation?: FunctionDeprecation;
|
|
718
|
-
aliases?: Record<string, string>;
|
|
719
|
-
supportsJsonOutput?: boolean;
|
|
720
|
-
}
|
|
623
|
+
declare const STABILITY_LEVELS: readonly ["stable", "beta", "experimental"];
|
|
624
|
+
type StabilityLevel = (typeof STABILITY_LEVELS)[number];
|
|
721
625
|
/**
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
626
|
+
* Title-case display names for each level, for section-level badges in
|
|
627
|
+
* generated docs (e.g. `Code Workflows (Beta)`). Inline description
|
|
628
|
+
* labels go through {@link applyStabilityLabel} instead.
|
|
629
|
+
*/
|
|
630
|
+
declare const STABILITY_TITLES: {
|
|
631
|
+
readonly stable: "Stable";
|
|
632
|
+
readonly beta: "Beta";
|
|
633
|
+
readonly experimental: "Experimental";
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Normalize authored meta to a concrete level: absent means `"stable"`,
|
|
637
|
+
* and the deprecated `experimental: true` boolean means `"experimental"`.
|
|
638
|
+
* The registry projection runs every entry through this, so
|
|
639
|
+
* `FunctionRegistryEntry.stability` is always concrete and consumers
|
|
640
|
+
* never branch on `undefined`.
|
|
641
|
+
*
|
|
642
|
+
* The declared value can cross a JSON boundary from a hand-written
|
|
643
|
+
* plugin, so at runtime it may be any string. An unrecognized level
|
|
644
|
+
* clamps to `"experimental"` — the author declared the method not
|
|
645
|
+
* stable, and clamping keeps the raw string out of notices and labels.
|
|
646
|
+
* It doesn't throw because this also runs in the `getStability` live
|
|
647
|
+
* read on the call path, where a throw would break the observed call.
|
|
648
|
+
*/
|
|
649
|
+
declare function normalizeStability(meta: {
|
|
650
|
+
stability?: StabilityLevel;
|
|
651
|
+
experimental?: boolean;
|
|
652
|
+
}): StabilityLevel;
|
|
653
|
+
/**
|
|
654
|
+
* The shared label renderer: every consumer that renders a registry
|
|
655
|
+
* entry's description (CLI help, MCP tool descriptions) labels it
|
|
656
|
+
* through this function, so a new consumer cannot silently drop the
|
|
657
|
+
* label. `stability` stays structured data on the registry entry — the
|
|
658
|
+
* label is applied at render time, never baked into the stored
|
|
659
|
+
* description (docs badge at the section level, so baking it in would
|
|
660
|
+
* double-badge).
|
|
661
|
+
*
|
|
662
|
+
* The label follows the plugin's declared level, not the subpath that
|
|
663
|
+
* surfaced it: a beta method surfaced through an experimental-tier
|
|
664
|
+
* consumer still reads "(beta)".
|
|
665
|
+
*/
|
|
666
|
+
declare function applyStabilityLabel({ description, stability, placement, }: {
|
|
667
|
+
description: string;
|
|
668
|
+
/** Absent means stable (the value may arrive from outside the
|
|
669
|
+
* normalized registry projection, e.g. hand-built JSON). */
|
|
670
|
+
stability: StabilityLevel | undefined;
|
|
671
|
+
/**
|
|
672
|
+
* `"suffix"` renders `<description> (beta)` (CLI help);
|
|
673
|
+
* `"prefix"` renders `[Beta] <description>` (MCP tool descriptions,
|
|
674
|
+
* where the front of the string is what an LLM reads first).
|
|
675
|
+
*/
|
|
676
|
+
placement?: "suffix" | "prefix";
|
|
677
|
+
}): string;
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Declaration for a registry category (a bucket grouping related functions).
|
|
681
|
+
* Plugins reference categories in their `meta.categories` field, as either a
|
|
682
|
+
* bare key (auto-derive title and plural) or this object (override either).
|
|
683
|
+
*
|
|
684
|
+
* Examples (with auto-derive rules):
|
|
685
|
+
* - `{ key: "app" }` → title "App", plural "Apps"
|
|
686
|
+
* - `{ key: "client-credentials" }` → title "Client Credentials", plural "Client Credentials"
|
|
687
|
+
* - `{ key: "utility" }` → title "Utility", plural "Utilities"
|
|
688
|
+
* - `{ key: "http", title: "HTTP Request" }` → plural "HTTP Requests"
|
|
689
|
+
*/
|
|
690
|
+
interface CategoryDefinition {
|
|
691
|
+
key: string;
|
|
692
|
+
/** Display title for the category. Auto-derived from `key` if omitted. */
|
|
693
|
+
title?: string;
|
|
694
|
+
/** Plural form of `title`. Auto-derived from the resolved title if omitted. */
|
|
695
|
+
titlePlural?: string;
|
|
696
|
+
}
|
|
697
|
+
interface FunctionRegistryEntry {
|
|
698
|
+
name: string;
|
|
699
|
+
/**
|
|
700
|
+
* Human-readable description of the function. Surfaced wherever the
|
|
701
|
+
* registry is consumed (command help, tool/RPC descriptions, generated
|
|
702
|
+
* documentation). Prefer providing this directly rather than relying
|
|
703
|
+
* solely on inputSchema.describe().
|
|
704
|
+
*/
|
|
705
|
+
description?: string;
|
|
706
|
+
type?: "list" | "item" | "create" | "update" | "delete" | "function";
|
|
707
|
+
itemType?: string;
|
|
708
|
+
returnType?: string;
|
|
709
|
+
inputSchema?: z.ZodSchema;
|
|
710
|
+
/**
|
|
711
|
+
* When true, the method owns its input validation and its boundary passes the
|
|
712
|
+
* input through unparsed. The resolution controller reads this to skip its
|
|
713
|
+
* final `safeParse` (it still uses `inputSchema` to plan/prompt parameters),
|
|
714
|
+
* so a method routed through the controller isn't re-validated against a
|
|
715
|
+
* schema it deliberately opts out of. Lifted off the materialized entry.
|
|
716
|
+
*/
|
|
717
|
+
skipInputValidation?: boolean;
|
|
718
|
+
outputSchema?: z.ZodSchema;
|
|
719
|
+
/**
|
|
720
|
+
* Ordered input keys the public surface projects onto positional arguments
|
|
721
|
+
* (the method's `positional` declaration). Absent when the method takes only
|
|
722
|
+
* the canonical single bag. Lifted off the materialized method entry by the
|
|
723
|
+
* surface builder, like `resolvers` — a runtime projection, not
|
|
724
|
+
* descriptive meta.
|
|
725
|
+
*/
|
|
726
|
+
positional?: readonly string[];
|
|
727
|
+
categories: string[];
|
|
728
|
+
/**
|
|
729
|
+
* Per-parameter bound resolvers (imports already captured, called with
|
|
730
|
+
* `input` only, no sdk). Lifted off the materialized method entry by the
|
|
731
|
+
* surface builder.
|
|
732
|
+
*/
|
|
733
|
+
resolvers?: Record<string, BoundResolver>;
|
|
734
|
+
packages?: string[];
|
|
735
|
+
/**
|
|
736
|
+
* API stability tier of the plugin, normalized from `MethodMeta.stability`
|
|
737
|
+
* (absent means `"stable"`; the legacy `experimental: true` boolean means
|
|
738
|
+
* `"experimental"`). Always concrete here, so consumers never branch on
|
|
739
|
+
* `undefined`.
|
|
740
|
+
*/
|
|
741
|
+
stability: StabilityLevel;
|
|
742
|
+
/**
|
|
743
|
+
* @deprecated Read `stability` instead. Derived as
|
|
744
|
+
* `stability === "experimental"` — literal by name, so beta reads
|
|
745
|
+
* `false`; the not-stable warning duty lives in `stability` and the
|
|
746
|
+
* runtime stability notice.
|
|
747
|
+
*/
|
|
748
|
+
experimental?: boolean;
|
|
749
|
+
/** Confirmation prompt type - prompts user before executing */
|
|
750
|
+
confirm?: "create-secret" | "delete";
|
|
751
|
+
/**
|
|
752
|
+
* Optional deprecation metadata for commands.
|
|
753
|
+
*/
|
|
754
|
+
deprecation?: FunctionDeprecation;
|
|
755
|
+
/**
|
|
756
|
+
* Short aliases for parameter names (e.g., { request: "X", header: "H" }).
|
|
757
|
+
* Consumers that render the function as a flag-style command surface use
|
|
758
|
+
* these as short forms.
|
|
759
|
+
*/
|
|
760
|
+
aliases?: Record<string, string>;
|
|
761
|
+
/**
|
|
762
|
+
* Output formatter, normalized to the bound runtime shape (its imports
|
|
763
|
+
* already captured), so consumers call `getContext`/`format` with no sdk.
|
|
764
|
+
* The surface builder lifts this off the method entry, where `defineFormatter`
|
|
765
|
+
* bound it at materialization.
|
|
766
|
+
*/
|
|
767
|
+
formatter?: BoundFormatter;
|
|
768
|
+
/** Defaults to true. Set to false to suppress --json (e.g. login/logout/init). */
|
|
769
|
+
supportsJsonOutput: boolean;
|
|
770
|
+
}
|
|
771
|
+
interface FunctionDeprecation {
|
|
772
|
+
/** User-facing deprecation message for why/how to migrate */
|
|
773
|
+
message: string;
|
|
774
|
+
}
|
|
775
|
+
interface RegistryResult {
|
|
776
|
+
functions: FunctionRegistryEntry[];
|
|
777
|
+
categories: {
|
|
778
|
+
key: string;
|
|
779
|
+
title: string;
|
|
780
|
+
titlePlural: string;
|
|
781
|
+
functions: string[];
|
|
782
|
+
}[];
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* ------------------------------
|
|
787
|
+
* Plugin Metadata
|
|
788
|
+
* ------------------------------
|
|
789
|
+
*
|
|
790
|
+
* The description fields a method or property carries for the registry, the
|
|
791
|
+
* CLI, MCP, and the docs generators. An author sets them directly on a
|
|
792
|
+
* `defineMethod` / `defineProperty` config, the descriptor carries them as its
|
|
793
|
+
* own fields, a `defineOverride` patches a subset onto the entry, and the
|
|
794
|
+
* registry projection merges the two.
|
|
795
|
+
* Nothing here changes what a method does. The two schemas are not here: they
|
|
796
|
+
* drive typing and validation, so they are fields of the method itself.
|
|
797
|
+
*/
|
|
798
|
+
|
|
799
|
+
interface PropertyMeta {
|
|
800
|
+
/**
|
|
801
|
+
* Human-readable description. Used by the CLI (help text), MCP (tool
|
|
802
|
+
* description), and README generators. For a method, falls back to the
|
|
803
|
+
* inputSchema's `.describe()` value when omitted.
|
|
804
|
+
*/
|
|
805
|
+
description?: string;
|
|
806
|
+
/**
|
|
807
|
+
* Buckets this plugin belongs to in `getRegistry()` output. Each entry is
|
|
808
|
+
* either a bare key (`"app"`) for auto-derived titles or a {@link CategoryDefinition}
|
|
809
|
+
* object to override the title or plural. Only one plugin needs to supply
|
|
810
|
+
* the object form per category key; object refs win over string refs, so
|
|
811
|
+
* other plugins in the same bucket can stay on bare strings.
|
|
812
|
+
*/
|
|
813
|
+
categories?: (string | CategoryDefinition)[];
|
|
814
|
+
/** Which package surfaces (`"sdk"`, `"cli"`, `"mcp"`) include it. */
|
|
815
|
+
packages?: string[];
|
|
816
|
+
/**
|
|
817
|
+
* API stability tier this plugin belongs to. Absent means `"stable"`;
|
|
818
|
+
* the registry projection normalizes it, so registry consumers always
|
|
819
|
+
* read a concrete {@link StabilityLevel}. Wrappers keep non-stable
|
|
820
|
+
* plugins out of their stable build (by gating them behind a `beta` /
|
|
821
|
+
* `experimental` subpath import) and consumers badge the level in
|
|
822
|
+
* generated docs, CLI help, and MCP tool descriptions. No runtime
|
|
823
|
+
* capability check.
|
|
824
|
+
*/
|
|
825
|
+
stability?: StabilityLevel;
|
|
826
|
+
/**
|
|
827
|
+
* @deprecated Use `stability: "experimental"` instead. Kept as an
|
|
828
|
+
* input for external authors; `true` normalizes to
|
|
829
|
+
* `stability: "experimental"` in the registry projection.
|
|
830
|
+
*/
|
|
831
|
+
experimental?: boolean;
|
|
832
|
+
deprecation?: FunctionDeprecation;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* A method's description fields: everything a property has, plus what only a
|
|
836
|
+
* callable can carry. A `defineOverride` patches the safe subset of these, see
|
|
837
|
+
* `OverridableMetaFields`.
|
|
838
|
+
*/
|
|
839
|
+
interface MethodMeta extends PropertyMeta {
|
|
840
|
+
type?: "list" | "item" | "create" | "update" | "delete" | "function";
|
|
841
|
+
itemType?: string;
|
|
842
|
+
returnType?: string;
|
|
843
|
+
/** Confirmation prompt type - prompts user before executing */
|
|
844
|
+
confirm?: "create-secret" | "delete";
|
|
845
|
+
/** Parameter name to CLI flag name. */
|
|
846
|
+
aliases?: Record<string, string>;
|
|
847
|
+
supportsJsonOutput?: boolean;
|
|
848
|
+
}
|
|
849
|
+
/** @deprecated Use {@link MethodMeta} or {@link PropertyMeta}. */
|
|
850
|
+
type PluginMeta = MethodMeta;
|
|
851
|
+
|
|
852
|
+
/** @deprecated Use {@link MethodMeta} or {@link PropertyMeta}. */
|
|
853
|
+
type LeafMeta = MethodMeta;
|
|
854
|
+
/**
|
|
855
|
+
* The description fields an override may patch onto an already-built method.
|
|
856
|
+
* One list serves both sides: `defineOverride` refuses any other key at
|
|
857
|
+
* runtime, and `OverridableMetaFields` is derived from it, so the type and the
|
|
858
|
+
* runtime guard cannot drift.
|
|
859
|
+
*
|
|
860
|
+
* An allow-list, so a field added to {@link MethodMeta} later is refused
|
|
861
|
+
* until someone decides it is safe. Naming the dangerous fields instead would
|
|
862
|
+
* hand every future field to overrides by default, and the default has to be
|
|
863
|
+
* the safe one: an override changes how a surface PRESENTS a method, never what
|
|
864
|
+
* runs, what input is accepted, or what safety gate fires. Nothing re-checks
|
|
865
|
+
* the method's declared TypeScript type after `defineMethod` fixes it.
|
|
866
|
+
*
|
|
867
|
+
* What that rule rules out, and why each is dangerous rather than merely
|
|
868
|
+
* unused:
|
|
869
|
+
*
|
|
870
|
+
* - `confirm` gates a host's confirmation prompt. Patching it can drop the
|
|
871
|
+
* prompt in front of a destructive call.
|
|
738
872
|
* - `type` reaches `confirm` indirectly: the registry derives
|
|
739
873
|
* `confirm: m.confirm ?? (m.type === "delete" ? "delete" : undefined)`, so
|
|
740
874
|
* moving a method off `"delete"` removes the same prompt quietly.
|
|
741
875
|
* - `aliases` maps a parameter to a CLI flag, so patching it changes which
|
|
742
876
|
* input a caller can pass.
|
|
743
|
-
* - `skipOutputValidation` is already unreachable, being absent from
|
|
744
|
-
* `LEAF_META_KEYS` and never folded into the projected meta.
|
|
745
877
|
*/
|
|
746
|
-
|
|
878
|
+
declare const OVERRIDABLE_META_KEYS: readonly ["description", "categories", "itemType", "returnType", "packages", "experimental", "deprecation", "supportsJsonOutput"];
|
|
879
|
+
type OverridableMetaFields = Pick<MethodMeta, (typeof OVERRIDABLE_META_KEYS)[number]>;
|
|
747
880
|
/** One segment of a {@link DynamicMember} path: a literal binding/segment name,
|
|
748
881
|
* or a `{ param }` placeholder for an open-ended key (rendered `{param}`). */
|
|
749
882
|
type DynamicMemberSegment = string | {
|
|
@@ -754,22 +887,25 @@ type DynamicMemberSegment = string | {
|
|
|
754
887
|
* (e.g. `apps.{appKey}.{actionType}.{actionKey}`), backed at runtime by a proxy.
|
|
755
888
|
* It is a bodyless declaration — the same descriptive fields an author sets on a
|
|
756
889
|
* leaf, keyed by a `path` instead of a `name`. The framework derives the
|
|
757
|
-
* registry name by joining the path (params rendered `{param}`) and
|
|
758
|
-
* fields into
|
|
890
|
+
* registry name by joining the path (params rendered `{param}`) and projects
|
|
891
|
+
* these fields into the registry / CLI / MCP / docs like a method's.
|
|
759
892
|
* `path[0]` must be a literal that resolves to a real surfaced binding (the
|
|
760
893
|
* owning member).
|
|
761
894
|
*/
|
|
762
895
|
type DynamicMember = {
|
|
763
896
|
path: readonly DynamicMemberSegment[];
|
|
764
|
-
/** Projection-only
|
|
897
|
+
/** Projection-only schemas (no runtime; the proxy validates its own). */
|
|
765
898
|
inputSchema?: z.ZodType;
|
|
766
|
-
|
|
899
|
+
outputSchema?: z.ZodSchema;
|
|
900
|
+
} & MethodMeta;
|
|
767
901
|
/** A {@link DynamicMember} normalized at define time: the derived registry name,
|
|
768
|
-
* the literal root segment (validated against the surface), and
|
|
769
|
-
interface NormalizedDynamicMember {
|
|
902
|
+
* the literal root segment (validated against the surface), and its description. */
|
|
903
|
+
interface NormalizedDynamicMember extends MethodMeta {
|
|
770
904
|
name: string;
|
|
771
905
|
rootBinding: string;
|
|
772
|
-
|
|
906
|
+
/** Projection-only, like the schemas a method entry carries. */
|
|
907
|
+
inputSchema?: z.ZodType;
|
|
908
|
+
outputSchema?: z.ZodSchema;
|
|
773
909
|
}
|
|
774
910
|
type AnyMethodPlugin = MethodPlugin<string, any, any, readonly string[]>;
|
|
775
911
|
type AnyPropertyPlugin = PropertyPlugin<string, any>;
|
|
@@ -781,7 +917,7 @@ type AnyLeafPlugin = AnyMethodPlugin | AnyPropertyPlugin;
|
|
|
781
917
|
* `selectExports(...)` element contributes its chosen bindings. To rename or
|
|
782
918
|
* subset, wrap an element in `selectExports`; there is no alias-map form.
|
|
783
919
|
*/
|
|
784
|
-
type ImportsInput = readonly
|
|
920
|
+
type ImportsInput = readonly Plugin[];
|
|
785
921
|
/** A resolved import edge: the local binding name and the plugin id it reads
|
|
786
922
|
* from `context.plugins` (id, not identity, so a swap stays transparent). */
|
|
787
923
|
interface ImportBinding {
|
|
@@ -838,7 +974,7 @@ type SurfaceCall<TInput, TOutput, TPositional extends readonly string[]> = TPosi
|
|
|
838
974
|
* its own name (method callable or property value), an aggregate under each of
|
|
839
975
|
* its export names — exactly the dependency's {@link PluginSurface}.
|
|
840
976
|
*/
|
|
841
|
-
type BindingsOf<TDep extends
|
|
977
|
+
type BindingsOf<TDep extends Plugin> = PluginSurface<TDep>;
|
|
842
978
|
/**
|
|
843
979
|
* The `imports` a body receives. Each element contributes its bindings
|
|
844
980
|
* (`BindingsOf`); empty imports yield an empty object.
|
|
@@ -888,7 +1024,7 @@ type HookAnnotator<TState = unknown> = (bag: {
|
|
|
888
1024
|
/** Shared plumbing for the method attachments: each declares its own
|
|
889
1025
|
* dependencies. Resolvers and formatters are otherwise separate concepts. */
|
|
890
1026
|
interface MethodAttachment {
|
|
891
|
-
imports: readonly
|
|
1027
|
+
imports: readonly Plugin[];
|
|
892
1028
|
/** Binding-name to plugin-id edges, normalized from `imports`; what the
|
|
893
1029
|
* narrowed bag captured at materialization is built from. */
|
|
894
1030
|
importBindings: readonly ImportBinding[];
|
|
@@ -1261,29 +1397,43 @@ interface BoundFormatter<TItem = unknown, TInput = Record<string, unknown>, TCon
|
|
|
1261
1397
|
* `run` is loosely typed for `imports` (the precise type lives on the
|
|
1262
1398
|
* `defineMethod` authoring surface, like the shipped definePlugin).
|
|
1263
1399
|
*/
|
|
1264
|
-
|
|
1400
|
+
/** Every `pluginType` the model builds. */
|
|
1401
|
+
type PluginType = "method" | "property" | "aggregate" | "hook" | "method-override";
|
|
1265
1402
|
/**
|
|
1266
|
-
* What
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1269
|
-
* {@link CallOutputOptions} and {@link PaginatedCallInput}. Those are the
|
|
1270
|
-
* framework's, peeled off before `run`, so folding them into one parameter
|
|
1271
|
-
* told a consumer reading `Parameters<typeof plugin.run>[0]` that `run` gets
|
|
1272
|
-
* a flag the runtime always removes.
|
|
1273
|
-
*
|
|
1274
|
-
* Defaults to `TInput`, since raw's caller and `run` see the same object.
|
|
1403
|
+
* What every plugin descriptor carries, whatever its kind. `pluginType` is the
|
|
1404
|
+
* discriminant, and each kind narrows it. `imports` and `importBindings` are on
|
|
1405
|
+
* every kind so the graph walk treats them alike (an override's are empty).
|
|
1275
1406
|
*/
|
|
1276
|
-
|
|
1277
|
-
pluginType:
|
|
1407
|
+
interface PluginBase<TName extends string = string> {
|
|
1408
|
+
pluginType: PluginType;
|
|
1278
1409
|
name: TName;
|
|
1279
1410
|
namespace?: string;
|
|
1280
1411
|
/** `namespace/name`, or bare `name`. The `context.plugins` key. */
|
|
1281
1412
|
id: string;
|
|
1282
|
-
|
|
1413
|
+
imports: readonly Plugin[];
|
|
1414
|
+
/** Binding-name to plugin-id edges, normalized from `imports`; what the
|
|
1415
|
+
* `imports` bag is built from. */
|
|
1416
|
+
importBindings: readonly ImportBinding[];
|
|
1417
|
+
}
|
|
1418
|
+
/** `setup` runs once at build, dependencies first, and returns the plugin's
|
|
1419
|
+
* private state. `dispose` releases what it acquired, in reverse build order. */
|
|
1420
|
+
interface PluginLifecycle {
|
|
1421
|
+
setup?: (bag: {
|
|
1422
|
+
imports: Record<string, unknown>;
|
|
1423
|
+
}) => unknown;
|
|
1424
|
+
dispose?: DisposeFn;
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* A method or property. A `declare*` stand-in wears the same shape with no
|
|
1428
|
+
* implementation, and a `declareDefault` wrapper marks the fallback provider
|
|
1429
|
+
* for an id.
|
|
1430
|
+
*/
|
|
1431
|
+
interface LeafBase<TName extends string = string> extends PluginBase<TName>, PluginLifecycle {
|
|
1432
|
+
/** True for a `declare*` stand-in: a typed reference with no real
|
|
1283
1433
|
* implementation. A real plugin under the same id satisfies it. */
|
|
1284
1434
|
standIn?: boolean;
|
|
1285
|
-
/** True for a `
|
|
1286
|
-
*
|
|
1435
|
+
/** True for a `declareOptional*` stand-in: dependents bind `undefined` if no
|
|
1436
|
+
* real plugin satisfies it, and `PluginSurface` types the binding
|
|
1287
1437
|
* `| undefined`. */
|
|
1288
1438
|
optional?: boolean;
|
|
1289
1439
|
/** Present on a `declareDefault` wrapper: this entry is the DEFAULT provider
|
|
@@ -1291,34 +1441,37 @@ TRunInput = TInput> {
|
|
|
1291
1441
|
* plugin, so two defaults for one id dedup (same source) or conflict
|
|
1292
1442
|
* (different source). */
|
|
1293
1443
|
defaultSource?: AnyLeafPlugin;
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
/**
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
/**
|
|
1320
|
-
*
|
|
1321
|
-
|
|
1444
|
+
}
|
|
1445
|
+
interface MethodPlugin<TName extends string = string, TInput = unknown, TOutput = unknown, TPositional extends readonly string[] = readonly [],
|
|
1446
|
+
/**
|
|
1447
|
+
* What `run` receives, when that differs from what a CALLER may pass.
|
|
1448
|
+
*
|
|
1449
|
+
* They part company for item and list, whose call type mixes in
|
|
1450
|
+
* {@link CallOutputOptions} and {@link PaginatedCallInput}. Those are the
|
|
1451
|
+
* framework's, peeled off before `run`, so folding them into one parameter
|
|
1452
|
+
* told a consumer reading `Parameters<typeof plugin.run>[0]` that `run` gets
|
|
1453
|
+
* a flag the runtime always removes.
|
|
1454
|
+
*
|
|
1455
|
+
* Defaults to `TInput`, since raw's caller and `run` see the same object.
|
|
1456
|
+
*/
|
|
1457
|
+
TRunInput = TInput> extends LeafBase<TName>, MethodMeta {
|
|
1458
|
+
pluginType: "method";
|
|
1459
|
+
/** Validates `input` before `run` and drives the authoring `input` type. */
|
|
1460
|
+
inputSchema?: z.ZodType;
|
|
1461
|
+
/** When true, skip the runtime validation/parse of `input`: `run` receives the
|
|
1462
|
+
* raw input untouched — no coercion, stripping, or cloning — even if
|
|
1463
|
+
* `inputSchema` is set (the schema stays for registry / CLI / MCP projection).
|
|
1464
|
+
* For raw methods that own their own validation and must not have their input
|
|
1465
|
+
* transformed, e.g. `fetch` passing a `RequestInit` bag through unchanged. */
|
|
1466
|
+
skipInputValidation?: boolean;
|
|
1467
|
+
/** Validates and strips `run`'s output, and describes it for the registry. */
|
|
1468
|
+
outputSchema?: z.ZodSchema;
|
|
1469
|
+
/** When true, the materializer skips validating/stripping `run`'s output
|
|
1470
|
+
* against `outputSchema` (the schema stays for projection). The output
|
|
1471
|
+
* partner of {@link MethodPlugin.skipInputValidation}. */
|
|
1472
|
+
skipOutputValidation?: boolean;
|
|
1473
|
+
/** Descriptive metadata for the registry / CLI / MCP / docs (carry-only at
|
|
1474
|
+
* runtime). */
|
|
1322
1475
|
/** Per-parameter input resolvers (method attachments). Reached for
|
|
1323
1476
|
* materialization and bound into the entry at createSdk; a reachability-only
|
|
1324
1477
|
* edge whose imports never enter this method's `importBindings`. */
|
|
@@ -1427,11 +1580,11 @@ type CallOutputOptions = {
|
|
|
1427
1580
|
* list-standard overload: a raw envelope with extra keys is not a `StrictPage`
|
|
1428
1581
|
* and falls through to the adapted overload, where `adaptPage` is required.
|
|
1429
1582
|
*/
|
|
1430
|
-
type StrictPage
|
|
1583
|
+
type StrictPage<TResponse> = SdkPage<unknown> & {
|
|
1431
1584
|
[K in Exclude<keyof TResponse, keyof SdkPage<unknown>>]?: never;
|
|
1432
1585
|
};
|
|
1433
1586
|
/** Item type sourced from a page-ish response. */
|
|
1434
|
-
type ItemOf
|
|
1587
|
+
type ItemOf<TResponse> = TResponse extends SdkPage<infer TItem> ? TItem : TResponse extends {
|
|
1435
1588
|
data: readonly (infer TItem)[];
|
|
1436
1589
|
} ? TItem : never;
|
|
1437
1590
|
/**
|
|
@@ -1456,37 +1609,8 @@ type DataOf<TResponse> = TResponse extends {
|
|
|
1456
1609
|
* eagerly at createSdk (dependencies first, like a method's `setup`) to build
|
|
1457
1610
|
* that state. An imported/surfaced property yields the value, not a callable.
|
|
1458
1611
|
*/
|
|
1459
|
-
interface PropertyPlugin<TName extends string = string, TValue = unknown> {
|
|
1612
|
+
interface PropertyPlugin<TName extends string = string, TValue = unknown> extends LeafBase<TName>, PropertyMeta {
|
|
1460
1613
|
pluginType: "property";
|
|
1461
|
-
name: TName;
|
|
1462
|
-
namespace?: string;
|
|
1463
|
-
/** `namespace/name`, or bare `name`. The `context.plugins` key. */
|
|
1464
|
-
id: string;
|
|
1465
|
-
/** True for a `declareProperty` stand-in: a typed reference with no value. A
|
|
1466
|
-
* real property under the same id satisfies it. */
|
|
1467
|
-
standIn?: boolean;
|
|
1468
|
-
/** True for a `declareOptionalProperty` stand-in: an optional reference. If no real
|
|
1469
|
-
* property satisfies it, dependents bind `undefined` rather than the build
|
|
1470
|
-
* failing on a missing dependency. */
|
|
1471
|
-
optional?: boolean;
|
|
1472
|
-
/** Present on a `declareDefault` wrapper: this entry is the DEFAULT provider
|
|
1473
|
-
* for its id (preempted by any explicit provider). Its value is the wrapped
|
|
1474
|
-
* plugin, so two defaults for one id dedup (same source) or conflict
|
|
1475
|
-
* (different source). */
|
|
1476
|
-
defaultSource?: AnyLeafPlugin;
|
|
1477
|
-
imports: readonly AnyPlugin[];
|
|
1478
|
-
/** Binding-name to plugin-id edges, normalized from `imports`;
|
|
1479
|
-
* what the `imports` bag is built from. */
|
|
1480
|
-
importBindings: readonly ImportBinding[];
|
|
1481
|
-
/** Optional once-eager constructor (the property twin of a method's `setup`):
|
|
1482
|
-
* runs once at createSdk (dependencies first), may side-effect, and returns the
|
|
1483
|
-
* private state delivered to `get` as `bag.state`. */
|
|
1484
|
-
setup?: (bag: {
|
|
1485
|
-
imports: Record<string, unknown>;
|
|
1486
|
-
}) => unknown;
|
|
1487
|
-
/** `setup`'s dual: releases what setup acquired. Run by `disposeSdk` in
|
|
1488
|
-
* reverse dependency order. */
|
|
1489
|
-
dispose?: DisposeFn;
|
|
1490
1614
|
value?: TValue;
|
|
1491
1615
|
/** A live getter: computes the value from imports and `setup` state on each
|
|
1492
1616
|
* read (not once). The stored shape is loose; the precise typing lives on the
|
|
@@ -1496,8 +1620,6 @@ interface PropertyPlugin<TName extends string = string, TValue = unknown> {
|
|
|
1496
1620
|
state: unknown;
|
|
1497
1621
|
callContext?: CallContext;
|
|
1498
1622
|
}) => TValue;
|
|
1499
|
-
/** Descriptive metadata for the registry / CLI / MCP / docs (carry-only). */
|
|
1500
|
-
meta?: LeafMeta;
|
|
1501
1623
|
/** Templated registry members for this property's dynamic sub-surface (e.g. a
|
|
1502
1624
|
* proxy). Carry-only: normalized at define time, folded into the registry. */
|
|
1503
1625
|
dynamicMembers?: readonly NormalizedDynamicMember[];
|
|
@@ -1536,6 +1658,21 @@ type MiddlewareMap<TImports, TState = unknown> = {
|
|
|
1536
1658
|
state: TState;
|
|
1537
1659
|
}) => TOutput : never;
|
|
1538
1660
|
};
|
|
1661
|
+
/**
|
|
1662
|
+
* An aggregate plugin: it re-exports child plugins under binding names. Has no
|
|
1663
|
+
* body of its own; composition is "declare what to re-export".
|
|
1664
|
+
* `exports` keys are binding names; re-exporting a child implies a dependency
|
|
1665
|
+
* on it (it is pulled into the graph). `imports` lists extra internal
|
|
1666
|
+
* plugins to materialize that are not re-exported. `middleware` wraps imported
|
|
1667
|
+
* methods, keyed by the target's binding name.
|
|
1668
|
+
*/
|
|
1669
|
+
/**
|
|
1670
|
+
* How a module declares its `exports`: an array, mirroring {@link ImportsInput}. A
|
|
1671
|
+
* leaf binds under its own `name`; a module (or `selectExports(...)`)
|
|
1672
|
+
* contributes each of its export bindings (spread). A binding-name collision
|
|
1673
|
+
* throws (wrap one in `selectExports` to rename).
|
|
1674
|
+
*/
|
|
1675
|
+
type ExportsInput = readonly (AnyLeafPlugin | AnyAggregatePlugin)[];
|
|
1539
1676
|
/** The export record one array element contributes: a leaf under its own name,
|
|
1540
1677
|
* a module under each of its export bindings. */
|
|
1541
1678
|
type ElementExports<E> = E extends MethodPlugin<infer N, any, any, any> ? {
|
|
@@ -1550,49 +1687,36 @@ type ElementExports<E> = E extends MethodPlugin<infer N, any, any, any> ? {
|
|
|
1550
1687
|
type ArrayExports<T extends readonly (AnyLeafPlugin | AnyAggregatePlugin)[]> = T extends readonly [] ? Record<never, never> : UnionToIntersection<{
|
|
1551
1688
|
[I in keyof T]: ElementExports<T[I]>;
|
|
1552
1689
|
}[number]>;
|
|
1553
|
-
|
|
1690
|
+
/**
|
|
1691
|
+
* Coerce a computed export record to the shape {@link AggregatePlugin} requires.
|
|
1692
|
+
* `ArrayExports` folds with `UnionToIntersection`, whose result the checker
|
|
1693
|
+
* cannot prove satisfies the constraint, so name the fallback rather than
|
|
1694
|
+
* asserting at each use.
|
|
1695
|
+
*/
|
|
1696
|
+
type AsExports<T> = T extends Record<string, AnyLeafPlugin> ? T : Record<string, AnyLeafPlugin>;
|
|
1697
|
+
/**
|
|
1698
|
+
* Reject an `exports` entry that is not a plugin: identity in the good case, an
|
|
1699
|
+
* error brand in the bad case. A deferred conditional rather than a constraint
|
|
1700
|
+
* on the type parameter, because a plugin-shaped constraint contextually types
|
|
1701
|
+
* the array literal and an inline `define*` call then infers `input` as `any`.
|
|
1702
|
+
* `declarePlugin`'s `exports` and every `imports` still carry the constraint;
|
|
1703
|
+
* move them here when something writes an inline `define*` there.
|
|
1704
|
+
*/
|
|
1705
|
+
type PluginList<T extends readonly unknown[]> = Exclude<T[number], AnyLeafPlugin | AnyAggregatePlugin> extends never ? unknown : {
|
|
1706
|
+
readonly __kitcoreError: "every exports entry must be a plugin built by define*, declare*, selectExports, or omitExports";
|
|
1707
|
+
};
|
|
1708
|
+
interface AggregatePlugin<TName extends string = string, TExports extends Record<string, AnyLeafPlugin> = Record<string, AnyLeafPlugin>> extends PluginBase<TName> {
|
|
1554
1709
|
pluginType: "aggregate";
|
|
1555
|
-
name: TName;
|
|
1556
|
-
namespace?: string;
|
|
1557
|
-
/** `namespace/name`, or bare `name`. The `context.plugins` key. */
|
|
1558
|
-
id: string;
|
|
1559
1710
|
/** True for a `declarePlugin` stand-in: a typed reference to a whole module
|
|
1560
1711
|
* with no implementation. A real aggregate under the same id satisfies it. */
|
|
1561
1712
|
standIn?: boolean;
|
|
1562
|
-
imports: readonly AnyPlugin[];
|
|
1563
|
-
/** Binding-name to plugin-id edges, normalized from `imports`; what a
|
|
1564
|
-
* wrap's `imports` is built from, and how a wrap target
|
|
1565
|
-
* binding resolves to a method id. */
|
|
1566
|
-
importBindings: readonly ImportBinding[];
|
|
1567
1713
|
exports: TExports;
|
|
1568
1714
|
}
|
|
1569
1715
|
type AnyAggregatePlugin = AggregatePlugin<string, Record<string, any>>;
|
|
1570
|
-
/**
|
|
1571
|
-
* A legacy bridge plugin: wraps an old function plugin
|
|
1572
|
-
* (`(sdk) => provides`) so it materializes inside the new graph. At
|
|
1573
|
-
* materialization it runs `run` against a live compat view, merges the
|
|
1574
|
-
* returned context contributions into the shared `SdkContext`, and synthesizes
|
|
1575
|
-
* a `context.plugins` entry per root key. `TSurface` is the surfaced shape (the
|
|
1576
|
-
* provides minus `context`). This is the single shape `createPluginStack()
|
|
1577
|
-
* .toPlugin()` emits; there is no separate interim definition format.
|
|
1578
|
-
*/
|
|
1579
|
-
interface LegacyPlugin<TSurface = Record<string, unknown>> {
|
|
1580
|
-
pluginType: "legacy";
|
|
1581
|
-
name: string;
|
|
1582
|
-
namespace?: string;
|
|
1583
|
-
/** `namespace/name`, or bare `name`. The `context.plugins` key. */
|
|
1584
|
-
id: string;
|
|
1585
|
-
imports: readonly AnyPlugin[];
|
|
1586
|
-
importBindings: readonly ImportBinding[];
|
|
1587
|
-
run: (sdk: any) => PluginProvides;
|
|
1588
|
-
/** Type-only carrier for the surfaced shape; never set at runtime. */
|
|
1589
|
-
readonly __surface?: TSurface;
|
|
1590
|
-
}
|
|
1591
|
-
type AnyLegacyPlugin = LegacyPlugin<any>;
|
|
1592
1716
|
/**
|
|
1593
1717
|
* A patch over an already-defined method's descriptive fields. It carries no
|
|
1594
1718
|
* `run`: it names an existing method by id (`target`) and, after that method
|
|
1595
|
-
* materializes, merges its `meta` (the same public {@link
|
|
1719
|
+
* materializes, merges its `meta` (the same public {@link MethodMeta} an
|
|
1596
1720
|
* author sets on `defineMethod`) onto the method's entry, so the surface
|
|
1597
1721
|
* registry / CLI / MCP / docs project the patched values. For surface-specific
|
|
1598
1722
|
* tweaks a base method should not carry (e.g. a CLI that deprecates `fetch`
|
|
@@ -1602,16 +1726,13 @@ type AnyLegacyPlugin = LegacyPlugin<any>;
|
|
|
1602
1726
|
* swaps the whole implementation and forces re-declaring `run`. An override
|
|
1603
1727
|
* inherits the target's implementation untouched and only patches meta.
|
|
1604
1728
|
*/
|
|
1605
|
-
interface MethodOverridePlugin {
|
|
1729
|
+
interface MethodOverridePlugin extends PluginBase {
|
|
1606
1730
|
pluginType: "method-override";
|
|
1607
|
-
name: string;
|
|
1608
|
-
id: string;
|
|
1609
1731
|
/** The id of the method whose meta is patched (its bare name if the method is
|
|
1610
1732
|
* namespace-less). */
|
|
1611
1733
|
target: string;
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
meta?: LeafMeta;
|
|
1734
|
+
/** The description fields this override sets on its target. */
|
|
1735
|
+
patch: OverridableMetaFields;
|
|
1615
1736
|
}
|
|
1616
1737
|
/**
|
|
1617
1738
|
* A method-lifecycle hook leaf (`defineHook`). `observe` contributes
|
|
@@ -1621,22 +1742,10 @@ interface MethodOverridePlugin {
|
|
|
1621
1742
|
* (e.g. a telemetry queue), delivered to the observers.
|
|
1622
1743
|
* Each observer bag mirrors a method's: `{ imports, input, state }` — `input` is
|
|
1623
1744
|
* the lifecycle context, and there is no `next` (observers don't participate in
|
|
1624
|
-
* the call).
|
|
1625
|
-
* `context.hooks`.
|
|
1745
|
+
* the call).
|
|
1626
1746
|
*/
|
|
1627
|
-
interface HookPlugin<TName extends string = string> {
|
|
1747
|
+
interface HookPlugin<TName extends string = string> extends PluginBase<TName>, PluginLifecycle {
|
|
1628
1748
|
pluginType: "hook";
|
|
1629
|
-
name: TName;
|
|
1630
|
-
namespace?: string;
|
|
1631
|
-
id: string;
|
|
1632
|
-
imports: readonly AnyPlugin[];
|
|
1633
|
-
importBindings: readonly ImportBinding[];
|
|
1634
|
-
setup?: (bag: {
|
|
1635
|
-
imports: any;
|
|
1636
|
-
}) => unknown;
|
|
1637
|
-
/** `setup`'s dual: releases what setup acquired. Run by `disposeSdk` in
|
|
1638
|
-
* reverse dependency order. */
|
|
1639
|
-
dispose?: DisposeFn;
|
|
1640
1749
|
/** Contract-preserving wraps around imported methods (the middleware onion,
|
|
1641
1750
|
* folded dependents-outermost in topological order). Keyed by the target's
|
|
1642
1751
|
* binding among this hook's `imports`. */
|
|
@@ -1657,30 +1766,13 @@ interface HookPlugin<TName extends string = string> {
|
|
|
1657
1766
|
* bag before `onMethodStart`. Coexists with other hooks' annotators. */
|
|
1658
1767
|
annotator?: HookAnnotator;
|
|
1659
1768
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
*
|
|
1663
|
-
*
|
|
1664
|
-
*
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
* aggregate, so each migration only edits that aggregate's exports, not the
|
|
1668
|
-
* heads. Deleted once every plugin is module-model.
|
|
1669
|
-
*/
|
|
1670
|
-
interface LegacyMergePlugin<TProvides extends PluginProvides = PluginProvides, TPlugin extends AnyPlugin = AnyPlugin> {
|
|
1671
|
-
pluginType: "legacy-merge";
|
|
1672
|
-
name: string;
|
|
1673
|
-
namespace?: string;
|
|
1674
|
-
id: string;
|
|
1675
|
-
/** The lifted legacy stack (one node). */
|
|
1676
|
-
legacy: LegacyPlugin<TProvides & {
|
|
1677
|
-
getRegistry: (options?: {
|
|
1678
|
-
package?: string;
|
|
1679
|
-
}) => RegistryResult;
|
|
1680
|
-
}>;
|
|
1681
|
-
/** The module-model plugins migrated off the legacy stack. */
|
|
1682
|
-
plugin: TPlugin;
|
|
1683
|
-
}
|
|
1769
|
+
/**
|
|
1770
|
+
* A plugin: the descriptor any `define*` call returns, what `createSdk` builds
|
|
1771
|
+
* and `addPlugin` adds, and the type a host gives a slot that accepts plugins.
|
|
1772
|
+
* A `declare*` stand-in matches structurally, so both entry points refuse one
|
|
1773
|
+
* by name at runtime.
|
|
1774
|
+
*/
|
|
1775
|
+
type Plugin = AnyLeafPlugin | AnyAggregatePlugin | HookPlugin | MethodOverridePlugin;
|
|
1684
1776
|
/** One middleware layer on a method's chain: the wrap and its owning hook
|
|
1685
1777
|
* (whose `imports` the wrap receives, built live at call time). */
|
|
1686
1778
|
interface MiddlewareWrap {
|
|
@@ -1689,25 +1781,33 @@ interface MiddlewareWrap {
|
|
|
1689
1781
|
}
|
|
1690
1782
|
/** A materialized method: a stable callable `value` that folds `chain` around
|
|
1691
1783
|
* the core at call time. The chain is ordered dependents-outermost; it is
|
|
1692
|
-
* mutable so post-seal `addPlugin` middleware can append.
|
|
1693
|
-
|
|
1784
|
+
* mutable so post-seal `addPlugin` middleware can append.
|
|
1785
|
+
*
|
|
1786
|
+
* The description fields are copied off the descriptor at build, like the
|
|
1787
|
+
* runtime fields, and a `defineOverride` writes into them. `descriptor` keeps
|
|
1788
|
+
* what the author wrote. */
|
|
1789
|
+
interface MethodEntry extends MethodMeta {
|
|
1694
1790
|
pluginType: "method";
|
|
1695
1791
|
name: string;
|
|
1792
|
+
/** The plugin object this entry was built from. Identity for `addPlugin`:
|
|
1793
|
+
* re-adding this object is a no-op, a different object under the same id is
|
|
1794
|
+
* refused. */
|
|
1795
|
+
descriptor: AnyMethodPlugin;
|
|
1696
1796
|
value: (input: any) => any;
|
|
1697
1797
|
/** The import-facing twin of `value`: the same boundary, called with the
|
|
1698
1798
|
* internal-call sentinel so surface-only concerns (the deprecation signal)
|
|
1699
1799
|
* don't fire when a sibling plugin delegates. `buildImports` and
|
|
1700
|
-
* `resolvePlugin` bind this
|
|
1701
|
-
*
|
|
1702
|
-
internalValue
|
|
1800
|
+
* `resolvePlugin` bind this through `bindInternal`; the surface and registry
|
|
1801
|
+
* bind `value`. */
|
|
1802
|
+
internalValue: (input: any) => any;
|
|
1703
1803
|
/** Produce the import-facing twin for a given call context: with a context,
|
|
1704
1804
|
* the twin mints a fresh child per invocation (callee inherits `callId`, its
|
|
1705
1805
|
* origin, and sits one level deeper); without one it is parent-less — the
|
|
1706
1806
|
* surface-origin `internalValue` by default, or a framework-internal root when
|
|
1707
1807
|
* `frameworkOrigin` is set (kitcore's own build-time passes request it, so
|
|
1708
1808
|
* their delegated calls can be dropped from telemetry). `buildImports` binds
|
|
1709
|
-
* this.
|
|
1710
|
-
bindInternal
|
|
1809
|
+
* this. */
|
|
1810
|
+
bindInternal: (opts: {
|
|
1711
1811
|
ctx?: CallContext;
|
|
1712
1812
|
frameworkOrigin?: boolean;
|
|
1713
1813
|
}) => (...args: any[]) => any;
|
|
@@ -1718,7 +1818,9 @@ interface MethodEntry {
|
|
|
1718
1818
|
* through unparsed; carried so the controller skips its final `safeParse` too
|
|
1719
1819
|
* (it still uses `inputSchema` to plan/prompt parameters). */
|
|
1720
1820
|
skipInputValidation?: boolean;
|
|
1721
|
-
|
|
1821
|
+
/** Carried from the descriptor: validates the output, and the registry
|
|
1822
|
+
* projects it. */
|
|
1823
|
+
outputSchema?: z.ZodSchema;
|
|
1722
1824
|
/** Resolved output mode; the registry derives presentation from it. */
|
|
1723
1825
|
output?: NormalizedOutput;
|
|
1724
1826
|
/** Positional input projection (see Output): ordered canonical-input keys the
|
|
@@ -1733,16 +1835,16 @@ interface MethodEntry {
|
|
|
1733
1835
|
/** A materialized property: a static `value`, or a live `getValue` thunk that
|
|
1734
1836
|
* re-derives the value per read (consumers install it as a getter on the surface
|
|
1735
1837
|
* and on `imports`). Exactly one of `value` / `getValue` is set. */
|
|
1736
|
-
interface PropertyEntry {
|
|
1838
|
+
interface PropertyEntry extends PropertyMeta {
|
|
1737
1839
|
pluginType: "property";
|
|
1738
1840
|
name: string;
|
|
1841
|
+
descriptor: AnyPropertyPlugin;
|
|
1739
1842
|
value?: any;
|
|
1740
1843
|
/** Re-derives the value per read. Receives the live per-call `CallContext`
|
|
1741
1844
|
* when installed on a method's `imports` bag with a threaded context, and
|
|
1742
1845
|
* nothing on a surface / build-time read. */
|
|
1743
1846
|
getValue?: (callContext?: CallContext) => any;
|
|
1744
1847
|
/** Carried from the descriptor for the registry / CLI / MCP / docs. */
|
|
1745
|
-
meta?: LeafMeta;
|
|
1746
1848
|
/** Carried from the descriptor: templated registry members for this
|
|
1747
1849
|
* property's dynamic sub-surface (folded into the registry by getRegistry). */
|
|
1748
1850
|
dynamicMembers?: readonly NormalizedDynamicMember[];
|
|
@@ -1752,27 +1854,42 @@ interface PropertyEntry {
|
|
|
1752
1854
|
interface AggregateEntry {
|
|
1753
1855
|
pluginType: "aggregate";
|
|
1754
1856
|
name: string;
|
|
1857
|
+
descriptor: AnyAggregatePlugin;
|
|
1755
1858
|
exports: Record<string, any>;
|
|
1756
1859
|
}
|
|
1757
|
-
/**
|
|
1758
|
-
*
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
*
|
|
1767
|
-
|
|
1768
|
-
|
|
1860
|
+
/** A materialized hook. It has no value: its wraps sit on other methods'
|
|
1861
|
+
* chains and its observers in `context.hooks`. The entry records that the
|
|
1862
|
+
* hook is in the graph. */
|
|
1863
|
+
interface HookEntry {
|
|
1864
|
+
pluginType: "hook";
|
|
1865
|
+
name: string;
|
|
1866
|
+
descriptor: HookPlugin;
|
|
1867
|
+
}
|
|
1868
|
+
/** A materialized `defineOverride`. No value: its patch is on the target
|
|
1869
|
+
* method's `meta`. The entry records that the override is in the graph. */
|
|
1870
|
+
interface OverrideEntry {
|
|
1871
|
+
pluginType: "method-override";
|
|
1872
|
+
name: string;
|
|
1873
|
+
descriptor: MethodOverridePlugin;
|
|
1874
|
+
}
|
|
1875
|
+
/** An entry in `context.plugins`, one per plugin in the graph. A method's
|
|
1876
|
+
* `value` is its callable, a property's its value, an aggregate's `exports`
|
|
1877
|
+
* its bindings. A hook and an override have no value. */
|
|
1878
|
+
type PluginEntry = MethodEntry | PropertyEntry | AggregateEntry | HookEntry | OverrideEntry;
|
|
1879
|
+
/**
|
|
1880
|
+
* The materialization substrate: every reachable plugin keyed by id, plus the
|
|
1881
|
+
* ambient state the method boundary reads. Exhaustive, with no index signature:
|
|
1882
|
+
* a plugin keeps its state in `setup` and reads values through `imports`.
|
|
1769
1883
|
*/
|
|
1770
1884
|
interface SdkContext {
|
|
1885
|
+
/** Every reachable plugin by id. Created with `Object.create(null)`, as is
|
|
1886
|
+
* `surface`, because the keys are names an author chose: on a `{}` a lookup
|
|
1887
|
+
* of `"toString"` finds `Object.prototype.toString` and a `"__proto__"` write
|
|
1888
|
+
* replaces the prototype instead of adding a key. */
|
|
1771
1889
|
plugins: Record<string, PluginEntry>;
|
|
1772
|
-
meta: Record<string, PluginMeta>;
|
|
1773
1890
|
hooks: MethodHooks;
|
|
1774
1891
|
/** The SDK surface: each callable/value binding name mapped to the leaf plugin
|
|
1775
|
-
* id it resolves to. This is what the consumer actually calls (the root's
|
|
1892
|
+
* id it resolves to. No prototype, for the reason given on `plugins`. This is what the consumer actually calls (the root's
|
|
1776
1893
|
* re-exports plus `addPlugin` additions), so the registry reports entries by
|
|
1777
1894
|
* binding (with meta from the leaf) rather than dumping `plugins` by id. An
|
|
1778
1895
|
* aliased re-export (`{ hi: greet }`) appears here as `hi -> "greet"`. */
|
|
@@ -1783,7 +1900,6 @@ interface SdkContext {
|
|
|
1783
1900
|
/** The first `disposeSdk` call's settled result; later calls return it
|
|
1784
1901
|
* (idempotent, first input wins). */
|
|
1785
1902
|
disposed?: Promise<void>;
|
|
1786
|
-
[key: string]: any;
|
|
1787
1903
|
}
|
|
1788
1904
|
/** One leaf's recorded teardown: built at materialization (closing over the
|
|
1789
1905
|
* leaf's imports + setup state), run by `disposeSdk`. */
|
|
@@ -1810,16 +1926,15 @@ type AggregateBindings<TExports extends Record<string, AnyLeafPlugin>> = {
|
|
|
1810
1926
|
* The SDK surface a plugin contributes, derived from its descriptor: a
|
|
1811
1927
|
* method's callable or a property's value under its name, or an aggregate's
|
|
1812
1928
|
* export bindings. No `SdkInternals` — this is the plugin's own slice, not a
|
|
1813
|
-
* whole SDK.
|
|
1814
|
-
*
|
|
1929
|
+
* whole SDK. Derive a package's provides type from it rather than hand-writing
|
|
1930
|
+
* the shape:
|
|
1815
1931
|
*
|
|
1816
1932
|
* export type ListAppsPluginProvides = PluginSurface<typeof listAppsPlugin>;
|
|
1817
1933
|
*
|
|
1818
|
-
* "Surface", not "Provides": `
|
|
1819
|
-
*
|
|
1820
|
-
* different concepts.
|
|
1934
|
+
* "Surface", not "Provides": `ProvidesOf` already names the completeness
|
|
1935
|
+
* ledger's phantom ids, which is a different concept.
|
|
1821
1936
|
*/
|
|
1822
|
-
type PluginSurface<P extends
|
|
1937
|
+
type PluginSurface<P extends Plugin> = P extends MethodPlugin<infer TName, infer TInput, infer TOutput, infer TPositional> ? P extends {
|
|
1823
1938
|
optional: true;
|
|
1824
1939
|
} ? {
|
|
1825
1940
|
[K in TName]: SurfaceCall<TInput, TOutput, TPositional> | undefined;
|
|
@@ -1851,7 +1966,7 @@ type SdkInternals = {
|
|
|
1851
1966
|
* The materialized SDK for a leaf root: the root's callable (method) or value
|
|
1852
1967
|
* (property) under its name, plus framework access.
|
|
1853
1968
|
*/
|
|
1854
|
-
type Sdk
|
|
1969
|
+
type Sdk<TName extends string, TInput, TOutput, TPositional extends readonly string[] = readonly []> = {
|
|
1855
1970
|
[K in TName]: SurfaceCall<TInput, TOutput, TPositional>;
|
|
1856
1971
|
} & SdkInternals;
|
|
1857
1972
|
/** The materialized SDK for a property root: the value under its name. */
|
|
@@ -1866,12 +1981,11 @@ type PropertySdk<TName extends string, TValue> = {
|
|
|
1866
1981
|
type AggregateSdk<TExports extends Record<string, AnyLeafPlugin>> = AggregateBindings<TExports> & SdkInternals;
|
|
1867
1982
|
/**
|
|
1868
1983
|
* The surface a plugin adds to an SDK when passed to `addPlugin`: a method
|
|
1869
|
-
* under its name, a property's value, an aggregate's export bindings
|
|
1870
|
-
* legacy function plugin's root provides (minus `context`).
|
|
1984
|
+
* under its name, a property's value, or an aggregate's export bindings.
|
|
1871
1985
|
*/
|
|
1872
|
-
type AddedSurface<P> = [P] extends [
|
|
1986
|
+
type AddedSurface<P> = [P] extends [Plugin] ? [
|
|
1873
1987
|
PluginSurface<P>
|
|
1874
|
-
] extends [never] ? Record<never, never> : PluginSurface<P> :
|
|
1988
|
+
] extends [never] ? Record<never, never> : PluginSurface<P> : Record<never, never>;
|
|
1875
1989
|
/** `T` when it is a specific string literal, else `never`. Used on a stand-in's
|
|
1876
1990
|
* `name` so the id is always captured as a literal: a widened `string` (or the
|
|
1877
1991
|
* stale `declareMethod<TInput, TOutput>(...)` call shape, where the contract
|
|
@@ -1958,7 +2072,7 @@ type RequiresOf<P> = P extends {
|
|
|
1958
2072
|
readonly [REQUIRES]?: infer R;
|
|
1959
2073
|
} ? Extract<R, string> : never;
|
|
1960
2074
|
/** The ids a plugin and its subgraph provide (reads the phantom carrier). */
|
|
1961
|
-
type ProvidesOf
|
|
2075
|
+
type ProvidesOf<P> = P extends {
|
|
1962
2076
|
readonly [PROVIDES]?: infer R;
|
|
1963
2077
|
} ? Extract<R, string> : never;
|
|
1964
2078
|
/** The contracts a plugin's subgraph declared (reads the phantom carrier). */
|
|
@@ -1971,7 +2085,7 @@ type ProvidedContractsOf<P> = P extends {
|
|
|
1971
2085
|
} ? Extract<C, ContractEntry> : never;
|
|
1972
2086
|
/** Union the requires / provides across an inline imports or exports tuple. */
|
|
1973
2087
|
type RequiresIn<T extends readonly unknown[]> = RequiresOf<T[number]>;
|
|
1974
|
-
type ProvidesIn<T extends readonly unknown[]> = ProvidesOf
|
|
2088
|
+
type ProvidesIn<T extends readonly unknown[]> = ProvidesOf<T[number]>;
|
|
1975
2089
|
/** Union the contracts across an inline imports or exports tuple. */
|
|
1976
2090
|
type RequiredContractsIn<T extends readonly unknown[]> = RequiredContractsOf<T[number]>;
|
|
1977
2091
|
type ProvidedContractsIn<T extends readonly unknown[]> = ProvidedContractsOf<T[number]>;
|
|
@@ -1986,753 +2100,182 @@ type StaticList<T extends readonly unknown[]> = number extends T["length"] ? {
|
|
|
1986
2100
|
readonly __kitcoreError: "must be a fixed inline list of plugins, not a widened Plugin[]; declare them inline so the dependency graph stays statically known";
|
|
1987
2101
|
} : T;
|
|
1988
2102
|
/** A plugin's id as a type: `namespace/name`, or bare `name` when the namespace
|
|
1989
|
-
* is empty. The ledger keys on this (matching runtime id resolution), not the
|
|
1990
|
-
* bare name, so same-named plugins in different namespaces stay distinct. */
|
|
1991
|
-
type IdOf<TNamespace extends string, TName extends string> = TNamespace extends "" ? TName : `${TNamespace}/${TName}`;
|
|
1992
|
-
/** The binding name of an id: its last `/`-separated segment. The inverse view
|
|
1993
|
-
* of `IdOf`, used by `declare*` to derive the bare binding from a full id. */
|
|
1994
|
-
type LastSegment<TId extends string> = TId extends `${string}/${infer Rest}` ? LastSegment<Rest> : TId;
|
|
1995
|
-
/**
|
|
1996
|
-
* The `PluginSummary` a leaf carries, keyed on its full id. `TBinding` is the
|
|
1997
|
-
* surfaced binding the leaf implements (its call signature or its value).
|
|
1998
|
-
*
|
|
1999
|
-
* `TBinding` is REQUIRED, deliberately. Defaulting it to `never` would make a
|
|
2000
|
-
* three-argument annotation contribute no contract, so a hand-written
|
|
2001
|
-
* annotation would keep compiling and silently drop the leaf out of the
|
|
2002
|
-
* compatibility check.
|
|
2003
|
-
* A missing argument is a compile error instead.
|
|
2004
|
-
*/
|
|
2005
|
-
type LeafSummary<TNamespace extends string, TName extends string, TImports extends readonly unknown[], TBinding> = LeafSummaryById<IdOf<TNamespace, TName>, TImports, TBinding>;
|
|
2006
|
-
/** {@link LeafSummary} for a leaf whose full id is already known rather than
|
|
2007
|
-
* composed from a namespace and a name, which is what the by-reference
|
|
2008
|
-
* `define*(ref, config)` forms have: the id comes off the stand-in. */
|
|
2009
|
-
type LeafSummaryById<TId extends string, TImports extends readonly unknown[], TBinding> = LeafSummaryOf<TId, RequiresIn<TImports>, ProvidesIn<TImports>, RequiredContractsIn<TImports>, ProvidedContractsIn<TImports>, TBinding>;
|
|
2010
|
-
/**
|
|
2011
|
-
* {@link LeafSummaryById} with each import ledger already read, so it is read
|
|
2012
|
-
* ONCE per leaf. See the rule on {@link AggregateSummaryOf}.
|
|
2013
|
-
*/
|
|
2014
|
-
type LeafSummaryOf<TId extends string, TRequires extends string, TProvides extends string, TRequiredContracts extends ContractEntry, TProvidedContracts extends ContractEntry, TBinding> = PluginSummary<Exclude<TRequires, TId | TProvides>, TId | TProvides, TRequiredContracts, ContractEntry<TId, TBinding> | TProvidedContracts>;
|
|
2015
|
-
/**
|
|
2016
|
-
* The `PluginSummary` an aggregate carries, keyed on its full id.
|
|
2017
|
-
*
|
|
2018
|
-
* It contributes no contract for its own id. A module's contract IS its
|
|
2019
|
-
* exports, and each export already carries one keyed by its own id, so
|
|
2020
|
-
* `declarePlugin` is checked against the real module leaf by leaf. Carrying the
|
|
2021
|
-
* whole export-bindings record as a second entry would only add the binding
|
|
2022
|
-
* NAMES to the comparison, and it costs a mapped type over every export inside
|
|
2023
|
-
* every enclosing summary. That cost grows with the graph, for nothing.
|
|
2024
|
-
*/
|
|
2025
|
-
type AggregateSummary<TNamespace extends string, TName extends string, TImports extends readonly unknown[], TExports extends readonly unknown[]> = AggregateSummaryOf<IdOf<TNamespace, TName>, RequiresIn<TImports> | RequiresIn<TExports>, ProvidesIn<TImports> | ProvidesIn<TExports>, RequiredContractsIn<TImports> | RequiredContractsIn<TExports>, ProvidedContractsIn<TImports> | ProvidedContractsIn<TExports>>;
|
|
2026
|
-
/**
|
|
2027
|
-
* {@link AggregateSummary} with each child ledger already read, so it is read
|
|
2028
|
-
* ONCE per aggregate.
|
|
2029
|
-
*
|
|
2030
|
-
* THE RULE FOR EVERY SUMMARY: read each child ledger ONCE, at the call site,
|
|
2031
|
-
* and pass it in. A summary's phantom slots must never contain an expression
|
|
2032
|
-
* that reads the children again.
|
|
2033
|
-
*
|
|
2034
|
-
* Duplicating a read makes the cost grow exponentially with graph depth rather
|
|
2035
|
-
* than linearly, and a deep graph then fails to compile at all. TypeScript has
|
|
2036
|
-
* no way to name an intermediate type, so a helper that takes the ledgers as
|
|
2037
|
-
* parameters is the only way to read each one exactly once.
|
|
2038
|
-
*
|
|
2039
|
-
* So `Exclude<TRequires, TId | TProvides>` is safe here: `TProvides` is a
|
|
2040
|
-
* parameter, already resolved, shared by both slots. Inlining it back to
|
|
2041
|
-
* `Exclude<RequiresIn<TImports>, TId | ProvidesIn<TImports>>` reads the
|
|
2042
|
-
* children twice and brings the exponential back. Do not "simplify" these
|
|
2043
|
-
* helpers away. `composition-depth.test.ts` and `import-chain-depth.test.ts`
|
|
2044
|
-
* are the canaries.
|
|
2045
|
-
*/
|
|
2046
|
-
type AggregateSummaryOf<TId extends string, TRequires extends string, TProvides extends string, TRequiredContracts extends ContractEntry, TProvidedContracts extends ContractEntry> = PluginSummary<Exclude<TRequires, TId | TProvides>, TId | TProvides, TRequiredContracts, TProvidedContracts>;
|
|
2047
|
-
/**
|
|
2048
|
-
* The `PluginSummary` a re-export synthetic forwards from its source: the
|
|
2049
|
-
* source's own ledgers, unchanged, since `selectExports` / `omitExports` change
|
|
2050
|
-
* which bindings are visible and never which ids the graph reaches. Each read
|
|
2051
|
-
* appears once, per the rule on {@link AggregateSummaryOf}.
|
|
2052
|
-
*
|
|
2053
|
-
* `TSource` is inferred from an intersection parameter, which is fragile. If it
|
|
2054
|
-
* ever stops binding the source's summary it falls back to `unknown`, these
|
|
2055
|
-
* ledgers come out empty, and every check behind the helper switches off
|
|
2056
|
-
* SILENTLY, with nothing failing to compile. The forwarding case in
|
|
2057
|
-
* `select-exports.test.ts` is the only thing that catches that, so it is
|
|
2058
|
-
* load-bearing rather than illustrative.
|
|
2059
|
-
*/
|
|
2060
|
-
type ForwardedSummary<TSource> = PluginSummary<RequiresOf<TSource>, ProvidesOf$1<TSource>, RequiredContractsOf<TSource>, ProvidedContractsOf<TSource>>;
|
|
2061
|
-
/** The `PluginSummary` a `declarePlugin` declaration carries: its id in the
|
|
2062
|
-
* requirements ledger, plus the contracts its export stand-ins declared, read
|
|
2063
|
-
* once at the call site per the rule on {@link AggregateSummaryOf}. */
|
|
2064
|
-
type AggregateDeclarationSummary<TId extends string, TRequiredContracts extends ContractEntry> = PluginSummary<TId, never, TRequiredContracts, never>;
|
|
2065
|
-
/** The `PluginSummary` a required declaration carries: its id in the
|
|
2066
|
-
* requirements ledger, and the contract every provider of that id must honor. */
|
|
2067
|
-
type DeclarationSummary<TId extends string, TBinding> = PluginSummary<TId, never, ContractEntry<TId, TBinding>, never>;
|
|
2068
|
-
/** The optional twin of {@link DeclarationSummary}: it claims no slot, so it is
|
|
2069
|
-
* never a missing dependency, but a provider that DOES appear under the id
|
|
2070
|
-
* still has to honor the contract. */
|
|
2071
|
-
type OptionalDeclarationSummary<TId extends string, TBinding> = PluginSummary<never, never, ContractEntry<TId, TBinding>, never>;
|
|
2072
|
-
/**
|
|
2073
|
-
* The runtime-input channel for `createSdk`. `configuration` maps plugin ids to
|
|
2074
|
-
* immutable values; each entry materializes as a static value property under
|
|
2075
|
-
* that id, satisfying a `declareProperty` / `declareOptionalProperty` stand-in exactly
|
|
2076
|
-
* as a registered provider would (DI value injection). Strict at build time:
|
|
2077
|
-
* an id must resolve to a property stand-in reachable from the root, so
|
|
2078
|
-
* unknown ids, non-property targets, and collisions with a registered real
|
|
2079
|
-
* provider all throw. kitcore keeps the map untyped; a head's factory is the
|
|
2080
|
-
* typed wrapper (`createMySdk(options)` passes
|
|
2081
|
-
* `{ configuration: { "my/config": options } }`).
|
|
2082
|
-
*/
|
|
2083
|
-
interface CreateSdkOptions {
|
|
2084
|
-
configuration?: Record<string, unknown>;
|
|
2085
|
-
}
|
|
2086
|
-
/**
|
|
2087
|
-
* Surfaced by `createSdk` when reachable declarations have no provider.
|
|
2088
|
-
*
|
|
2089
|
-
* The guard names the property it checks (`CompletenessOf`) and the brand
|
|
2090
|
-
* names the fault, so the pair shares no root. That is deliberate: "missing"
|
|
2091
|
-
* tells a reader what to do, where "incomplete" only restates the property.
|
|
2092
|
-
*/
|
|
2093
|
-
interface MissingProviders<TIds extends string> {
|
|
2094
|
-
readonly __kitcoreError: "Missing concrete provider(s) for required declaration id(s)";
|
|
2095
|
-
readonly missing: TIds;
|
|
2096
|
-
}
|
|
2097
|
-
/**
|
|
2098
|
-
* `unknown` when every reachable declaration is provided, otherwise a
|
|
2099
|
-
* `MissingProviders` brand. `createSdk` takes `root: P & CompletenessOf<P>`,
|
|
2100
|
-
* so a complete root infers `P` unchanged (intersect `unknown`) while an
|
|
2101
|
-
* incomplete one fails to assign (the argument lacks `missing`).
|
|
2102
|
-
*/
|
|
2103
|
-
type CompletenessOf<P> = [
|
|
2104
|
-
Exclude<RequiresOf<P>, ProvidesOf$1<P>>
|
|
2105
|
-
] extends [never] ? unknown : MissingProviders<Exclude<RequiresOf<P>, ProvidesOf$1<P>>>;
|
|
2106
|
-
/** The provided entries registered under one id. */
|
|
2107
|
-
type ProvidersFor<TProvided extends ContractEntry, TId extends string> = Extract<TProvided, {
|
|
2108
|
-
readonly id: TId;
|
|
2109
|
-
}>;
|
|
2110
|
-
/**
|
|
2111
|
-
* The ids whose reachable providers do not all honor the declared contract.
|
|
2112
|
-
*
|
|
2113
|
-
* EVERY provider under an id must honor it, not just one: `declareDefault` lets
|
|
2114
|
-
* a default coexist with an explicit provider, so "some compatible provider
|
|
2115
|
-
* exists" would pass a good default beside a bad explicit one while the runtime
|
|
2116
|
-
* picks the bad one.
|
|
2117
|
-
*
|
|
2118
|
-
* An id with no provider yields nothing here. That is `CompletenessOf`'s
|
|
2119
|
-
* report, and two errors for one cause read worse than one.
|
|
2120
|
-
*/
|
|
2121
|
-
type IncompatibleIds<TRequired extends ContractEntry, TProvided extends ContractEntry> = TRequired extends ContractEntry ? MismatchedProviders<TRequired, ProvidersFor<TProvided, TRequired["id"]>> : never;
|
|
2122
|
-
/** The required id, once per provider of it that fails the contract. An id with
|
|
2123
|
-
* no provider yields `never` here, since a distributive conditional over
|
|
2124
|
-
* `never` is `never`. */
|
|
2125
|
-
type MismatchedProviders<TRequired extends ContractEntry, TCandidate extends ContractEntry> = TCandidate extends ContractEntry ? [TCandidate["binding"]] extends [TRequired["binding"]] ? never : ServesEveryDeclaredCall<TCandidate["binding"], TRequired["binding"]> extends true ? never : TRequired["id"] : never;
|
|
2126
|
-
/** The keys a caller of `T` must supply. */
|
|
2127
|
-
type RequiredKeys<T> = keyof {
|
|
2128
|
-
[K in keyof T as {} extends Pick<T, K> ? never : K]: unknown;
|
|
2129
|
-
};
|
|
2130
|
-
/**
|
|
2131
|
-
* Rescues a provider that whole-function assignability rejects for a reason
|
|
2132
|
-
* that does not apply here.
|
|
2133
|
-
*
|
|
2134
|
-
* TypeScript's weak-type rule refuses to relate two object types that share no
|
|
2135
|
-
* properties, even when the target needs none of them. So a declaration
|
|
2136
|
-
* promising `{ search: string }` failed against a provider taking
|
|
2137
|
-
* `{ locale?: string }`, though that provider requires nothing and reads
|
|
2138
|
-
* nothing the declaration sends. That contradicts the rule this check is built
|
|
2139
|
-
* on, which is that a provider may accept WIDER input.
|
|
2140
|
-
*
|
|
2141
|
-
* The escape stays sound by demanding all three: the output is still a subtype,
|
|
2142
|
-
* the provider requires no input field, and the two inputs share no key, so
|
|
2143
|
-
* there is no field the provider can read at a type it does not expect.
|
|
2144
|
-
*/
|
|
2145
|
-
type ServesEveryDeclaredCall<TProvided, TRequired> = TRequired extends (...args: infer TDeclaredArgs) => infer TDeclaredOut ? TProvided extends (...args: infer TProviderArgs) => infer TProviderOut ? [TProviderOut] extends [TDeclaredOut] ? [TDeclaredArgs] extends [readonly [unknown?]] ? [TProviderArgs] extends [readonly [unknown?]] ? [
|
|
2146
|
-
Extract<keyof NonNullable<TDeclaredArgs[0]>, keyof NonNullable<TProviderArgs[0]>>
|
|
2147
|
-
] extends [never] ? [RequiredKeys<NonNullable<TProviderArgs[0]>>] extends [never] ? true : false : false : false : false : false : false : false;
|
|
2148
|
-
/** Surfaced by `createSdk` when a provider contradicts its declaration. */
|
|
2149
|
-
interface IncompatibleProviders<TIds extends string> {
|
|
2150
|
-
readonly __kitcoreError: "Provider(s) do not match the contract declared for the id(s); a provider may accept wider input but must return a subtype of the declared output";
|
|
2151
|
-
readonly incompatible: TIds;
|
|
2152
|
-
}
|
|
2153
|
-
/**
|
|
2154
|
-
* `unknown` when every provided id honors the contract declared for it,
|
|
2155
|
-
* otherwise an `IncompatibleProviders` brand. `createSdk` takes
|
|
2156
|
-
* `root: P & CompletenessOf<P> & CompatibilityOf<P>`, so a sound graph infers
|
|
2157
|
-
* `P` unchanged (intersect `unknown`) while an unsound one fails to assign.
|
|
2158
|
-
*/
|
|
2159
|
-
type CompatibilityOf<P> = IncompatibleIds<RequiredContractsOf<P>, ProvidedContractsOf<P>> extends infer TIds extends string ? [TIds] extends [never] ? unknown : IncompatibleProviders<TIds> : never;
|
|
2160
|
-
/** Recover the materialized SDK type for a checked root (the summary that
|
|
2161
|
-
* rides on the `define*` return is transparent to these). */
|
|
2162
|
-
type MethodSdkOf<P> = P extends MethodPlugin<infer TName, infer TInput, infer TOutput, infer TPos> ? Sdk$1<TName, TInput, TOutput, TPos> : never;
|
|
2163
|
-
type PropertySdkOf<P> = P extends PropertyPlugin<infer TName, infer TValue> ? PropertySdk<TName, TValue> : never;
|
|
2164
|
-
type AggregateSdkOf<P> = P extends AggregatePlugin<string, infer TExports> ? AggregateSdk<TExports> : never;
|
|
2165
|
-
|
|
2166
|
-
/**
|
|
2167
|
-
* Declaration for a registry category (a bucket grouping related functions).
|
|
2168
|
-
* Plugins reference categories in their `meta.categories` field, as either a
|
|
2169
|
-
* bare key (auto-derive title and plural) or this object (override either).
|
|
2170
|
-
*
|
|
2171
|
-
* Examples (with auto-derive rules):
|
|
2172
|
-
* - `{ key: "app" }` → title "App", plural "Apps"
|
|
2173
|
-
* - `{ key: "client-credentials" }` → title "Client Credentials", plural "Client Credentials"
|
|
2174
|
-
* - `{ key: "utility" }` → title "Utility", plural "Utilities"
|
|
2175
|
-
* - `{ key: "http", title: "HTTP Request" }` → plural "HTTP Requests"
|
|
2176
|
-
*/
|
|
2177
|
-
interface CategoryDefinition {
|
|
2178
|
-
key: string;
|
|
2179
|
-
/** Display title for the category. Auto-derived from `key` if omitted. */
|
|
2180
|
-
title?: string;
|
|
2181
|
-
/** Plural form of `title`. Auto-derived from the resolved title if omitted. */
|
|
2182
|
-
titlePlural?: string;
|
|
2183
|
-
}
|
|
2184
|
-
interface FunctionRegistryEntry {
|
|
2185
|
-
name: string;
|
|
2186
|
-
/**
|
|
2187
|
-
* Human-readable description of the function. Surfaced wherever the
|
|
2188
|
-
* registry is consumed (command help, tool/RPC descriptions, generated
|
|
2189
|
-
* documentation). Prefer providing this directly rather than relying
|
|
2190
|
-
* solely on inputSchema.describe().
|
|
2191
|
-
*/
|
|
2192
|
-
description?: string;
|
|
2193
|
-
type?: "list" | "item" | "create" | "update" | "delete" | "function";
|
|
2194
|
-
itemType?: string;
|
|
2195
|
-
returnType?: string;
|
|
2196
|
-
inputSchema?: z.ZodSchema;
|
|
2197
|
-
/**
|
|
2198
|
-
* When true, the method owns its input validation and its boundary passes the
|
|
2199
|
-
* input through unparsed. The resolution controller reads this to skip its
|
|
2200
|
-
* final `safeParse` (it still uses `inputSchema` to plan/prompt parameters),
|
|
2201
|
-
* so a method routed through the controller isn't re-validated against a
|
|
2202
|
-
* schema it deliberately opts out of. Lifted off the materialized entry.
|
|
2203
|
-
*/
|
|
2204
|
-
skipInputValidation?: boolean;
|
|
2205
|
-
outputSchema?: z.ZodSchema;
|
|
2206
|
-
/**
|
|
2207
|
-
* Ordered input keys the public surface projects onto positional arguments
|
|
2208
|
-
* (the method's `positional` declaration). Absent when the method takes only
|
|
2209
|
-
* the canonical single bag. Lifted off the materialized method entry by the
|
|
2210
|
-
* surface builder, like `resolvers` — a runtime projection, not
|
|
2211
|
-
* descriptive meta.
|
|
2212
|
-
*/
|
|
2213
|
-
positional?: readonly string[];
|
|
2214
|
-
categories: string[];
|
|
2215
|
-
/**
|
|
2216
|
-
* Per-parameter bound resolvers (imports already captured, called with
|
|
2217
|
-
* `input` only, no sdk). Lifted off the materialized method entry by the
|
|
2218
|
-
* surface builder.
|
|
2219
|
-
*/
|
|
2220
|
-
resolvers?: Record<string, BoundResolver>;
|
|
2221
|
-
packages?: string[];
|
|
2222
|
-
/**
|
|
2223
|
-
* API stability tier of the plugin, normalized from `PluginMeta.stability`
|
|
2224
|
-
* (absent means `"stable"`; the legacy `experimental: true` boolean means
|
|
2225
|
-
* `"experimental"`). Always concrete here, so consumers never branch on
|
|
2226
|
-
* `undefined`.
|
|
2227
|
-
*/
|
|
2228
|
-
stability: StabilityLevel;
|
|
2229
|
-
/**
|
|
2230
|
-
* @deprecated Read `stability` instead. Derived as
|
|
2231
|
-
* `stability === "experimental"` — literal by name, so beta reads
|
|
2232
|
-
* `false`; the not-stable warning duty lives in `stability` and the
|
|
2233
|
-
* runtime stability notice.
|
|
2234
|
-
*/
|
|
2235
|
-
experimental?: boolean;
|
|
2236
|
-
/** Confirmation prompt type - prompts user before executing */
|
|
2237
|
-
confirm?: "create-secret" | "delete";
|
|
2238
|
-
/**
|
|
2239
|
-
* Optional deprecation metadata for commands.
|
|
2240
|
-
*/
|
|
2241
|
-
deprecation?: FunctionDeprecation;
|
|
2242
|
-
/**
|
|
2243
|
-
* Short aliases for parameter names (e.g., { request: "X", header: "H" }).
|
|
2244
|
-
* Consumers that render the function as a flag-style command surface use
|
|
2245
|
-
* these as short forms.
|
|
2246
|
-
*/
|
|
2247
|
-
aliases?: Record<string, string>;
|
|
2248
|
-
/**
|
|
2249
|
-
* Output formatter, normalized to the bound runtime shape (its imports/sdk
|
|
2250
|
-
* already captured), so consumers call `getContext`/`format` with no sdk.
|
|
2251
|
-
* The surface builder produces this from the method entry — `entry.formatter`
|
|
2252
|
-
* for a migrated plugin, or the legacy `meta.formatter` adapted — so vintage
|
|
2253
|
-
* is invisible here.
|
|
2254
|
-
*/
|
|
2255
|
-
formatter?: BoundFormatter;
|
|
2256
|
-
/** Defaults to true. Set to false to suppress --json (e.g. login/logout/init). */
|
|
2257
|
-
supportsJsonOutput: boolean;
|
|
2258
|
-
}
|
|
2259
|
-
interface FunctionDeprecation {
|
|
2260
|
-
/** User-facing deprecation message for why/how to migrate */
|
|
2261
|
-
message: string;
|
|
2262
|
-
}
|
|
2263
|
-
interface RegistryResult {
|
|
2264
|
-
functions: FunctionRegistryEntry[];
|
|
2265
|
-
categories: {
|
|
2266
|
-
key: string;
|
|
2267
|
-
title: string;
|
|
2268
|
-
titlePlural: string;
|
|
2269
|
-
functions: string[];
|
|
2270
|
-
}[];
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
/**
|
|
2274
|
-
* ------------------------------
|
|
2275
|
-
* Plugin Type System
|
|
2276
|
-
* ------------------------------
|
|
2277
|
-
*
|
|
2278
|
-
* Plugins receive the sdk as a positional parameter. sdk.context holds shared
|
|
2279
|
-
* internal state (api client, event emission, meta, options, etc.). SDK methods
|
|
2280
|
-
* live at the root, context nests under .context.
|
|
2281
|
-
*
|
|
2282
|
-
* A plugin is (sdk) => partialSdk. `createPluginStack()` accumulates plugins
|
|
2283
|
-
* and materializes a built `Sdk` via `.toSdk()`; `addPlugin(sdk, plugin)`
|
|
2284
|
-
* extends an already-built SDK in place with one more plugin.
|
|
2285
|
-
*/
|
|
2286
|
-
|
|
2287
|
-
interface PluginProvides extends Record<string, any> {
|
|
2288
|
-
context?: {
|
|
2289
|
-
meta?: Record<string, PluginMeta<any>>;
|
|
2290
|
-
hooks?: MethodHooks;
|
|
2291
|
-
[key: string]: any;
|
|
2292
|
-
};
|
|
2293
|
-
}
|
|
2294
|
-
interface PluginMeta<TSdk = unknown> {
|
|
2295
|
-
/**
|
|
2296
|
-
* Human-readable description of the plugin function. Used by the CLI (help text),
|
|
2297
|
-
* MCP (tool description), and README generators. When omitted, falls back to
|
|
2298
|
-
* the inputSchema's `.describe()` value or a generic placeholder.
|
|
2299
|
-
*/
|
|
2300
|
-
description?: string;
|
|
2301
|
-
/**
|
|
2302
|
-
* Buckets this function belongs to in `getRegistry()` output. Each entry is
|
|
2303
|
-
* either a bare key (`"app"`) for auto-derived titles or a {@link CategoryDefinition}
|
|
2304
|
-
* object to override the title or plural. Only one plugin needs to supply
|
|
2305
|
-
* the object form per category key; object refs win over string refs, so
|
|
2306
|
-
* other plugins in the same bucket can stay on bare strings.
|
|
2307
|
-
*/
|
|
2308
|
-
categories?: (string | CategoryDefinition)[];
|
|
2309
|
-
type?: "list" | "item" | "create" | "update" | "delete" | "function";
|
|
2310
|
-
itemType?: string;
|
|
2311
|
-
returnType?: string;
|
|
2312
|
-
inputSchema?: z.ZodSchema;
|
|
2313
|
-
outputSchema?: z.ZodSchema;
|
|
2314
|
-
/**
|
|
2315
|
-
* Item formatter that the registry hands to the CLI/MCP renderer. The
|
|
2316
|
-
* `sdk` param on `fetch` is typed to the plugin's own declared SDK
|
|
2317
|
-
* surface (`TRequires & TProvides`); reaching into another plugin's
|
|
2318
|
-
* method requires adding it to `TRequires` explicitly.
|
|
2319
|
-
*/
|
|
2320
|
-
formatter?: OutputFormatter<TSdk, any, any, any>;
|
|
2321
|
-
/**
|
|
2322
|
-
* Per-parameter resolver metadata. Same `TSdk` surfaces in each
|
|
2323
|
-
* resolver's `fetch`/`tryResolveWithoutPrompt` callbacks.
|
|
2324
|
-
*/
|
|
2325
|
-
resolvers?: Record<string, ResolverMetadata<TSdk, any, any>>;
|
|
2326
|
-
/** Confirmation prompt type - prompts user before executing */
|
|
2327
|
-
confirm?: "create-secret" | "delete";
|
|
2328
|
-
/**
|
|
2329
|
-
* API stability tier this plugin belongs to. Absent means `"stable"`;
|
|
2330
|
-
* the registry projection normalizes it, so registry consumers always
|
|
2331
|
-
* read a concrete {@link StabilityLevel}. Wrappers keep non-stable
|
|
2332
|
-
* plugins out of their stable build (by gating them behind a `beta` /
|
|
2333
|
-
* `experimental` subpath import) and consumers badge the level in
|
|
2334
|
-
* generated docs, CLI help, and MCP tool descriptions. No runtime
|
|
2335
|
-
* capability check.
|
|
2336
|
-
*/
|
|
2337
|
-
stability?: StabilityLevel;
|
|
2338
|
-
/**
|
|
2339
|
-
* @deprecated Use `stability: "experimental"` instead. Kept as an
|
|
2340
|
-
* input for external authors; `true` normalizes to
|
|
2341
|
-
* `stability: "experimental"` in the registry projection.
|
|
2342
|
-
*/
|
|
2343
|
-
experimental?: boolean;
|
|
2344
|
-
[key: string]: any;
|
|
2345
|
-
}
|
|
2346
|
-
/**
|
|
2347
|
-
* Plugin interface — 2 type params:
|
|
2348
|
-
*
|
|
2349
|
-
* TSdk = what this plugin needs (the SDK shape including context)
|
|
2350
|
-
* TProvides = what this plugin returns (a partial SDK shape)
|
|
2351
|
-
*
|
|
2352
|
-
* The sdk param always includes context.meta, even if TSdk doesn't declare it.
|
|
2353
|
-
*/
|
|
2354
|
-
interface Plugin<TSdk = {}, TProvides extends PluginProvides = PluginProvides> {
|
|
2355
|
-
(sdk: TSdk & {
|
|
2356
|
-
context: {
|
|
2357
|
-
meta: Record<string, PluginMeta<any>>;
|
|
2358
|
-
hooks: MethodHooks;
|
|
2359
|
-
};
|
|
2360
|
-
}): TProvides;
|
|
2361
|
-
}
|
|
2362
|
-
/**
|
|
2363
|
-
* A built SDK. Carries the plugins' contributions plus the
|
|
2364
|
-
* `getRegistry` accessor over `context.meta`. No `addPlugin` method
|
|
2365
|
-
* on the shape: extension after build goes through the top-level
|
|
2366
|
-
* `addPlugin(sdk, plugin)` function, which mutates the sdk in place
|
|
2367
|
-
* and narrows the caller's binding via TypeScript's assertion
|
|
2368
|
-
* functions.
|
|
2369
|
-
*/
|
|
2370
|
-
type Sdk<T = {
|
|
2371
|
-
context: {
|
|
2372
|
-
meta: Record<string, PluginMeta<any>>;
|
|
2373
|
-
hooks: MethodHooks;
|
|
2374
|
-
};
|
|
2375
|
-
}> = T & {
|
|
2376
|
-
getRegistry(options?: {
|
|
2377
|
-
package?: string;
|
|
2378
|
-
}): RegistryResult;
|
|
2379
|
-
};
|
|
2380
|
-
|
|
2381
|
-
/**
|
|
2382
|
-
* ------------------------------
|
|
2383
|
-
* Plugin authoring helpers
|
|
2384
|
-
* ------------------------------
|
|
2385
|
-
*
|
|
2386
|
-
* - `createPluginMethod` / `createPaginatedPluginMethod`: per-method
|
|
2387
|
-
* primitives that sit inside a `definePlugin` callback and build the
|
|
2388
|
-
*
|
|
2389
|
-
* { [name]: wrappedFn, context: { meta: { [name]: meta } } }
|
|
2390
|
-
*
|
|
2391
|
-
* fragment a plugin returns for a single method, wiring up
|
|
2392
|
-
* `createFunction` / `createPaginatedFunction`, the method-call hooks,
|
|
2393
|
-
* and the doubled `name` (function key + meta key) in one place.
|
|
2394
|
-
*
|
|
2395
|
-
* Two method helpers (rather than one with a `paginated: true` discriminant)
|
|
2396
|
-
* because the handler signature changes shape across pagination, and
|
|
2397
|
-
* discriminated unions on optional booleans produce noisy TS errors.
|
|
2398
|
-
*
|
|
2399
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
2400
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
2401
|
-
*/
|
|
2402
|
-
|
|
2403
|
-
/**
|
|
2404
|
-
* Method-level meta fields. Mirrors `PluginMeta` minus `inputSchema`, which is
|
|
2405
|
-
* passed at the top level alongside the handler and merged into the meta by
|
|
2406
|
-
* the helpers themselves.
|
|
2407
|
-
*
|
|
2408
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
2409
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
2410
|
-
*/
|
|
2411
|
-
type MethodMeta<TSdk> = Omit<PluginMeta<TSdk>, "inputSchema">;
|
|
2412
|
-
/**
|
|
2413
|
-
* The plugin's own method signature, synthesized from the method config.
|
|
2414
|
-
* Mixed into the resolver-side SDK so a resolver may freely reference the
|
|
2415
|
-
* host plugin's own method (e.g. `appKeyResolver` calling `sdk.getApp`)
|
|
2416
|
-
* without forcing the plugin to declare a circular dependency on itself.
|
|
2417
|
-
*
|
|
2418
|
-
* Uses `any` for options and return: we only need to assert the method
|
|
2419
|
-
* exists on `sdk`, not pin its full signature. Using `TInput`/`TResult`
|
|
2420
|
-
* here would create a circular inference (TSdk depends on TInput/TResult
|
|
2421
|
-
* via the resolvers slot, TInput/TResult are inferred from the handler
|
|
2422
|
-
* which depends on TSdk), and TS resolves the cycle by widening to
|
|
2423
|
-
* `unknown`. With `any`, the resolver check still verifies the method's
|
|
2424
|
-
* presence on the SDK; signature precision for self is the plugin
|
|
2425
|
-
* author's responsibility.
|
|
2426
|
-
*
|
|
2427
|
-
* Not mixed into the handler's `sdk`: handlers run against the SDK that
|
|
2428
|
-
* existed when the plugin was added to the stack (closure-captured), so
|
|
2429
|
-
* self-method access there would be a lie at runtime.
|
|
2430
|
-
*
|
|
2431
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
2432
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
2433
|
-
*/
|
|
2434
|
-
type SelfMethod<TName extends string> = {
|
|
2435
|
-
[K in TName]: (options?: any) => any;
|
|
2436
|
-
};
|
|
2437
|
-
interface PluginMethodConfig<TSdk, TInput, TResult, TName extends string, TResolvers> extends Omit<MethodMeta<TSdk>, "resolvers"> {
|
|
2438
|
-
name: TName;
|
|
2439
|
-
/**
|
|
2440
|
-
* Schema for runtime input validation; drives the handler's `options`
|
|
2441
|
-
* type. For plugins that accept deprecated parameter aliases this is a
|
|
2442
|
-
* `z.union([CanonicalSchema, DeprecatedSchema])` — the registry
|
|
2443
|
-
* unwraps unions and exposes only the first variant (canonical) to
|
|
2444
|
-
* documentation and downstream consumer surfaces.
|
|
2445
|
-
*
|
|
2446
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
2447
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
2448
|
-
*/
|
|
2449
|
-
inputSchema?: z.ZodSchema<TInput>;
|
|
2450
|
-
handler: (args: {
|
|
2451
|
-
sdk: TSdk;
|
|
2452
|
-
options: TInput;
|
|
2453
|
-
}) => Promise<TResult>;
|
|
2454
|
-
/**
|
|
2455
|
-
* Per-parameter resolvers. Each entry's `TSdk` requirement is checked
|
|
2456
|
-
* against the plugin's own `TSdk` (plus the plugin's own method via
|
|
2457
|
-
* {@link SelfMethod}) using {@link ValidResolvers}; mismatches surface
|
|
2458
|
-
* at the offending key. `NoInfer` pins `TSdk` to the `sdk` argument so
|
|
2459
|
-
* resolver entries don't widen the inferred `TSdk`.
|
|
2460
|
-
*
|
|
2461
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
2462
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
2463
|
-
*/
|
|
2464
|
-
resolvers?: ValidResolvers<NoInfer<TSdk & SelfMethod<TName>>, TResolvers> & TResolvers;
|
|
2465
|
-
}
|
|
2466
|
-
type PluginMethodReturn<TName extends string, TInput, TResult> = {
|
|
2467
|
-
[K in TName]: (options?: TInput) => Promise<TResult>;
|
|
2468
|
-
} & {
|
|
2469
|
-
context: {
|
|
2470
|
-
meta: {
|
|
2471
|
-
[K in TName]: PluginMeta;
|
|
2472
|
-
};
|
|
2473
|
-
};
|
|
2474
|
-
};
|
|
2103
|
+
* is empty. The ledger keys on this (matching runtime id resolution), not the
|
|
2104
|
+
* bare name, so same-named plugins in different namespaces stay distinct. */
|
|
2105
|
+
type IdOf<TNamespace extends string, TName extends string> = TNamespace extends "" ? TName : `${TNamespace}/${TName}`;
|
|
2106
|
+
/** The binding name of an id: its last `/`-separated segment. The inverse view
|
|
2107
|
+
* of `IdOf`, used by `declare*` to derive the bare binding from a full id. */
|
|
2108
|
+
type LastSegment<TId extends string> = TId extends `${string}/${infer Rest}` ? LastSegment<Rest> : TId;
|
|
2475
2109
|
/**
|
|
2476
|
-
*
|
|
2477
|
-
*
|
|
2478
|
-
*
|
|
2479
|
-
* export const getProfilePlugin = definePlugin(
|
|
2480
|
-
* (sdk: ApiPluginProvides & EventEmissionProvides) =>
|
|
2481
|
-
* createPluginMethod(sdk, {
|
|
2482
|
-
* name: "getProfile",
|
|
2483
|
-
* categories: ["account"],
|
|
2484
|
-
* inputSchema: GetProfileSchema,
|
|
2485
|
-
* handler: async ({ sdk }) => { ... },
|
|
2486
|
-
* }),
|
|
2487
|
-
* );
|
|
2110
|
+
* The `PluginSummary` a leaf carries, keyed on its full id. `TBinding` is the
|
|
2111
|
+
* surfaced binding the leaf implements (its call signature or its value).
|
|
2488
2112
|
*
|
|
2489
|
-
*
|
|
2490
|
-
*
|
|
2113
|
+
* `TBinding` is REQUIRED, deliberately. Defaulting it to `never` would make a
|
|
2114
|
+
* three-argument annotation contribute no contract, so a hand-written
|
|
2115
|
+
* annotation would keep compiling and silently drop the leaf out of the
|
|
2116
|
+
* compatibility check.
|
|
2117
|
+
* A missing argument is a compile error instead.
|
|
2491
2118
|
*/
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
/** Same semantics as `createPluginMethod`'s `inputSchema`. */
|
|
2498
|
-
inputSchema?: z.ZodSchema<TInput>;
|
|
2499
|
-
/**
|
|
2500
|
-
* Optional default page size when the caller doesn't pass one. Mirrors
|
|
2501
|
-
* `createPaginatedFunction`'s `defaultPageSize` arg.
|
|
2502
|
-
*/
|
|
2503
|
-
defaultPageSize?: number;
|
|
2504
|
-
/** See {@link PluginMethodConfig.resolvers}. */
|
|
2505
|
-
resolvers?: ValidResolvers<NoInfer<TSdk & SelfMethod<TName>>, TResolvers> & TResolvers;
|
|
2506
|
-
}
|
|
2119
|
+
type LeafSummary<TNamespace extends string, TName extends string, TImports extends readonly unknown[], TBinding> = LeafSummaryById<IdOf<TNamespace, TName>, TImports, TBinding>;
|
|
2120
|
+
/** {@link LeafSummary} for a leaf whose full id is already known rather than
|
|
2121
|
+
* composed from a namespace and a name, which is what the by-reference
|
|
2122
|
+
* `define*(ref, config)` forms have: the id comes off the stand-in. */
|
|
2123
|
+
type LeafSummaryById<TId extends string, TImports extends readonly unknown[], TBinding> = LeafSummaryOf<TId, RequiresIn<TImports>, ProvidesIn<TImports>, RequiredContractsIn<TImports>, ProvidedContractsIn<TImports>, TBinding>;
|
|
2507
2124
|
/**
|
|
2508
|
-
*
|
|
2509
|
-
*
|
|
2510
|
-
* `links`/`meta`, a top-level `next`, etc.) is NOT a `StrictPage`, so it falls
|
|
2511
|
-
* through to the Adapted overload and `adaptPage` becomes required. Each excess
|
|
2512
|
-
* key is mapped to `?: never`, which a real value (e.g. `links: {...}`) can't
|
|
2513
|
-
* satisfy — that's what a plain `SdkPage` assignability check (which allows
|
|
2514
|
-
* excess keys structurally) misses.
|
|
2125
|
+
* {@link LeafSummaryById} with each import ledger already read, so it is read
|
|
2126
|
+
* ONCE per leaf. See the rule on {@link AggregateSummaryOf}.
|
|
2515
2127
|
*/
|
|
2516
|
-
type
|
|
2517
|
-
[K in Exclude<keyof TResponse, keyof SdkPage<unknown>>]?: never;
|
|
2518
|
-
};
|
|
2519
|
-
/**
|
|
2520
|
-
* Config for a paginated method whose handler already returns a clean page
|
|
2521
|
-
* (`{ data, nextCursor? }` and nothing else — see `StrictPage`, enforced on
|
|
2522
|
-
* the overload). No `adaptPage` needed; `TItem` is sourced from the handler's
|
|
2523
|
-
* `data`. Interface extension keeps this a single flattened object type (not
|
|
2524
|
-
* an intersection), preserving clean inference of the `resolvers` /
|
|
2525
|
-
* `TResolvers` slot.
|
|
2526
|
-
*/
|
|
2527
|
-
interface PaginatedPluginMethodConfigStandard<TSdk, TInput, TResponse, TName extends string, TResolvers> extends PaginatedPluginMethodConfigBase<TSdk, TInput, TName, TResolvers> {
|
|
2528
|
-
handler: (args: {
|
|
2529
|
-
sdk: TSdk;
|
|
2530
|
-
options: TInput & {
|
|
2531
|
-
cursor?: string;
|
|
2532
|
-
pageSize?: number;
|
|
2533
|
-
};
|
|
2534
|
-
}) => Promise<TResponse>;
|
|
2535
|
-
/** No adapter: the handler already returns a page. */
|
|
2536
|
-
adaptPage?: undefined;
|
|
2537
|
-
}
|
|
2538
|
-
/**
|
|
2539
|
-
* Config for a paginated method whose handler returns a raw upstream shape
|
|
2540
|
-
* (`TResponse`, e.g. a JSON:API `links.next` envelope). `adaptPage` is required
|
|
2541
|
-
* to translate it into a page. `TItem` is sourced from `TResponse` (`ItemOf`),
|
|
2542
|
-
* not the adapter — the adapter is item-agnostic (relocates the cursor; items
|
|
2543
|
-
* are finalized in the handler's `data`), hence `NoInfer`, so a generic adapter
|
|
2544
|
-
* (e.g. `<T>(r) => SdkPage<T>`) doesn't collapse `TItem` to `unknown`.
|
|
2545
|
-
*/
|
|
2546
|
-
interface PaginatedPluginMethodConfigAdapted<TSdk, TInput, TResponse, TItem, TName extends string, TResolvers> extends PaginatedPluginMethodConfigBase<TSdk, TInput, TName, TResolvers> {
|
|
2547
|
-
handler: (args: {
|
|
2548
|
-
sdk: TSdk;
|
|
2549
|
-
options: TInput & {
|
|
2550
|
-
cursor?: string;
|
|
2551
|
-
pageSize?: number;
|
|
2552
|
-
};
|
|
2553
|
-
}) => Promise<TResponse>;
|
|
2554
|
-
adaptPage: (response: TResponse) => SdkPage<NoInfer<TItem>>;
|
|
2555
|
-
}
|
|
2556
|
-
type ItemOf<TResponse> = TResponse extends SdkPage<infer TItem> ? TItem : TResponse extends {
|
|
2557
|
-
data: readonly (infer TItem)[];
|
|
2558
|
-
} ? TItem : never;
|
|
2559
|
-
type PaginatedPluginMethodReturn<TName extends string, TInput, TItem> = {
|
|
2560
|
-
[K in TName]: (options?: TInput & {
|
|
2561
|
-
cursor?: string;
|
|
2562
|
-
pageSize?: number;
|
|
2563
|
-
maxItems?: number;
|
|
2564
|
-
}) => PaginatedSdkResult<TItem>;
|
|
2565
|
-
} & {
|
|
2566
|
-
context: {
|
|
2567
|
-
meta: {
|
|
2568
|
-
[K in TName]: PluginMeta;
|
|
2569
|
-
};
|
|
2570
|
-
};
|
|
2571
|
-
};
|
|
2128
|
+
type LeafSummaryOf<TId extends string, TRequires extends string, TProvides extends string, TRequiredContracts extends ContractEntry, TProvidedContracts extends ContractEntry, TBinding> = PluginSummary<Exclude<TRequires, TId | TProvides>, TId | TProvides, TRequiredContracts, ContractEntry<TId, TBinding> | TProvidedContracts>;
|
|
2572
2129
|
/**
|
|
2573
|
-
*
|
|
2574
|
-
* response contract at compile time:
|
|
2130
|
+
* The `PluginSummary` an aggregate carries, keyed on its full id.
|
|
2575
2131
|
*
|
|
2576
|
-
*
|
|
2577
|
-
*
|
|
2578
|
-
*
|
|
2579
|
-
*
|
|
2132
|
+
* It contributes no contract for its own id. A module's contract IS its
|
|
2133
|
+
* exports, and each export already carries one keyed by its own id, so
|
|
2134
|
+
* `declarePlugin` is checked against the real module leaf by leaf. Carrying the
|
|
2135
|
+
* whole export-bindings record as a second entry would only add the binding
|
|
2136
|
+
* NAMES to the comparison, and it costs a mapped type over every export inside
|
|
2137
|
+
* every enclosing summary. That cost grows with the graph, for nothing.
|
|
2138
|
+
*/
|
|
2139
|
+
type AggregateSummary<TNamespace extends string, TName extends string, TImports extends readonly unknown[], TExports extends readonly unknown[]> = AggregateSummaryOf<IdOf<TNamespace, TName>, RequiresIn<TImports> | RequiresIn<TExports>, ProvidesIn<TImports> | ProvidesIn<TExports>, RequiredContractsIn<TImports> | RequiredContractsIn<TExports>, ProvidedContractsIn<TImports> | ProvidedContractsIn<TExports>>;
|
|
2140
|
+
/**
|
|
2141
|
+
* {@link AggregateSummary} with each child ledger already read, so it is read
|
|
2142
|
+
* ONCE per aggregate.
|
|
2580
2143
|
*
|
|
2581
|
-
*
|
|
2582
|
-
*
|
|
2144
|
+
* THE RULE FOR EVERY SUMMARY: read each child ledger ONCE, at the call site,
|
|
2145
|
+
* and pass it in. A summary's phantom slots must never contain an expression
|
|
2146
|
+
* that reads the children again.
|
|
2583
2147
|
*
|
|
2584
|
-
*
|
|
2585
|
-
*
|
|
2586
|
-
*
|
|
2587
|
-
*
|
|
2588
|
-
* handler: ({ sdk, options }) => sdk.context.api.get("/things", { ... }),
|
|
2589
|
-
* });
|
|
2148
|
+
* Duplicating a read makes the cost grow exponentially with graph depth rather
|
|
2149
|
+
* than linearly, and a deep graph then fails to compile at all. TypeScript has
|
|
2150
|
+
* no way to name an intermediate type, so a helper that takes the ledgers as
|
|
2151
|
+
* parameters is the only way to read each one exactly once.
|
|
2590
2152
|
*
|
|
2591
|
-
*
|
|
2592
|
-
*
|
|
2153
|
+
* So `Exclude<TRequires, TId | TProvides>` is safe here: `TProvides` is a
|
|
2154
|
+
* parameter, already resolved, shared by both slots. Inlining it back to
|
|
2155
|
+
* `Exclude<RequiresIn<TImports>, TId | ProvidesIn<TImports>>` reads the
|
|
2156
|
+
* children twice and brings the exponential back. Do not "simplify" these
|
|
2157
|
+
* helpers away. `composition-depth.test.ts` and `import-chain-depth.test.ts`
|
|
2158
|
+
* are the canaries.
|
|
2593
2159
|
*/
|
|
2594
|
-
|
|
2595
|
-
context: unknown;
|
|
2596
|
-
}, TInput, TResponse extends StrictPage<TResponse>, TItem = ItemOf<TResponse>, const TResolvers extends Record<string, ResolverMetadata<any, any, any>> = {}>(sdk: TSdk, config: PaginatedPluginMethodConfigStandard<TSdk, TInput, TResponse, TName, TResolvers>): PaginatedPluginMethodReturn<TName, TInput, TItem>;
|
|
2597
|
-
declare function createPaginatedPluginMethod<const TName extends string, TSdk extends {
|
|
2598
|
-
context: unknown;
|
|
2599
|
-
}, TInput, TResponse, TItem = ItemOf<TResponse>, const TResolvers extends Record<string, ResolverMetadata<any, any, any>> = {}>(sdk: TSdk, config: PaginatedPluginMethodConfigAdapted<TSdk, TInput, TResponse, TItem, TName, TResolvers>): PaginatedPluginMethodReturn<TName, TInput, TItem>;
|
|
2160
|
+
type AggregateSummaryOf<TId extends string, TRequires extends string, TProvides extends string, TRequiredContracts extends ContractEntry, TProvidedContracts extends ContractEntry> = PluginSummary<Exclude<TRequires, TId | TProvides>, TId | TProvides, TRequiredContracts, TProvidedContracts>;
|
|
2600
2161
|
/**
|
|
2601
|
-
*
|
|
2162
|
+
* The `PluginSummary` a re-export synthetic forwards from its source: the
|
|
2163
|
+
* source's own ledgers, unchanged, since `selectExports` / `omitExports` change
|
|
2164
|
+
* which bindings are visible and never which ids the graph reaches. Each read
|
|
2165
|
+
* appears once, per the rule on {@link AggregateSummaryOf}.
|
|
2602
2166
|
*
|
|
2603
|
-
*
|
|
2604
|
-
*
|
|
2167
|
+
* `TSource` is inferred from an intersection parameter, which is fragile. If it
|
|
2168
|
+
* ever stops binding the source's summary it falls back to `unknown`, these
|
|
2169
|
+
* ledgers come out empty, and every check behind the helper switches off
|
|
2170
|
+
* SILENTLY, with nothing failing to compile. The forwarding case in
|
|
2171
|
+
* `select-exports.test.ts` is the only thing that catches that, so it is
|
|
2172
|
+
* load-bearing rather than illustrative.
|
|
2605
2173
|
*/
|
|
2606
|
-
type
|
|
2607
|
-
|
|
2608
|
-
|
|
2174
|
+
type ForwardedSummary<TSource> = PluginSummary<RequiresOf<TSource>, ProvidesOf<TSource>, RequiredContractsOf<TSource>, ProvidedContractsOf<TSource>>;
|
|
2175
|
+
/** The `PluginSummary` a `declarePlugin` declaration carries: its id in the
|
|
2176
|
+
* requirements ledger, plus the contracts its export stand-ins declared, read
|
|
2177
|
+
* once at the call site per the rule on {@link AggregateSummaryOf}. */
|
|
2178
|
+
type AggregateDeclarationSummary<TId extends string, TRequiredContracts extends ContractEntry> = PluginSummary<TId, never, TRequiredContracts, never>;
|
|
2179
|
+
/** The `PluginSummary` a required declaration carries: its id in the
|
|
2180
|
+
* requirements ledger, and the contract every provider of that id must honor. */
|
|
2181
|
+
type DeclarationSummary<TId extends string, TBinding> = PluginSummary<TId, never, ContractEntry<TId, TBinding>, never>;
|
|
2182
|
+
/** The optional twin of {@link DeclarationSummary}: it claims no slot, so it is
|
|
2183
|
+
* never a missing dependency, but a provider that DOES appear under the id
|
|
2184
|
+
* still has to honor the contract. */
|
|
2185
|
+
type OptionalDeclarationSummary<TId extends string, TBinding> = PluginSummary<never, never, ContractEntry<TId, TBinding>, never>;
|
|
2609
2186
|
/**
|
|
2610
|
-
*
|
|
2611
|
-
*
|
|
2612
|
-
*
|
|
2613
|
-
*
|
|
2187
|
+
* The runtime-input channel for `createSdk`. `configuration` maps plugin ids to
|
|
2188
|
+
* immutable values; each entry materializes as a static value property under
|
|
2189
|
+
* that id, satisfying a `declareProperty` / `declareOptionalProperty` stand-in exactly
|
|
2190
|
+
* as a registered provider would (DI value injection). Strict at build time:
|
|
2191
|
+
* an id must resolve to a property stand-in reachable from the root, so
|
|
2192
|
+
* unknown ids, non-property targets, and collisions with a registered real
|
|
2193
|
+
* provider all throw. kitcore keeps the map untyped; a head's factory is the
|
|
2194
|
+
* typed wrapper (`createMySdk(options)` passes
|
|
2195
|
+
* `{ configuration: { "my/config": options } }`).
|
|
2614
2196
|
*/
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
}
|
|
2197
|
+
interface CreateSdkOptions {
|
|
2198
|
+
configuration?: Record<string, unknown>;
|
|
2199
|
+
}
|
|
2618
2200
|
/**
|
|
2619
|
-
*
|
|
2620
|
-
* result is an object that has every property of every member at once.
|
|
2621
|
-
*
|
|
2622
|
-
* IntersectAll<[{ api }, { options }]> = { api } & { options }
|
|
2623
|
-
* IntersectAll<[]> = {}
|
|
2201
|
+
* Surfaced by `createSdk` when reachable declarations have no provider.
|
|
2624
2202
|
*
|
|
2625
|
-
*
|
|
2626
|
-
*
|
|
2627
|
-
*
|
|
2628
|
-
* both `api` AND `options` — not "either api or options."
|
|
2629
|
-
*/
|
|
2630
|
-
type IntersectAll<T extends readonly unknown[]> = T extends readonly [
|
|
2631
|
-
infer Head,
|
|
2632
|
-
...infer Tail
|
|
2633
|
-
] ? Head & IntersectAll<Tail> : {};
|
|
2634
|
-
/**
|
|
2635
|
-
* The TSdk a composed plugin requires: every sub-plugin's TSdk requirement,
|
|
2636
|
-
* all at once. Composing a plugin that needs `{ api }` with one that needs
|
|
2637
|
-
* `{ options }` yields a composed plugin that needs `{ api } & { options }`.
|
|
2203
|
+
* The guard names the property it checks (`CompletenessOf`) and the brand
|
|
2204
|
+
* names the fault, so the pair shares no root. That is deliberate: "missing"
|
|
2205
|
+
* tells a reader what to do, where "incomplete" only restates the property.
|
|
2638
2206
|
*/
|
|
2639
|
-
|
|
2207
|
+
interface MissingProviders<TIds extends string> {
|
|
2208
|
+
readonly __kitcoreError: "Missing concrete provider(s) for required declaration id(s)";
|
|
2209
|
+
readonly missing: TIds;
|
|
2210
|
+
}
|
|
2640
2211
|
/**
|
|
2641
|
-
*
|
|
2642
|
-
*
|
|
2643
|
-
*
|
|
2212
|
+
* `unknown` when every reachable declaration is provided, otherwise a
|
|
2213
|
+
* `MissingProviders` brand. `createSdk` takes `root: P & CompletenessOf<P>`,
|
|
2214
|
+
* so a complete root infers `P` unchanged (intersect `unknown`) while an
|
|
2215
|
+
* incomplete one fails to assign (the argument lacks `missing`).
|
|
2644
2216
|
*/
|
|
2645
|
-
type
|
|
2217
|
+
type CompletenessOf<P> = [
|
|
2218
|
+
Exclude<RequiresOf<P>, ProvidesOf<P>>
|
|
2219
|
+
] extends [never] ? unknown : MissingProviders<Exclude<RequiresOf<P>, ProvidesOf<P>>>;
|
|
2220
|
+
/** The provided entries registered under one id. */
|
|
2221
|
+
type ProvidersFor<TProvided extends ContractEntry, TId extends string> = Extract<TProvided, {
|
|
2222
|
+
readonly id: TId;
|
|
2223
|
+
}>;
|
|
2646
2224
|
/**
|
|
2647
|
-
*
|
|
2648
|
-
* collision-detection and hook-composition behavior and supports
|
|
2649
|
-
* per-step `{ override: true }` for intentional duplicates. Migration
|
|
2650
|
-
* (note the stack emits a definition, not a bare function):
|
|
2651
|
-
*
|
|
2652
|
-
* composePlugins(a, b, c)
|
|
2653
|
-
* // →
|
|
2654
|
-
* createPluginStack().use(a).use(b).use(c).toPlugin({ name: "bundle" })
|
|
2225
|
+
* The ids whose reachable providers do not all honor the declared contract.
|
|
2655
2226
|
*
|
|
2656
|
-
*
|
|
2657
|
-
*
|
|
2658
|
-
*
|
|
2659
|
-
*
|
|
2660
|
-
* one sub-plugin's contributions to another).
|
|
2661
|
-
*/
|
|
2662
|
-
declare function composePlugins<const Ts extends readonly Plugin<any, any>[]>(...plugins: Ts): Plugin<ComposeSdk<Ts>, ComposeProvides<Ts>>;
|
|
2663
|
-
/**
|
|
2664
|
-
* A typed builder that accumulates plugins into an immutable linked list.
|
|
2665
|
-
* Each `.use` returns a new stack instance (cons-style); the original
|
|
2666
|
-
* stack stays usable for branching. Call `toPlugin()` to collapse the
|
|
2667
|
-
* accumulated chain into a single `Plugin<TRequires, TProvides>`.
|
|
2227
|
+
* EVERY provider under an id must honor it, not just one: `declareDefault` lets
|
|
2228
|
+
* a default coexist with an explicit provider, so "some compatible provider
|
|
2229
|
+
* exists" would pass a good default beside a bad explicit one while the runtime
|
|
2230
|
+
* picks the bad one.
|
|
2668
2231
|
*
|
|
2669
|
-
*
|
|
2670
|
-
*
|
|
2671
|
-
* `TProvides` accumulates every registration's provides.
|
|
2232
|
+
* An id with no provider yields nothing here. That is `CompletenessOf`'s
|
|
2233
|
+
* report, and two errors for one cause read worse than one.
|
|
2672
2234
|
*/
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
*
|
|
2683
|
-
* `{ override: true }` lets a registration replace an earlier root/meta
|
|
2684
|
-
* key it would otherwise collide with.
|
|
2685
|
-
*/
|
|
2686
|
-
use<TNewProvides extends PluginProvides>(plugin: Plugin<TRequires & TProvides, TNewProvides>, options?: {
|
|
2687
|
-
override?: boolean;
|
|
2688
|
-
}): PluginStack<TRequires, TProvides & TNewProvides>;
|
|
2689
|
-
/**
|
|
2690
|
-
* Collapse the accumulated registrations into a single bare function
|
|
2691
|
-
* plugin. Its TSdk is `TRequires` (the declared external surface);
|
|
2692
|
-
* in-stack inter-plugin dependencies are resolved when its setup runs.
|
|
2693
|
-
* A head lifts it into the module model with `fromFunctionPlugin`.
|
|
2694
|
-
*/
|
|
2695
|
-
toPlugin(): Plugin<TRequires, TProvides>;
|
|
2696
|
-
/**
|
|
2697
|
-
* Build the stack into a sealed, ready-to-use SDK. Eagerly applies the
|
|
2698
|
-
* resolved order: each plugin runs once during `toSdk`, contributions
|
|
2699
|
-
* merge into a single accumulator, and the result is wrapped as an
|
|
2700
|
-
* `Sdk<TRequires & TProvides>`. The returned SDK has `context` and
|
|
2701
|
-
* `getRegistry`, but no plugin-registration method.
|
|
2702
|
-
* To extend a built SDK, use the top-level {@link addPlugin}.
|
|
2703
|
-
*/
|
|
2704
|
-
toSdk(): Sdk<TRequires & TProvides>;
|
|
2705
|
-
}
|
|
2235
|
+
type IncompatibleIds<TRequired extends ContractEntry, TProvided extends ContractEntry> = TRequired extends ContractEntry ? MismatchedProviders<TRequired, ProvidersFor<TProvided, TRequired["id"]>> : never;
|
|
2236
|
+
/** The required id, once per provider of it that fails the contract. An id with
|
|
2237
|
+
* no provider yields `never` here, since a distributive conditional over
|
|
2238
|
+
* `never` is `never`. */
|
|
2239
|
+
type MismatchedProviders<TRequired extends ContractEntry, TCandidate extends ContractEntry> = TCandidate extends ContractEntry ? [TCandidate["binding"]] extends [TRequired["binding"]] ? never : ServesEveryDeclaredCall<TCandidate["binding"], TRequired["binding"]> extends true ? never : TRequired["id"] : never;
|
|
2240
|
+
/** The keys a caller of `T` must supply. */
|
|
2241
|
+
type RequiredKeys<T> = keyof {
|
|
2242
|
+
[K in keyof T as {} extends Pick<T, K> ? never : K]: unknown;
|
|
2243
|
+
};
|
|
2706
2244
|
/**
|
|
2707
|
-
*
|
|
2708
|
-
*
|
|
2709
|
-
*
|
|
2710
|
-
* const tablesPlugin = createPluginStack<FetchPluginProvides>()
|
|
2711
|
-
* .use(apiPlugin)
|
|
2712
|
-
* .use(listTablesPlugin)
|
|
2713
|
-
* .use(getTablePlugin)
|
|
2714
|
-
* .toPlugin({ name: "tables" });
|
|
2245
|
+
* Rescues a provider that whole-function assignability rejects for a reason
|
|
2246
|
+
* that does not apply here.
|
|
2715
2247
|
*
|
|
2716
|
-
*
|
|
2717
|
-
*
|
|
2718
|
-
*
|
|
2719
|
-
*
|
|
2248
|
+
* TypeScript's weak-type rule refuses to relate two object types that share no
|
|
2249
|
+
* properties, even when the target needs none of them. So a declaration
|
|
2250
|
+
* promising `{ search: string }` failed against a provider taking
|
|
2251
|
+
* `{ locale?: string }`, though that provider requires nothing and reads
|
|
2252
|
+
* nothing the declaration sends. That contradicts the rule this check is built
|
|
2253
|
+
* on, which is that a provider may accept WIDER input.
|
|
2720
2254
|
*
|
|
2721
|
-
* The
|
|
2722
|
-
*
|
|
2723
|
-
*
|
|
2724
|
-
* run.
|
|
2255
|
+
* The escape stays sound by demanding all three: the output is still a subtype,
|
|
2256
|
+
* the provider requires no input field, and the two inputs share no key, so
|
|
2257
|
+
* there is no field the provider can read at a type it does not expect.
|
|
2725
2258
|
*/
|
|
2259
|
+
type ServesEveryDeclaredCall<TProvided, TRequired> = TRequired extends (...args: infer TDeclaredArgs) => infer TDeclaredOut ? TProvided extends (...args: infer TProviderArgs) => infer TProviderOut ? [TProviderOut] extends [TDeclaredOut] ? [TDeclaredArgs] extends [readonly [unknown?]] ? [TProviderArgs] extends [readonly [unknown?]] ? [
|
|
2260
|
+
Extract<keyof NonNullable<TDeclaredArgs[0]>, keyof NonNullable<TProviderArgs[0]>>
|
|
2261
|
+
] extends [never] ? [RequiredKeys<NonNullable<TProviderArgs[0]>>] extends [never] ? true : false : false : false : false : false : false : false;
|
|
2262
|
+
/** Surfaced by `createSdk` when a provider contradicts its declaration. */
|
|
2263
|
+
interface IncompatibleProviders<TIds extends string> {
|
|
2264
|
+
readonly __kitcoreError: "Provider(s) do not match the contract declared for the id(s); a provider may accept wider input but must return a subtype of the declared output";
|
|
2265
|
+
readonly incompatible: TIds;
|
|
2266
|
+
}
|
|
2726
2267
|
/**
|
|
2727
|
-
*
|
|
2728
|
-
*
|
|
2268
|
+
* `unknown` when every provided id honors the contract declared for it,
|
|
2269
|
+
* otherwise an `IncompatibleProviders` brand. `createSdk` takes
|
|
2270
|
+
* `root: P & CompletenessOf<P> & CompatibilityOf<P>`, so a sound graph infers
|
|
2271
|
+
* `P` unchanged (intersect `unknown`) while an unsound one fails to assign.
|
|
2729
2272
|
*/
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2273
|
+
type CompatibilityOf<P> = IncompatibleIds<RequiredContractsOf<P>, ProvidedContractsOf<P>> extends infer TIds extends string ? [TIds] extends [never] ? unknown : IncompatibleProviders<TIds> : never;
|
|
2274
|
+
/** Recover the materialized SDK type for a checked root (the summary that
|
|
2275
|
+
* rides on the `define*` return is transparent to these). */
|
|
2276
|
+
type MethodSdkOf<P> = P extends MethodPlugin<infer TName, infer TInput, infer TOutput, infer TPos> ? Sdk<TName, TInput, TOutput, TPos> : never;
|
|
2277
|
+
type PropertySdkOf<P> = P extends PropertyPlugin<infer TName, infer TValue> ? PropertySdk<TName, TValue> : never;
|
|
2278
|
+
type AggregateSdkOf<P> = P extends AggregatePlugin<string, infer TExports> ? AggregateSdk<TExports> : never;
|
|
2736
2279
|
|
|
2737
2280
|
/**
|
|
2738
2281
|
* Reject a LIST stand-in from the ref form, at the REF rather than at `run`.
|
|
@@ -2792,7 +2335,11 @@ declare function defineMethod<const TName extends string, TInput, TOutput, const
|
|
|
2792
2335
|
input?: unknown;
|
|
2793
2336
|
}) => void | Promise<void>;
|
|
2794
2337
|
run: (bag: MethodRunBag<ImportsOf<TImports>, TInput, TState>) => TOutput;
|
|
2795
|
-
|
|
2338
|
+
/** Validates and strips the output, and describes it for the registry. */
|
|
2339
|
+
outputSchema?: z.ZodSchema;
|
|
2340
|
+
/** Skip validating and stripping the output against `outputSchema`. */
|
|
2341
|
+
skipOutputValidation?: boolean;
|
|
2342
|
+
} & MethodMeta): MethodPlugin<TName, TInput, TOutput, TPositional> & LeafSummary<TNamespace, TName, TImports, MethodContract<TInput, TOutput, TPositional>>;
|
|
2796
2343
|
declare function defineMethod<const TName extends string, TInput, TResponse extends StrictItem<TResponse>, TData = DataOf<TResponse>, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", TState = undefined>(config: {
|
|
2797
2344
|
name: TName;
|
|
2798
2345
|
namespace?: TNamespace;
|
|
@@ -2813,14 +2360,18 @@ declare function defineMethod<const TName extends string, TInput, TResponse exte
|
|
|
2813
2360
|
input?: unknown;
|
|
2814
2361
|
}) => void | Promise<void>;
|
|
2815
2362
|
run: (bag: MethodRunBag<ImportsOf<TImports>, TInput, TState>) => TResponse | Promise<TResponse>;
|
|
2816
|
-
|
|
2363
|
+
/** Validates and strips the output, and describes it for the registry. */
|
|
2364
|
+
outputSchema?: z.ZodSchema;
|
|
2365
|
+
/** Skip validating and stripping the output against `outputSchema`. */
|
|
2366
|
+
skipOutputValidation?: boolean;
|
|
2367
|
+
} & MethodMeta): MethodPlugin<TName, TInput & CallOutputOptions, Promise<{
|
|
2817
2368
|
data: TData;
|
|
2818
2369
|
meta?: ResponseMeta;
|
|
2819
2370
|
}>, readonly [], ItemRunInput<TInput>> & LeafSummary<TNamespace, TName, TImports, MethodContract<CallContractInput<TInput, CallOutputOptions>, Promise<{
|
|
2820
2371
|
data: TData;
|
|
2821
2372
|
meta?: ResponseMeta;
|
|
2822
2373
|
}>>>;
|
|
2823
|
-
declare function defineMethod<const TName extends string, TInput, TResponse extends StrictPage
|
|
2374
|
+
declare function defineMethod<const TName extends string, TInput, TResponse extends StrictPage<TResponse>, TItem = ItemOf<TResponse>, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", TState = undefined>(config: {
|
|
2824
2375
|
name: TName;
|
|
2825
2376
|
namespace?: TNamespace;
|
|
2826
2377
|
imports?: TImports & StaticList<TImports>;
|
|
@@ -2842,7 +2393,11 @@ declare function defineMethod<const TName extends string, TInput, TResponse exte
|
|
|
2842
2393
|
input?: unknown;
|
|
2843
2394
|
}) => void | Promise<void>;
|
|
2844
2395
|
run: (bag: MethodRunBag<ImportsOf<TImports>, TInput & PageFetchInput, TState>) => TResponse | Promise<TResponse>;
|
|
2845
|
-
|
|
2396
|
+
/** Validates and strips the output, and describes it for the registry. */
|
|
2397
|
+
outputSchema?: z.ZodSchema;
|
|
2398
|
+
/** Skip validating and stripping the output against `outputSchema`. */
|
|
2399
|
+
skipOutputValidation?: boolean;
|
|
2400
|
+
} & MethodMeta): MethodPlugin<TName, TInput & PaginatedCallInput & CallOutputOptions, PaginatedSdkResult<TItem>, readonly [], ListRunInput<TInput>> & LeafSummary<TNamespace, TName, TImports, MethodContract<CallContractInput<TInput, PaginatedCallInput & CallOutputOptions>, PaginatedSdkResult<TItem>>>;
|
|
2846
2401
|
declare function defineMethod<const TName extends string, TInput, TResponse, TItem, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", TState = undefined>(config: {
|
|
2847
2402
|
name: TName;
|
|
2848
2403
|
namespace?: TNamespace;
|
|
@@ -2865,7 +2420,11 @@ declare function defineMethod<const TName extends string, TInput, TResponse, TIt
|
|
|
2865
2420
|
input?: unknown;
|
|
2866
2421
|
}) => void | Promise<void>;
|
|
2867
2422
|
run: (bag: MethodRunBag<ImportsOf<TImports>, TInput & PageFetchInput, TState>) => TResponse | Promise<TResponse>;
|
|
2868
|
-
|
|
2423
|
+
/** Validates and strips the output, and describes it for the registry. */
|
|
2424
|
+
outputSchema?: z.ZodSchema;
|
|
2425
|
+
/** Skip validating and stripping the output against `outputSchema`. */
|
|
2426
|
+
skipOutputValidation?: boolean;
|
|
2427
|
+
} & MethodMeta): MethodPlugin<TName, TInput & PaginatedCallInput & CallOutputOptions, PaginatedSdkResult<TItem>, readonly [], ListRunInput<TInput>> & LeafSummary<TNamespace, TName, TImports, MethodContract<CallContractInput<TInput, PaginatedCallInput & CallOutputOptions>, PaginatedSdkResult<TItem>>>;
|
|
2869
2428
|
declare function defineMethod<const TName extends string, TInput, TOutput, const TId extends string, const TImports extends ImportsInput = readonly [], TState = undefined>(ref: MethodPlugin<TName, TInput, TOutput> & StandInId<TId> & RefFormRawOnly<TOutput>, config: {
|
|
2870
2429
|
imports?: TImports & StaticList<TImports>;
|
|
2871
2430
|
inputSchema?: z.ZodType<TInput>;
|
|
@@ -2881,7 +2440,11 @@ declare function defineMethod<const TName extends string, TInput, TOutput, const
|
|
|
2881
2440
|
input?: unknown;
|
|
2882
2441
|
}) => void | Promise<void>;
|
|
2883
2442
|
run: (bag: MethodRunBag<ImportsOf<TImports>, NoInfer<TInput>, TState>) => NoInfer<TOutput>;
|
|
2884
|
-
|
|
2443
|
+
/** Validates and strips the output, and describes it for the registry. */
|
|
2444
|
+
outputSchema?: z.ZodSchema;
|
|
2445
|
+
/** Skip validating and stripping the output against `outputSchema`. */
|
|
2446
|
+
skipOutputValidation?: boolean;
|
|
2447
|
+
} & MethodMeta): MethodPlugin<TName, TInput, TOutput> & LeafSummaryById<TId, TImports, MethodContract<TInput, TOutput>>;
|
|
2885
2448
|
/**
|
|
2886
2449
|
* Patch how a surface PRESENTS an already-defined method, by reference. Pass
|
|
2887
2450
|
* the method (or its `declareMethod` stand-in) and any of
|
|
@@ -3096,7 +2659,7 @@ declare function defineProperty<const TName extends string, TValue, const TNames
|
|
|
3096
2659
|
name: TName;
|
|
3097
2660
|
namespace?: TNamespace;
|
|
3098
2661
|
value: TValue;
|
|
3099
|
-
} &
|
|
2662
|
+
} & PropertyMeta): PropertyPlugin<TName, TValue> & LeafSummary<TNamespace, TName, readonly [], TValue>;
|
|
3100
2663
|
declare function defineProperty<const TName extends string, TValue, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", TState = undefined>(config: {
|
|
3101
2664
|
name: TName;
|
|
3102
2665
|
namespace?: TNamespace;
|
|
@@ -3123,7 +2686,7 @@ declare function defineProperty<const TName extends string, TValue, const TImpor
|
|
|
3123
2686
|
/** Templated registry members for this property's dynamic sub-surface (e.g.
|
|
3124
2687
|
* a proxy): each a bodyless declaration keyed by `path` instead of `name`. */
|
|
3125
2688
|
dynamicMembers?: readonly DynamicMember[];
|
|
3126
|
-
} &
|
|
2689
|
+
} & PropertyMeta): PropertyPlugin<TName, TValue> & LeafSummary<TNamespace, TName, TImports, TValue>;
|
|
3127
2690
|
/**
|
|
3128
2691
|
* Provide a value for a declared property BY REFERENCE: pass the
|
|
3129
2692
|
* `declareProperty` / `declareOptionalProperty` stand-in instead of respelling
|
|
@@ -3134,7 +2697,7 @@ declare function defineProperty<const TName extends string, TValue, const TImpor
|
|
|
3134
2697
|
*/
|
|
3135
2698
|
declare function defineProperty<const TName extends string, TValue, const TId extends string>(ref: PropertyPlugin<TName, TValue> & StandInId<TId>, config: {
|
|
3136
2699
|
value: NoInfer<TValue>;
|
|
3137
|
-
} &
|
|
2700
|
+
} & PropertyMeta): PropertyPlugin<TName, TValue> & PluginSummary<never, TId, never, ContractEntry<TId, TValue>>;
|
|
3138
2701
|
/**
|
|
3139
2702
|
* Declare a stand-in for a property registered elsewhere (a configured factory
|
|
3140
2703
|
* plugin, e.g. the api client built from options). Carries only a name and a
|
|
@@ -3181,10 +2744,8 @@ declare function declareDefault<P extends AnyLeafPlugin>({ plugin, }: {
|
|
|
3181
2744
|
* Define a method-lifecycle hook: a leaf whose `observe` contributes
|
|
3182
2745
|
* fire-and-forget observers (`onMethodStart` / `onMethodEnd`) the method
|
|
3183
2746
|
* boundary fires around every method, and whose `wrap` contributes
|
|
3184
|
-
* contract-preserving middleware around imported methods. This is
|
|
3185
|
-
*
|
|
3186
|
-
* to a legacy plugin writing `context.hooks` and to `definePlugin`'s
|
|
3187
|
-
* deleted `middleware` map).
|
|
2747
|
+
* contract-preserving middleware around imported methods. This is the one way a
|
|
2748
|
+
* plugin provides cross-cutting behavior.
|
|
3188
2749
|
*
|
|
3189
2750
|
* `setup` runs once and owns the hook's state (e.g. a telemetry queue),
|
|
3190
2751
|
* delivered to the observers. Each observer's bag
|
|
@@ -3244,26 +2805,6 @@ declare function declarePlugin<const TId extends string, const TExports extends
|
|
|
3244
2805
|
id: LiteralString<TId>;
|
|
3245
2806
|
exports?: TExports & StaticList<TExports>;
|
|
3246
2807
|
}): AggregatePlugin<LastSegment<TId>, ArrayExports<TExports>> & AggregateDeclarationSummary<TId, RequiredContractsIn<TExports>>;
|
|
3247
|
-
/**
|
|
3248
|
-
* Function form — the legacy function-plugin identity wrapper: it returns the
|
|
3249
|
-
* function unchanged but constrains its return to `PluginProvides` and
|
|
3250
|
-
* preserves the narrow inferred shape, so callers derive `*PluginProvides` via
|
|
3251
|
-
* `ReturnType<typeof plugin>`. Such a plugin runs through the legacy bridge
|
|
3252
|
-
* (`fromFunctionPlugin` / `createPluginStack`), deprecated with it.
|
|
3253
|
-
*
|
|
3254
|
-
* @deprecated Author plugins with `defineMethod` / `defineProperty` /
|
|
3255
|
-
* object-form `definePlugin` instead. This form logs a runtime deprecation and
|
|
3256
|
-
* will be removed in a release after the warning ships.
|
|
3257
|
-
*/
|
|
3258
|
-
declare function definePlugin<TSdk, TProvides extends PluginProvides>(fn: (sdk: TSdk & {
|
|
3259
|
-
context: {
|
|
3260
|
-
meta: Record<string, PluginMeta>;
|
|
3261
|
-
};
|
|
3262
|
-
}) => TProvides): (sdk: TSdk & {
|
|
3263
|
-
context: {
|
|
3264
|
-
meta: Record<string, PluginMeta>;
|
|
3265
|
-
};
|
|
3266
|
-
}) => TProvides;
|
|
3267
2808
|
/**
|
|
3268
2809
|
* Define a plugin module: an aggregate that re-exports child plugins.
|
|
3269
2810
|
* `exports` mirrors `imports`: an array where a leaf binds under its own name
|
|
@@ -3272,12 +2813,12 @@ declare function definePlugin<TSdk, TProvides extends PluginProvides>(fn: (sdk:
|
|
|
3272
2813
|
* imports-only module can omit it. Re-exporting implies a dependency on the
|
|
3273
2814
|
* child. To wrap imported methods, export a `defineHook` with `wrap`.
|
|
3274
2815
|
*/
|
|
3275
|
-
declare function definePlugin<const TName extends string, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", const TExports extends readonly
|
|
2816
|
+
declare function definePlugin<const TName extends string, const TImports extends ImportsInput = readonly [], const TNamespace extends string = "", const TExports extends readonly unknown[] = readonly []>(config: {
|
|
3276
2817
|
name: TName;
|
|
3277
2818
|
namespace?: TNamespace;
|
|
3278
2819
|
imports?: TImports & StaticList<TImports>;
|
|
3279
|
-
exports?: TExports & StaticList<TExports>;
|
|
3280
|
-
}): AggregatePlugin<TName, ArrayExports<TExports
|
|
2820
|
+
exports?: TExports & StaticList<TExports> & PluginList<TExports>;
|
|
2821
|
+
}): AggregatePlugin<TName, AsExports<ArrayExports<Extract<TExports, ExportsInput>>>> & AggregateSummary<TNamespace, TName, TImports, TExports>;
|
|
3281
2822
|
|
|
3282
2823
|
/**
|
|
3283
2824
|
* A `selectExports` spec: a bare export name to keep (`"getApp"`), or a rename
|
|
@@ -3294,9 +2835,6 @@ type ResolveSpec<TExports extends Record<string, AnyLeafPlugin>, S> = S extends
|
|
|
3294
2835
|
} : never : {
|
|
3295
2836
|
[K in keyof S]: S[K] extends keyof TExports ? TExports[S[K]] : never;
|
|
3296
2837
|
};
|
|
3297
|
-
/** Ensure the computed export record satisfies the `AggregatePlugin` constraint
|
|
3298
|
-
* (an empty/degenerate selection collapses to a bare exports record). */
|
|
3299
|
-
type AsExports<T> = T extends Record<string, AnyLeafPlugin> ? T : Record<string, AnyLeafPlugin>;
|
|
3300
2838
|
/**
|
|
3301
2839
|
* Select (and optionally rename) a subset of a module's exports, the ES
|
|
3302
2840
|
* `{ a, b, c as d }` clause. Works the same in `imports` (import) and
|
|
@@ -3321,47 +2859,13 @@ declare function selectExports<TExports extends Record<string, AnyLeafPlugin>, c
|
|
|
3321
2859
|
*/
|
|
3322
2860
|
declare function omitExports<TExports extends Record<string, AnyLeafPlugin>, const TOmit extends readonly (keyof TExports & string)[], TSource = unknown>(source: AggregatePlugin<string, TExports> & TSource, omit: TOmit): AggregatePlugin<string, Omit<TExports, TOmit[number]>> & ForwardedSummary<TSource>;
|
|
3323
2861
|
|
|
3324
|
-
/**
|
|
3325
|
-
* Lift a legacy function plugin into the module model. The
|
|
3326
|
-
* returned plugin runs `fn` at materialization and surfaces its root methods;
|
|
3327
|
-
* `createPluginStack().toPlugin()` is built on this, and `addPlugin` uses it for
|
|
3328
|
-
* external function plugins. `fn`'s `context` contributions merge into the live
|
|
3329
|
-
* `SdkContext`; its other root keys become the surface.
|
|
3330
|
-
*
|
|
3331
|
-
* @deprecated The module model replaces this exit; it logs a runtime
|
|
3332
|
-
* deprecation and will be removed in a release after this warning ships.
|
|
3333
|
-
*/
|
|
3334
|
-
declare function fromFunctionPlugin<TProvides extends PluginProvides>(fn: (sdk: any) => TProvides, config: {
|
|
3335
|
-
name: string;
|
|
3336
|
-
namespace?: string;
|
|
3337
|
-
}): LegacyPlugin<TProvides & {
|
|
3338
|
-
getRegistry: (options?: {
|
|
3339
|
-
package?: string;
|
|
3340
|
-
}) => RegistryResult;
|
|
3341
|
-
}>;
|
|
3342
|
-
/**
|
|
3343
|
-
* Build a {@link LegacyMergePlugin}: pass the collapsed legacy stack
|
|
3344
|
-
* (`stack.toPlugin()`) as `legacy` and the migrated module-model plugins as
|
|
3345
|
-
* `plugin`. `createSdk(defineLegacyMerge({...}))` surfaces both.
|
|
3346
|
-
*
|
|
3347
|
-
* @deprecated Build directly with `createSdk(root, { configuration })`
|
|
3348
|
-
* instead; it logs a runtime deprecation and will be removed in a release
|
|
3349
|
-
* after this warning ships.
|
|
3350
|
-
*/
|
|
3351
|
-
declare function defineLegacyMerge<TProvides extends PluginProvides, const TPlugin extends AnyPlugin>(args: {
|
|
3352
|
-
name: string;
|
|
3353
|
-
namespace?: string;
|
|
3354
|
-
legacy: (sdk: any) => TProvides;
|
|
3355
|
-
plugin: TPlugin;
|
|
3356
|
-
}): LegacyMergePlugin<TProvides, TPlugin>;
|
|
3357
|
-
|
|
3358
2862
|
/**
|
|
3359
2863
|
* Core error machinery.
|
|
3360
2864
|
*
|
|
3361
2865
|
* kitcore constructs errors at two internal throw sites: input
|
|
3362
2866
|
* validation (`utils/validation.ts`) and non-Error normalization
|
|
3363
2867
|
* (`utils/function-utils.ts`'s `normalizeError`). Heads supply a
|
|
3364
|
-
* `adaptError` factory
|
|
2868
|
+
* `adaptError` factory under `CORE_OPTIONS_ID` to map kitcore's abstract
|
|
3365
2869
|
* `CoreErrorCode` values onto their own branded error classes; if
|
|
3366
2870
|
* no factory is supplied, kitcore falls back to constructing a plain
|
|
3367
2871
|
* `CoreError`. Either way, every kitcore-thrown error is brand-stamped
|
|
@@ -3386,6 +2890,13 @@ declare const CORE_ERROR_SYMBOL: unique symbol;
|
|
|
3386
2890
|
declare const CoreErrorCode: {
|
|
3387
2891
|
readonly Validation: "VALIDATION_ERROR";
|
|
3388
2892
|
readonly Unknown: "UNKNOWN_ERROR";
|
|
2893
|
+
/**
|
|
2894
|
+
* The object handed to a framework reader is not an SDK `createSdk` built, so
|
|
2895
|
+
* there is no plugin graph to read. A code rather than prose because a caller
|
|
2896
|
+
* distinguishing "no registry here" from "the registry failed to build" has to
|
|
2897
|
+
* match on something stable, and the message is not that.
|
|
2898
|
+
*/
|
|
2899
|
+
readonly NoSdkContext: "NO_SDK_CONTEXT_ERROR";
|
|
3389
2900
|
};
|
|
3390
2901
|
type CoreErrorCode = (typeof CoreErrorCode)[keyof typeof CoreErrorCode];
|
|
3391
2902
|
/**
|
|
@@ -3506,9 +3017,7 @@ interface StabilityNotice {
|
|
|
3506
3017
|
/**
|
|
3507
3018
|
* The well-known id for framework options: heads inject a `CoreOptions` bag
|
|
3508
3019
|
* under it via `createSdk`'s `configuration` (or register a property plugin),
|
|
3509
|
-
* and the method boundary resolves it by id at every invocation
|
|
3510
|
-
* to the legacy `context.core` write while the deprecated `createCorePlugin`
|
|
3511
|
-
* path still exists.
|
|
3020
|
+
* and the method boundary resolves it by id at every invocation.
|
|
3512
3021
|
*/
|
|
3513
3022
|
declare const CORE_OPTIONS_ID = "kitcore/coreOptions";
|
|
3514
3023
|
/**
|
|
@@ -3597,15 +3106,14 @@ declare const getRegistryPlugin: MethodPlugin<"getRegistry", {
|
|
|
3597
3106
|
package?: string | undefined;
|
|
3598
3107
|
} | undefined) => RegistryResult>;
|
|
3599
3108
|
|
|
3600
|
-
/** The off-surface
|
|
3109
|
+
/** The off-surface reader for an SDK's `SdkContext`. Throws when there is
|
|
3110
|
+
* none, because every caller dereferences the result at once. */
|
|
3601
3111
|
declare function getContext(sdk: unknown): SdkContext;
|
|
3602
3112
|
/**
|
|
3603
3113
|
* Read an SDK's registry from outside its surface, so a head need not re-export
|
|
3604
|
-
* `getRegistryPlugin` for a controller to introspect it.
|
|
3605
|
-
* through the shared, memoized {@link getCachedRegistry} (context-keyed, so
|
|
3606
|
-
* and a surfaced `getRegistry()` return the same object).
|
|
3607
|
-
* stack-built SDK has no `[CONTEXT]` graph; for those the only path is a
|
|
3608
|
-
* surfaced `getRegistry()`, so fall back to it when present. Each package
|
|
3114
|
+
* `getRegistryPlugin` for a controller to introspect it. A `createSdk` build
|
|
3115
|
+
* goes through the shared, memoized {@link getCachedRegistry} (context-keyed, so
|
|
3116
|
+
* this and a surfaced `getRegistry()` return the same object). Each package
|
|
3609
3117
|
* filter is memoized separately.
|
|
3610
3118
|
*/
|
|
3611
3119
|
declare function getRegistry(sdk: unknown, packageFilter?: string): RegistryResult;
|
|
@@ -3651,21 +3159,14 @@ declare function disposeSdk(sdk: unknown, input?: unknown): Promise<void>;
|
|
|
3651
3159
|
declare function createSdk<P extends AnyMethodPlugin>(root: P & CompletenessOf<P> & CompatibilityOf<P>, options?: CreateSdkOptions): MethodSdkOf<P>;
|
|
3652
3160
|
declare function createSdk<P extends AnyPropertyPlugin>(root: P & CompletenessOf<P> & CompatibilityOf<P>, options?: CreateSdkOptions): PropertySdkOf<P>;
|
|
3653
3161
|
declare function createSdk<P extends AnyAggregatePlugin>(root: P & CompletenessOf<P> & CompatibilityOf<P>, options?: CreateSdkOptions): AggregateSdkOf<P>;
|
|
3654
|
-
declare function createSdk<
|
|
3655
|
-
declare function createSdk<TProvides extends PluginProvides, TPlugin extends AnyPlugin>(root: LegacyMergePlugin<TProvides, TPlugin>, options?: CreateSdkOptions): TProvides & {
|
|
3656
|
-
getRegistry: (options?: {
|
|
3657
|
-
package?: string;
|
|
3658
|
-
}) => RegistryResult;
|
|
3659
|
-
} & AddedSurface<TPlugin> & SdkInternals;
|
|
3660
|
-
declare function createSdk<P extends AnyPlugin>(root: P & CompletenessOf<P> & CompatibilityOf<P>, options?: CreateSdkOptions): never;
|
|
3162
|
+
declare function createSdk<P extends Plugin>(root: P & CompletenessOf<P> & CompatibilityOf<P>, options?: CreateSdkOptions): never;
|
|
3661
3163
|
/**
|
|
3662
3164
|
* Extend an already-built SDK in place with one more plugin (the post-seal
|
|
3663
|
-
* extension path)
|
|
3664
|
-
*
|
|
3665
|
-
*
|
|
3666
|
-
* caller's `sdk` binding is narrowed to include the addition.
|
|
3165
|
+
* extension path): the plugin's not-yet-materialized graph is materialized
|
|
3166
|
+
* incrementally into the live graph, and the caller's `sdk` binding is narrowed
|
|
3167
|
+
* to include the addition.
|
|
3667
3168
|
*/
|
|
3668
|
-
declare function addPlugin<TSdk extends object, P>(sdk: TSdk, plugin: P, options?: {
|
|
3169
|
+
declare function addPlugin<TSdk extends object, P extends Plugin>(sdk: TSdk, plugin: P, options?: {
|
|
3669
3170
|
override?: boolean;
|
|
3670
3171
|
}): asserts sdk is TSdk & AddedSurface<P>;
|
|
3671
3172
|
|
|
@@ -4062,16 +3563,18 @@ interface Controller {
|
|
|
4062
3563
|
* What the driver needs of a built SDK: one of two ways to reach a registry.
|
|
4063
3564
|
*
|
|
4064
3565
|
* The registry is read with the free {@link getRegistry}, which finds it on the
|
|
4065
|
-
* SDK's context and falls back to a surfaced `getRegistry()` for
|
|
4066
|
-
*
|
|
4067
|
-
* SDK does not surface one, and it cannot always add `getRegistryPlugin`
|
|
3566
|
+
* SDK's context and falls back to a surfaced `getRegistry()` for an object that
|
|
3567
|
+
* carries no context. So demanding the surfaced method alone is wrong: a bare
|
|
3568
|
+
* tool SDK does not surface one, and it cannot always add `getRegistryPlugin`
|
|
4068
3569
|
* either, because a head bundling its own kitcore copy would collide with it on
|
|
4069
3570
|
* the shared `kitcore/getRegistry` id.
|
|
4070
3571
|
*
|
|
4071
3572
|
* A union, because those really are two different shapes. `SdkInternals` is
|
|
4072
|
-
* what every `createSdk` result carries
|
|
4073
|
-
*
|
|
4074
|
-
*
|
|
3573
|
+
* what every `createSdk` result carries; the structural branch covers whatever
|
|
3574
|
+
* else answers the registry contract, such as a test stub or a host wrapper
|
|
3575
|
+
* projecting someone else's registry. Anything else can never back a
|
|
3576
|
+
* controller, and saying so here beats an internal registry error on the
|
|
3577
|
+
* caller's first `listMethods()`.
|
|
4075
3578
|
*
|
|
4076
3579
|
* The context branch is `SdkInternals`, which declares the `[CONTEXT]` symbol
|
|
4077
3580
|
* materialization actually writes. So this checks the real thing rather than a
|
|
@@ -4090,167 +3593,6 @@ type ControllerSdk = SdkInternals | {
|
|
|
4090
3593
|
*/
|
|
4091
3594
|
declare function createController(sdk: ControllerSdk): Controller;
|
|
4092
3595
|
|
|
4093
|
-
/**
|
|
4094
|
-
* The floor the framework holds its own call parameters to, and the only
|
|
4095
|
-
* statement of their shapes. Which of them a given boundary reads at all is
|
|
4096
|
-
* that boundary's {@link FrameworkOptionsPolicy}.
|
|
4097
|
-
*
|
|
4098
|
-
* MINIMAL on purpose. It rejects what the machinery cannot act on and nothing
|
|
4099
|
-
* else, leaving a plugin free to tighten it. `pageSize` is at least 1 because a
|
|
4100
|
-
* page loop asking upstream for zero items does not terminate. `maxItems` may
|
|
4101
|
-
* be 0, since "return nothing" is a coherent request the loop already handles.
|
|
4102
|
-
* `cursor` is any string: its meaning belongs to the head's API, including
|
|
4103
|
-
* whatever a reverse-paginating one encodes in it.
|
|
4104
|
-
*
|
|
4105
|
-
* A plugin that wants a tighter rule writes it in its own `inputSchema`, and
|
|
4106
|
-
* both run. See {@link parseCallOptions}.
|
|
4107
|
-
*/
|
|
4108
|
-
declare const CallFrameworkOptionsSchema: z.ZodObject<{
|
|
4109
|
-
cursor: z.ZodOptional<z.ZodString>;
|
|
4110
|
-
pageSize: z.ZodOptional<z.ZodNumber>;
|
|
4111
|
-
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
4112
|
-
skipOutputDataValidation: z.ZodOptional<z.ZodBoolean>;
|
|
4113
|
-
}, z.core.$strip>;
|
|
4114
|
-
type CallFrameworkOptions = z.infer<typeof CallFrameworkOptionsSchema>;
|
|
4115
|
-
type CallFrameworkOptionKey = keyof CallFrameworkOptions;
|
|
4116
|
-
/**
|
|
4117
|
-
* What one boundary does with the framework's call parameters.
|
|
4118
|
-
*
|
|
4119
|
-
* There is no global answer, because the modes differ. A list call feeds a page
|
|
4120
|
-
* loop; an item call has no loop to feed; a legacy handler honors nothing the
|
|
4121
|
-
* framework added after it was written.
|
|
4122
|
-
*
|
|
4123
|
-
* This is a fact about the MODE, decided when the boundary is built. It says
|
|
4124
|
-
* nothing about the plugin's schema, which is the difference between this and
|
|
4125
|
-
* everything {@link parseCallOptions} used to infer.
|
|
4126
|
-
*/
|
|
4127
|
-
interface FrameworkOptionsPolicy {
|
|
4128
|
-
/** The parameters this boundary reads. Each is also held to
|
|
4129
|
-
* {@link CallFrameworkOptionsSchema}, whatever the plugin's schema says. */
|
|
4130
|
-
claims: readonly CallFrameworkOptionKey[];
|
|
4131
|
-
/** The subset handed to `run` even when the plugin's schema dropped it,
|
|
4132
|
-
* because `run` cannot do its job without it. A list `run` is asked for one
|
|
4133
|
-
* page, so it gets that page. */
|
|
4134
|
-
injects: readonly CallFrameworkOptionKey[];
|
|
4135
|
-
}
|
|
4136
|
-
|
|
4137
|
-
/**
|
|
4138
|
-
* Generic utility functions for creating SDK-method wrappers.
|
|
4139
|
-
*
|
|
4140
|
-
* Both `createFunction` and `createPaginatedFunction` accept the SDK
|
|
4141
|
-
* as a parameter and read framework state (`hooks`, `core.adaptError`)
|
|
4142
|
-
* live from `sdk.context.*` at method-invocation time. Plugins registered
|
|
4143
|
-
* after a method is built still observe and configure it; ordering of
|
|
4144
|
-
* plugin registration doesn't change runtime semantics. (Pagination's
|
|
4145
|
-
* `adaptPage` is passed in per method, not read from context.)
|
|
4146
|
-
*/
|
|
4147
|
-
|
|
4148
|
-
/**
|
|
4149
|
-
* Minimal SDK shape the function wrappers accept. The wrappers only
|
|
4150
|
-
* touch `context.hooks` and the resolved core options, but we keep
|
|
4151
|
-
* `context` typed as `unknown` so any kitcore-built SDK (whose context type
|
|
4152
|
-
* widens unpredictably as plugins layer on) flows through without
|
|
4153
|
-
* upstream type narrowing. Each read inside is asserted at the use
|
|
4154
|
-
* site against the small slice we actually need.
|
|
4155
|
-
*/
|
|
4156
|
-
type FunctionSdk = {
|
|
4157
|
-
context: unknown;
|
|
4158
|
-
};
|
|
4159
|
-
/**
|
|
4160
|
-
* Wrap a core async function with input validation, error normalization,
|
|
4161
|
-
* and method-call lifecycle hooks. Hooks and `adaptError` are read live
|
|
4162
|
-
* from `sdk.context.*` at every invocation, so a plugin registered
|
|
4163
|
-
* after this method is built still observes and configures it.
|
|
4164
|
-
*
|
|
4165
|
-
* @param coreFn - the underlying async function to wrap
|
|
4166
|
-
* @param options.sdk - the SDK (or sub-SDK view) providing `context.hooks`
|
|
4167
|
-
* and `context.core`
|
|
4168
|
-
* @param options.schema - optional Zod schema for input validation
|
|
4169
|
-
*/
|
|
4170
|
-
declare function createFunction<TOptions, TResult, TSchemaOptions extends TOptions = TOptions>(coreFn: (options: TOptions, context?: CallContext) => Promise<TResult>, options: {
|
|
4171
|
-
sdk: FunctionSdk;
|
|
4172
|
-
schema?: z.ZodSchema<TSchemaOptions>;
|
|
4173
|
-
name?: string;
|
|
4174
|
-
/** Pre-run per-method annotator (see applyAnnotations): invoked before
|
|
4175
|
-
* onMethodStart with the normalized input, its result merged into the
|
|
4176
|
-
* call's annotation bag. */
|
|
4177
|
-
annotator?: (input: unknown) => Annotations;
|
|
4178
|
-
/** Which framework call parameters this callable reads; see
|
|
4179
|
-
* `FrameworkOptionsPolicy`. Omitted means none, which is what a legacy
|
|
4180
|
-
* handler wants: nothing there honors a framework parameter, so every key
|
|
4181
|
-
* in the call object is the handler's own. */
|
|
4182
|
-
frameworkOptions?: FrameworkOptionsPolicy;
|
|
4183
|
-
/** Live read of the method's deprecation meta (see signalDeprecation). */
|
|
4184
|
-
getDeprecation?: () => FunctionDeprecation | undefined;
|
|
4185
|
-
/** Live read of the method's stability level (see signalStability). */
|
|
4186
|
-
getStability?: () => StabilityLevel | undefined;
|
|
4187
|
-
}): (callOptions?: TOptions) => Promise<TResult>;
|
|
4188
|
-
/**
|
|
4189
|
-
* Higher-order function that creates a paginated function that wraps
|
|
4190
|
-
* results in `SdkPage<TItem>`.
|
|
4191
|
-
*
|
|
4192
|
-
* @param coreFn - Function that returns T directly or throws errors
|
|
4193
|
-
* @returns A function that normalizes errors and wraps results in `SdkPage`
|
|
4194
|
-
*/
|
|
4195
|
-
/**
|
|
4196
|
-
* Extract the item type from a page handler's return shape. The handler
|
|
4197
|
-
* may return a flat `{ data: TItem[] }` (or single `data: TItem`), a bare
|
|
4198
|
-
* array, or anything else; in all cases the wrapper normalizes to
|
|
4199
|
-
* `SdkPage<TItem>` and this resolves the right `TItem`.
|
|
4200
|
-
*/
|
|
4201
|
-
type ItemType<TResult> = TResult extends {
|
|
4202
|
-
data: infer TData;
|
|
4203
|
-
} ? TData extends readonly (infer TItem)[] ? TItem : TData : TResult extends readonly (infer TItem)[] ? TItem : TResult;
|
|
4204
|
-
declare function createPaginatedFunction<TUserOptions, TResponse, TItem = ItemType<TResponse>>(coreFn: (options: TUserOptions & {
|
|
4205
|
-
cursor?: string;
|
|
4206
|
-
pageSize?: number;
|
|
4207
|
-
}, context?: CallContext) => Promise<TResponse>, options: {
|
|
4208
|
-
sdk: FunctionSdk;
|
|
4209
|
-
schema?: z.ZodSchema<TUserOptions>;
|
|
4210
|
-
name?: string;
|
|
4211
|
-
defaultPageSize?: number;
|
|
4212
|
-
/**
|
|
4213
|
-
* Translate the handler's raw `TResponse` into `SdkPage<TItem>`. `TItem`
|
|
4214
|
-
* is wrapped in `NoInfer`: it is sourced from `TResponse` (via the
|
|
4215
|
-
* `ItemType` default), not from this adapter, which is item-agnostic (it
|
|
4216
|
-
* relocates the cursor; items are finalized in the handler's `data`).
|
|
4217
|
-
* Without `NoInfer`, a generic adapter (e.g. `<T>(r) => SdkPage<T>`)
|
|
4218
|
-
* would collapse `TItem` to `unknown`.
|
|
4219
|
-
*/
|
|
4220
|
-
adaptPage?: (response: TResponse) => SdkPage<NoInfer<TItem>>;
|
|
4221
|
-
/** Pre-run per-method annotator (see applyAnnotations). */
|
|
4222
|
-
annotator?: (input: unknown) => Annotations;
|
|
4223
|
-
/** Applied to each canonical page after the shape guard (output validation),
|
|
4224
|
-
* with this call's options so it can read per-call controls. */
|
|
4225
|
-
finalizePage?: (page: SdkPage<TItem>, callOptions: unknown) => SdkPage<TItem>;
|
|
4226
|
-
/** Which framework call parameters this callable reads; see
|
|
4227
|
-
* `FrameworkOptionsPolicy`. */
|
|
4228
|
-
frameworkOptions?: FrameworkOptionsPolicy;
|
|
4229
|
-
/** Live read of the method's deprecation meta (see signalDeprecation). */
|
|
4230
|
-
getDeprecation?: () => FunctionDeprecation | undefined;
|
|
4231
|
-
/** Live read of the method's stability level (see signalStability). */
|
|
4232
|
-
getStability?: () => StabilityLevel | undefined;
|
|
4233
|
-
}): (options?: TUserOptions & {
|
|
4234
|
-
cursor?: string;
|
|
4235
|
-
pageSize?: number;
|
|
4236
|
-
maxItems?: number;
|
|
4237
|
-
}) => PaginatedSdkResult<TItem>;
|
|
4238
|
-
|
|
4239
|
-
/**
|
|
4240
|
-
* Register kitcore-level configuration by writing the options to
|
|
4241
|
-
* `context.core`; the method boundary falls back to that path when no
|
|
4242
|
-
* `kitcore/coreOptions` configuration value exists.
|
|
4243
|
-
*
|
|
4244
|
-
* @deprecated Inject the `CoreOptions` bag under `CORE_OPTIONS_ID` via
|
|
4245
|
-
* `createSdk(root, { configuration })` instead. This factory logs a runtime
|
|
4246
|
-
* deprecation and will be removed in a release after the warning ships.
|
|
4247
|
-
*/
|
|
4248
|
-
declare function createCorePlugin(options: CoreOptions): Plugin<object, {
|
|
4249
|
-
context: {
|
|
4250
|
-
core: CoreOptions;
|
|
4251
|
-
};
|
|
4252
|
-
}>;
|
|
4253
|
-
|
|
4254
3596
|
/**
|
|
4255
3597
|
* Per-invocation scope for SDK method calls. Each top-level SDK method call
|
|
4256
3598
|
* runs in its own AsyncLocalStorage scope (via `runInMethodScope`), isolating
|
|
@@ -4337,12 +3679,6 @@ declare const validateOptions: <TOptions, TSchemaOptions extends TOptions>(schem
|
|
|
4337
3679
|
adaptError?: AdaptError;
|
|
4338
3680
|
}) => TSchemaOptions;
|
|
4339
3681
|
|
|
4340
|
-
/**
|
|
4341
|
-
* Translates a paginated handler's raw response into a normalized
|
|
4342
|
-
* `SdkPage<TItem>`. Supplied per method as the `adaptPage` on
|
|
4343
|
-
* `createPaginatedPluginMethod` (and forwarded to `createPaginatedFunction`).
|
|
4344
|
-
*/
|
|
4345
|
-
type AdaptPage<TResponse = unknown, TItem = unknown> = (response: TResponse) => SdkPage<TItem>;
|
|
4346
3682
|
type TPageOptions<TOptions> = TOptions extends undefined ? {
|
|
4347
3683
|
cursor?: string;
|
|
4348
3684
|
maxItems?: number;
|
|
@@ -4963,4 +4299,4 @@ declare const normalizeConnectionPlugin: MethodPlugin<"normalizeConnection", Nor
|
|
|
4963
4299
|
*/
|
|
4964
4300
|
declare const resolveConnectionPlugin: MethodPlugin<"resolveConnection", ResolveConnectionInput, string | undefined, readonly [], ResolveConnectionInput> & LeafSummary<"kitcore", "resolveConnection", readonly [], (input: ResolveConnectionInput) => string | undefined>;
|
|
4965
4301
|
|
|
4966
|
-
export { type AdaptError, type AdaptErrorOptions, type
|
|
4302
|
+
export { type AdaptError, type AdaptErrorOptions, type AggregatePlugin, type Annotations, type ArrayResolver$1 as ArrayResolver, type AsyncContext, type AttemptHttpRequestInput, type AuthorizeHttpRequestInput, type BoundFormatter, type BoundResolver, CONTEXT, CORE_ERROR_SYMBOL, CORE_OPTIONS_ID, CORE_SIGNAL_SYMBOL, type CallContext, type CallOrigin, type CategoryDefinition, type ComposedAnnotator, type ConstantResolver$1 as ConstantResolver, type ContractEntry, type Controller, type ControllerAction, type ControllerAffordance, type ControllerAnswerFn, type ControllerChoice, type ControllerError, type ControllerIssue, type ControllerListingPage, type ControllerListingPosition, type ControllerMethodDescription, type ControllerMethodSummary, type ControllerPagination, type ControllerParameterDescription, type ControllerPath, type ControllerQuestion, type ControllerResult, type ControllerSdk, type ControllerSelectPage, type ControllerState, type CoreApiError, CoreCancelledSignal, CoreDisposeError, CoreError, CoreErrorCode, type CoreErrorOptions, type CoreOptions, CoreSignal, type CreateSdkOptions, type DeclarationSummary, type DefaultConnectionSchemeInput, type DeprecatedPromptConfigChoice, type DeprecationLogger, type DeprecationWarning, type DispatchHttpRequestInput, type DisposeFn, type DynamicListResolver, type DynamicMember, type DynamicResolver$1 as DynamicResolver, type DynamicSearchResolver, type FieldsResolver, type FormattedItem, type Formatter, type FunctionDeprecation, type FunctionRegistryEntry, HTTP_FETCH_ID, type HookAnnotator, type HookPlugin, type HttpAttemptContext, type HttpFetchInit, type HttpOperationContext, type HttpOperationStart, type HttpPipelineState, type HttpRequest, type HttpRequestInput, type HttpResponse, type InitializeHttpRequestInput, type LeafBase, type LeafMeta, type LeafSummary, type ListItemsResult, type ListPromptConfig, type MethodAnnotator, type MethodAttachment, type MethodContract, type MethodHooks, type MethodMeta, type MethodOverridePlugin, type MethodPlugin, type MethodScope, type Resolver as ModelResolver, type NegatableMetadata, type NormalizeConnectionInput, type NormalizedConnection, type OnMethodEnd, type OnMethodEndContext, type OnMethodStart, type OnMethodStartContext, type OptionalDeclarationSummary, type OutputDataValidationReport, type OverridableMetaFields, type PaginatedSdkFunction, type PaginatedSdkResult, type Plugin, type PluginBase, type PluginLifecycle, type PluginMeta, type PluginSummary, type PluginSurface, type PluginType, type PositionalMetadata, type PrepareHttpRequestInput, type PromptConfig, type PromptConfigChoice, type PropertyMeta, type PropertyPlugin, RETRY_HTTP_REQUEST_OPTIONS_ID, type ReceiveHttpResponseInput, type RegistryResult, type RequiredSdkOf, type ResolveConnectionInput, type Resolver$1 as Resolver, type ResolverConfig, type ResolverFieldItem, type ResolverMetadata, type ResolverPromptConfig, type ResolverRequirement, type ResolverType, type ResponseMeta, type RetryHttpRequestAttempt, type RetryHttpRequestOptions, STABILITY_LEVELS, STABILITY_TITLES, type SdkContext, type SdkContextCarrier, type SdkPage, type SendHttpRequest, type StabilityLevel, type StabilityNotice, type StabilityNoticeLogger, type StandInId, type StaticResolver$1 as StaticResolver, type ValidResolvers, addPlugin, applyStabilityLabel, attemptHttpRequestPlugin, authorizeHttpRequestPlugin, canonicalInputSchema, concatLists, concatPaginated, coreOptionsPluginRef, createAsyncContext, createController, createCoreError, createDeprecationLogger, createPrefixedCursor, createSdk, createStabilityNoticeLogger, createValidator, dangerousContextPlugin, declareDefault, declareMethod, declareOptionalMethod, declareOptionalProperty, declarePlugin, declareProperty, decodeIncomingCursor, defaultConnectionSchemePlugin, defaultLogDeprecation, defineFormatter, defineHook, defineMethod, defineMethodOverride, defineOverride, definePlugin, defineProperty, defineResolver, dispatchHttpRequestPlugin, disposeSdk, fetchPlugin, getContext, getCoreErrorCause, getCoreErrorCode, getCurrentDepth, getCurrentScope, getFieldDescriptions, getNegatable, getOutputSchema, getRegistry, getRegistryPlugin, getSchemaDescription, httpFetchPluginRef, initializeHttpRequestPlugin, isCoreCancelledSignal, isCoreError, isCoreSignal, isNestedMethodCall, isPositional, isTelemetryNested, normalizeConnectionPlugin, normalizeStability, objectShapeOf, omitExports, openEnum, paginate, paginateBuffered, paginateMaxItems, prepareHttpRequestPlugin, receiveHttpResponsePlugin, redactHeaders, redactHttpRequest, resolveConnectionPlugin, resolvePlugin, retryHttpRequestOptionsPluginRef, retryHttpRequestPlugin, runInMethodScope, runWithTelemetryContext, selectExports, sendHttpRequestPlugin, splitPrefixedCursor, toIterable, toSnakeCase, toTitleCase, unwrapSchema, validateOptions, withOutputSchema, withPositional, withResolver };
|