better-call 0.0.0-experimental.01ff4b77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +265 -0
  3. package/dist/capability.cjs +417 -0
  4. package/dist/capability.cjs.map +1 -0
  5. package/dist/capability.d.cts +189 -0
  6. package/dist/capability.d.mts +189 -0
  7. package/dist/capability.mjs +401 -0
  8. package/dist/capability.mjs.map +1 -0
  9. package/dist/error.cjs +76 -0
  10. package/dist/error.cjs.map +1 -0
  11. package/dist/error.d.cts +51 -0
  12. package/dist/error.d.mts +51 -0
  13. package/dist/error.mjs +72 -0
  14. package/dist/error.mjs.map +1 -0
  15. package/dist/fn.cjs +350 -0
  16. package/dist/fn.cjs.map +1 -0
  17. package/dist/fn.d.cts +378 -0
  18. package/dist/fn.d.mts +378 -0
  19. package/dist/fn.mjs +350 -0
  20. package/dist/fn.mjs.map +1 -0
  21. package/dist/index.cjs +43 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.cts +50 -0
  24. package/dist/index.d.mts +50 -0
  25. package/dist/index.mjs +24 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/module.cjs +176 -0
  28. package/dist/module.cjs.map +1 -0
  29. package/dist/module.d.cts +283 -0
  30. package/dist/module.d.mts +283 -0
  31. package/dist/module.mjs +166 -0
  32. package/dist/module.mjs.map +1 -0
  33. package/dist/plugins/db.cjs +24 -0
  34. package/dist/plugins/db.cjs.map +1 -0
  35. package/dist/plugins/db.d.cts +18 -0
  36. package/dist/plugins/db.d.mts +18 -0
  37. package/dist/plugins/db.mjs +19 -0
  38. package/dist/plugins/db.mjs.map +1 -0
  39. package/dist/plugins/http/attrs.cjs +91 -0
  40. package/dist/plugins/http/attrs.cjs.map +1 -0
  41. package/dist/plugins/http/attrs.d.cts +26 -0
  42. package/dist/plugins/http/attrs.d.mts +26 -0
  43. package/dist/plugins/http/attrs.mjs +87 -0
  44. package/dist/plugins/http/attrs.mjs.map +1 -0
  45. package/dist/plugins/http/cookie.cjs +117 -0
  46. package/dist/plugins/http/cookie.cjs.map +1 -0
  47. package/dist/plugins/http/cookie.d.cts +637 -0
  48. package/dist/plugins/http/cookie.d.mts +637 -0
  49. package/dist/plugins/http/cookie.mjs +113 -0
  50. package/dist/plugins/http/cookie.mjs.map +1 -0
  51. package/dist/plugins/http/error.cjs +39 -0
  52. package/dist/plugins/http/error.cjs.map +1 -0
  53. package/dist/plugins/http/error.d.cts +38 -0
  54. package/dist/plugins/http/error.d.mts +38 -0
  55. package/dist/plugins/http/error.mjs +35 -0
  56. package/dist/plugins/http/error.mjs.map +1 -0
  57. package/dist/plugins/http/handle.cjs +73 -0
  58. package/dist/plugins/http/handle.cjs.map +1 -0
  59. package/dist/plugins/http/handle.d.cts +955 -0
  60. package/dist/plugins/http/handle.d.mts +955 -0
  61. package/dist/plugins/http/handle.mjs +72 -0
  62. package/dist/plugins/http/handle.mjs.map +1 -0
  63. package/dist/plugins/http/redirect.cjs +82 -0
  64. package/dist/plugins/http/redirect.cjs.map +1 -0
  65. package/dist/plugins/http/redirect.d.cts +67 -0
  66. package/dist/plugins/http/redirect.d.mts +67 -0
  67. package/dist/plugins/http/redirect.mjs +79 -0
  68. package/dist/plugins/http/redirect.mjs.map +1 -0
  69. package/dist/plugins/http/request.cjs +63 -0
  70. package/dist/plugins/http/request.cjs.map +1 -0
  71. package/dist/plugins/http/request.d.cts +142 -0
  72. package/dist/plugins/http/request.d.mts +142 -0
  73. package/dist/plugins/http/request.mjs +61 -0
  74. package/dist/plugins/http/request.mjs.map +1 -0
  75. package/dist/plugins/http/response.cjs +13 -0
  76. package/dist/plugins/http/response.cjs.map +1 -0
  77. package/dist/plugins/http/response.d.cts +18 -0
  78. package/dist/plugins/http/response.d.mts +18 -0
  79. package/dist/plugins/http/response.mjs +13 -0
  80. package/dist/plugins/http/response.mjs.map +1 -0
  81. package/dist/plugins/http.cjs +64 -0
  82. package/dist/plugins/http.cjs.map +1 -0
  83. package/dist/plugins/http.d.cts +945 -0
  84. package/dist/plugins/http.d.mts +945 -0
  85. package/dist/plugins/http.mjs +37 -0
  86. package/dist/plugins/http.mjs.map +1 -0
  87. package/dist/plugins/read-only.cjs +19 -0
  88. package/dist/plugins/read-only.cjs.map +1 -0
  89. package/dist/plugins/read-only.d.cts +17 -0
  90. package/dist/plugins/read-only.d.mts +17 -0
  91. package/dist/plugins/read-only.mjs +19 -0
  92. package/dist/plugins/read-only.mjs.map +1 -0
  93. package/dist/schema.cjs +245 -0
  94. package/dist/schema.cjs.map +1 -0
  95. package/dist/schema.d.cts +411 -0
  96. package/dist/schema.d.mts +411 -0
  97. package/dist/schema.mjs +235 -0
  98. package/dist/schema.mjs.map +1 -0
  99. package/dist/scope.d.cts +31 -0
  100. package/dist/scope.d.mts +31 -0
  101. package/dist/storage.cjs +308 -0
  102. package/dist/storage.cjs.map +1 -0
  103. package/dist/storage.d.cts +220 -0
  104. package/dist/storage.d.mts +220 -0
  105. package/dist/storage.mjs +302 -0
  106. package/dist/storage.mjs.map +1 -0
  107. package/dist/types.d.cts +8 -0
  108. package/dist/types.d.mts +8 -0
  109. package/dist/var.cjs +186 -0
  110. package/dist/var.cjs.map +1 -0
  111. package/dist/var.d.cts +46 -0
  112. package/dist/var.d.mts +46 -0
  113. package/dist/var.mjs +177 -0
  114. package/dist/var.mjs.map +1 -0
  115. package/package.json +114 -0
package/dist/fn.d.mts ADDED
@@ -0,0 +1,378 @@
1
+ import { FnError } from "./error.mjs";
2
+ import { LiteralString, Prettify } from "./types.mjs";
3
+ import { InferArgs, InferInput, OutputSchemaOf, TypeDefination, vTypes } from "./schema.mjs";
4
+ import { ResolvedVars, ScopeOf, VarName, VarScope } from "./scope.mjs";
5
+ import { ApplyOns, InputVarExtra, InputVarExtraOut, Module, ModuleFns, OnEntry, TargetMatches, VarGetContext, VarSetContext, WithDerived } from "./module.mjs";
6
+ import { VarDefination } from "./var.mjs";
7
+ //#region src/fn.d.ts
8
+ type ParentContext = Record<string, any>;
9
+ /**
10
+ * `{}` assignable to `A`, and `A` is not an open index signature
11
+ * (`Record<string, …>` / `v.object()` with no shape). Those accept any
12
+ * object, so omitting the arg is not the same as sending one.
13
+ */
14
+ type EmptyExtendsArgs<A> = Record<never, never> extends A ? string extends keyof A ? false : true : false;
15
+ /**
16
+ * Callers may omit a non-tuple input when the schema is optional or
17
+ * defaulted, or every field is already optional to send.
18
+ */
19
+ type InputOmittable<A, I> = I extends {
20
+ $var: true;
21
+ schema?: infer S;
22
+ } ? InputOmittable<A, NonNullable<S>> : I extends TypeDefination<any, any, infer D> ? [D] extends [never] ? EmptyExtendsArgs<A> : true : EmptyExtendsArgs<A>;
23
+ /** The call shape: a TUPLE input spreads - one parameter per position,
24
+ * the parent context last. No input, or an omittable one, takes
25
+ * `(input?, parent?)`; required inputs stay required. */
26
+ type CallArgs<A, I> = I extends readonly unknown[] ? A extends readonly unknown[] ? [...A] | [...A, ParentContext] : never : [A] extends [void] ? [input?: undefined, parent?: ParentContext] : InputOmittable<A, I> extends true ? [input?: A, parent?: ParentContext] : [input: A, parent?: ParentContext];
27
+ /** The union of a fn's DECLARED errors, as thrown values. */
28
+ type FnErrorsOf<Er> = { [T in keyof Er & string]: FnError<T, InferInput<Er[T]>>; }[keyof Er & string];
29
+ /** The declared-error union of a fn - for typing catch sites. */
30
+ type FnErrors<F> = F extends FnDefination<any, any, any, any, any, infer Er> ? FnErrorsOf<Er> : never;
31
+ /** Non-distributive `never` guard first: a naked `R extends Promise`
32
+ * distributes over `never` into `never`, and `[never] extends [Promise<_>]`
33
+ * is also true (bottom type). Always-throwing bodies need a sync result. */
34
+ type TryResult<R, Er> = [R] extends [never] ? {
35
+ ok: true;
36
+ value: never;
37
+ } | {
38
+ ok: false;
39
+ error: FnErrorsOf<Er>;
40
+ } : R extends Promise<infer V> ? Promise<{
41
+ ok: true;
42
+ value: V;
43
+ } | {
44
+ ok: false;
45
+ error: FnErrorsOf<Er>;
46
+ }> : {
47
+ ok: true;
48
+ value: R;
49
+ } | {
50
+ ok: false;
51
+ error: FnErrorsOf<Er>;
52
+ };
53
+ /** No declared errors - the default error channel. */
54
+ type NoErrors = Record<never, never>;
55
+ /** The `use` half of `.with`: fn overrides by name, recursing into
56
+ * GROUPS so a nested binding can be overridden too. A var alias takes a
57
+ * SEED for the var it points at. */
58
+ type WithFns<U> = { [K in keyof U]?: U[K] extends FnDefination<any, any, any, any, any, any> ? BoundFn<U[K]> : U[K] extends VarDefination<any, infer T, any, any> ? T : WithFns<U[K]>; };
59
+ /** The context `.with` accepts: any var of the fn's WHOLE chain scope
60
+ * (the builder's `use` included, not just the fn's own), plus any `use`
61
+ * fn as an override - and nothing else. Kept as PLAIN mapped types: with
62
+ * `RV`/`U` unknown both halves collapse to `{}`, which keeps every
63
+ * `extends FnDefination<any, ...>` structural check passing.
64
+ *
65
+ * Prefer {@link WithSeed} for values stored on {@link FnDefination} - it
66
+ * is what `v.fn` returns, and stays declaration-emit safe. */
67
+ type WithContext<RV, U> = { [K in keyof RV]?: RV[K]; } & WithFns<U>;
68
+ /** Storage (or the FnEntries slice of one): `$models` plus callable
69
+ * `$adapter`. Nested under a module as `{ db }`, it must not flow into
70
+ * `.with` seeds - model schemas alone blow past declaration serialize
71
+ * limits. ModuleFns keeps collections; WithSeed still drops storage. */
72
+ type StorageLike = {
73
+ $models: object;
74
+ $adapter: (...args: never[]) => unknown;
75
+ };
76
+ /** Flatten `use` members to `.with` overrides: bound call signatures, var
77
+ * alias values, nested groups. Storage is dropped (mount-only). */
78
+ type WithFnsSeed<U> = { [K in keyof U as U[K] extends StorageLike ? never : K]?: U[K] extends FnDefination<any, any, any, any, any, any> ? BoundFn<U[K]> : U[K] extends VarDefination<any, infer T, any, any> ? T : WithFnsSeed<U[K]>; };
79
+ /**
80
+ * Flat `.with` seed map stored on exported fns. Evaluating ScopeOf /
81
+ * ModuleFns here (instead of embedding those wrappers as type arguments)
82
+ * keeps declaration emit small: `.d.ts` shows leaf var shapes and bound
83
+ * call signatures, not `ScopeOf<ResolvedVars<entire module graph>>`.
84
+ */
85
+ type WithSeed<RV, U> = Prettify<{ [K in keyof RV]?: RV[K]; } & WithFnsSeed<U>>;
86
+ /** What `v.fn` / `e.fn` returns: contract params plus a flat {@link WithSeed}
87
+ * for `.with`, never the raw ScopeOf / ModuleFns graph. */
88
+ type PublicFn<A, R, K extends string, I, P extends readonly string[], Er, RV, U, O = unknown> = FnDefination<A, R, K, I, P, Er, WithSeed<RV, U>, O>;
89
+ /** What `.with` returns: the same callable, context baked in. */
90
+ interface BoundCall<A, R, I, Er> {
91
+ (...args: CallArgs<A, I>): R;
92
+ try(...args: CallArgs<A, I>): TryResult<R, Er>;
93
+ }
94
+ interface FnDefination<A, R, K extends string = string, I = unknown, P extends readonly string[] = readonly string[], Er = NoErrors,
95
+ /** `.with` seed map ({@link WithSeed}). Defaults keep structural
96
+ * `extends FnDefination<any, ...>` checks passing. */
97
+ W = unknown, O = unknown> {
98
+ (...args: CallArgs<A, I>): R;
99
+ /**
100
+ * Call with DECLARED errors caught as a value: `{ ok: true, value }`
101
+ * or `{ ok: false, error }`, narrowed by `error.tag`. Only tagged,
102
+ * expected errors become results - defects and contract violations
103
+ * still throw, exactly as they should.
104
+ */
105
+ try(...args: CallArgs<A, I>): TryResult<R, Er>;
106
+ /**
107
+ * Call with a HAND-BUILT context. Keys naming a var SEED that var in a
108
+ * fresh scope; keys naming a `use` fn OVERRIDE that binding for the
109
+ * whole subtree below. Both are typed from the fn's chain - what the
110
+ * BUILDER mounted counts, so `signOut.with({ user })` type-checks even
111
+ * though `signOut` itself never says `use: [user]`. A parent passed to
112
+ * the bound call is FORKED: its vars are copied in, never written back.
113
+ */
114
+ with(context: W): BoundCall<A, R, I, Er>;
115
+ /** Brand, so a plugin module can be scanned for its fns. */
116
+ readonly $fn: true;
117
+ /** The name interceptors target - literal, so `ApplyOn` can match it. */
118
+ readonly key: K;
119
+ /** The declared contract, retained AS WRITTEN for runtime
120
+ * introspection (tool cards, docs renderers): the raw input/output
121
+ * schemas, error tag map, and required vars. Optional so structural
122
+ * `extends FnDefination` checks keep passing for hand-built fns. */
123
+ readonly $schema?: {
124
+ input?: unknown;
125
+ output?: unknown;
126
+ errors?: Record<string, unknown>;
127
+ requires?: readonly string[];
128
+ /** Declared idempotence - same args, same result, safe to repeat. */
129
+ idempotent?: boolean;
130
+ };
131
+ /** Vars this fn promises to set when ITS OWN body runs - the literal
132
+ * list, readable by graph tooling at both type and runtime level. */
133
+ readonly provides: P;
134
+ /** Phantom: the raw declared input, so extensions of the vars it
135
+ * references can widen used-fn call sites. Never set at runtime. */
136
+ readonly $input?: I;
137
+ /** Phantom: the raw declared output, the counterpart of `$input` - the
138
+ * schema as written, for type-level introspection. Never set at runtime. */
139
+ readonly $output?: O;
140
+ /** Phantom: declared error tags -> payload schemas. */
141
+ readonly $errors?: Er;
142
+ }
143
+ type ArgsOf<I> = I extends readonly unknown[] ? { -readonly [K in keyof I]: InferArgs<I[K]>; } : unknown extends I ? void : InferArgs<I>;
144
+ /**
145
+ * Call args of a declaring fn: the declared input, plus whatever mounted
146
+ * `v.extend` / same-name shadows add for vars that input references.
147
+ * Mirrors {@link ApplyOn} so `input: user` + `use: [userWithEmail]` types
148
+ * the door the same way a used call site would.
149
+ */
150
+ type WidenedArgs<I, ExtPL> = unknown extends InputVarExtra<ExtPL, I> ? ArgsOf<I> : Prettify<([ArgsOf<I>] extends [void] ? unknown : ArgsOf<I>) & InputVarExtra<ExtPL, I>>;
151
+ type OptionType<I, O, P, Q, PL, RO extends boolean = boolean, Er = any> = {
152
+ /**
153
+ * The fn's DECLARED failures: tag -> payload schema. The THIRD
154
+ * contract door - input validates on entry, output on exit, errors at
155
+ * `throw c.error(tag, data)`. Once declared, any UNTAGGED throw
156
+ * escaping the body is a defect and comes out as `UnexpectedError` -
157
+ * callers can tell a domain refusal from a bug without string
158
+ * matching.
159
+ */
160
+ errors?: Er;
161
+ /**
162
+ * A readonly fn cannot write vars - not in its handler, not in
163
+ * anything it calls, not from interceptors mounted on it. Enforced at
164
+ * the type level (vars readonly on `c`, declared writers uncallable)
165
+ * and at runtime (the whole subtree's store locks).
166
+ */
167
+ readonly?: RO;
168
+ /**
169
+ * Declared idempotence: calling with the same args always produces the
170
+ * same result and repeating the call is harmless - a read, a lookup, a
171
+ * pure computation. Part of the retained contract (`$schema`), so
172
+ * hosts may DEDUPE calls: the script engine serves repeated
173
+ * same-args calls to an idempotent fn from one dispatch per session.
174
+ * Note this is a different promise than `readonly` (writes no vars) -
175
+ * an fn can be readonly and still hit a non-idempotent API.
176
+ */
177
+ idempotent?: boolean;
178
+ input?: I;
179
+ /**
180
+ * The fn's return contract. A bare schema is BOTH the signature and
181
+ * the exit check; the wrapper `{ def?, validation? }` splits them -
182
+ * `{ def }` documents the return (tool cards, handler typing) without
183
+ * runtime validation, `validation` is the schema the exit check runs
184
+ * (defaults to none in the wrapper form).
185
+ */
186
+ output?: O;
187
+ /** Vars this fn guarantees to set. Checked on exit. */
188
+ provides?: P;
189
+ /** Vars that must already be set. Checked on entry, before the body. */
190
+ requires?: Q;
191
+ /**
192
+ * Module namespaces to pull in. Their vars come into scope, their fns
193
+ * land directly on `c` already bound to this context (a plain-record
194
+ * member nests as a NAMESPACE: `c.cookies.setCookie`), and their `on`
195
+ * entries stay active for everything below.
196
+ */
197
+ use?: PL;
198
+ };
199
+ /** A used fn, with the parent context already applied. A tuple-input fn
200
+ * keeps its positional signature. Omittable inputs match {@link CallArgs}. */
201
+ type BoundFn<F> = F extends FnDefination<infer A, infer R, string, infer I, any, any> ? I extends readonly unknown[] ? A extends readonly unknown[] ? (...args: [...A]) => R : never : [A] extends [void] ? () => R : InputOmittable<A, I> extends true ? (input?: A) => R : (input: A) => R : never;
202
+ /** Keys of a usable map whose member is a VAR alias. */
203
+ type UseVarKeys<U> = { [K in keyof U]: U[K] extends VarDefination<any, any, any, any> ? K : never; }[keyof U];
204
+ /**
205
+ * VarDefination surface keys. ModuleFns intersects a merge var with
206
+ * same-key namespace helpers (`VarDef & { createUser }`); stripping these
207
+ * leaves the helper group for {@link UseApi}.
208
+ */
209
+ type VarSurfaceKeys = "$var" | "name" | "default" | "schema" | "type" | "$source" | "$attrs" | "$merge" | "customize";
210
+ type MergeHelpersOnVar<V> = Omit<V, VarSurfaceKeys>;
211
+ /** Bound helpers intersected onto a merge var in ModuleFns, if any. */
212
+ type UseApiMergeExtras<V> = V extends {
213
+ $merge: true;
214
+ } ? [keyof MergeHelpersOnVar<V>] extends [never] ? never : UseApi<MergeHelpersOnVar<V>> : never;
215
+ /**
216
+ * A var alias' surface: the var's VALUE, plus same-key namespace helpers
217
+ * when the var is `merge: true` (mirrors {@link collectMergeSeeds} /
218
+ * {@link viewMergeVar}).
219
+ */
220
+ type UseVarValue<V> = V extends VarDefination<any, infer T, any, any> ? UseApiMergeExtras<V> extends (infer H) ? [H] extends [never] ? T : Prettify<T & H> : T : never;
221
+ /**
222
+ * Fold merge-var helpers from the usable map `U` onto scope values keyed
223
+ * by DECLARED name (so `c.vt_merge_db.byTag` types when the export key
224
+ * was `db`).
225
+ */
226
+ type MergeIntoScope<RV, U> = { [K in keyof RV]: HelpersForDeclaredName<K & string, U> extends (infer H) ? [H] extends [never] ? RV[K] : Prettify<RV[K] & H> : RV[K]; };
227
+ type HelpersForDeclaredName<N extends string, U> = { [K in keyof U]: U[K] extends VarDefination<N, any, any, any> ? UseApiMergeExtras<U[K]> : never; }[keyof U];
228
+ type UseApi<U> = Prettify<{ [K in Exclude<keyof U, UseVarKeys<U>>]: U[K] extends FnDefination<any, any, any, any, any, any> ? BoundFn<U[K]> : U[K] extends StorageLike ? U[K] : UseApi<U[K]>; } & { [K in UseVarKeys<U>]: UseVarValue<U[K]>; }>;
229
+ /** Used fns inside a readonly fn: declared writers become uncallable,
230
+ * with the reason on hover instead of a generic type error; var aliases
231
+ * become readonly properties. */
232
+ type ReadUseApi<U> = Prettify<{ [K in Exclude<keyof U, UseVarKeys<U>>]: U[K] extends FnDefination<any, any, any, any, infer P, any> ? P extends readonly [] ? BoundFn<U[K]> : `writes "${P[number] & string}" - not callable from a readonly fn` : U[K] extends StorageLike ? U[K] : ReadUseApi<U[K]>; } & { readonly [K in UseVarKeys<U>]: UseVarValue<U[K]>; }>;
233
+ type Context<I, RV, Required, U = unknown, FnApi = Fn, RO extends boolean = false, Errs = NoErrors,
234
+ /** Modules that widen var-bound input (this fn's `use` + builder chain). */
235
+ ExtPL = unknown> = {
236
+ input: unknown extends InputVarExtraOut<ExtPL, I> ? InferInput<I> : Prettify<InferInput<I> & InputVarExtraOut<ExtPL, I>>;
237
+ /**
238
+ * Mint a DECLARED error - tag-checked, payload validated at creation:
239
+ * `throw c.error("invalid_credentials", { attempts: 3 })`. Only tags
240
+ * from this fn's `errors` exist; the payload validates like input.
241
+ */
242
+ error: <T extends keyof Errs & string>(tag: T, ...data: Record<never, never> extends InferArgs<Errs[T]> ? [data?: InferArgs<Errs[T]>] : [data: InferArgs<Errs[T]>]) => FnError<T, InferInput<Errs[T]>>;
243
+ /** Define fns from inside: this fn's scope and key carry over, so
244
+ * anything built here is typed exactly like a chained builder. */
245
+ fn: FnApi;
246
+ /** The schema constructors (string, number, object, ...). */
247
+ types: typeof vTypes;
248
+ } & /** Every var in scope, directly on `c`: read `c.session`, write by
249
+ * plain assignment (`c.session = {...}`). Every var is a readonly
250
+ * property on a readonly fn. Merge vars also expose same-key helpers
251
+ * folded from `U` (declared-name access). */ VarScope<MergeIntoScope<RV, U>, Required, RO> &
252
+ /** Fns from `use`, directly on `c` and already threaded with this
253
+ * context: `c.createUser({...})`. */
254
+ (RO extends true ? ReadUseApi<U> : UseApi<U>);
255
+ type InferReturn<O> = unknown extends O ? unknown : InferInput<OutputSchemaOf<O>>;
256
+ interface Fn<Base = unknown, BaseFns = unknown, BasePL extends readonly Module[] = [], Prefix extends string = ""> {
257
+ /**
258
+ * The builder FN is a schema too: `create: v.fn` (never called) declares
259
+ * "any function" - typed `(...args: any[]) => any`, runtime checks only
260
+ * `typeof value === "function"`.
261
+ */
262
+ readonly $fnSchema: {
263
+ input?: unknown;
264
+ output?: unknown;
265
+ };
266
+ /**
267
+ * "A fn with THIS signature", as a schema: `create: v.fn.type({ input,
268
+ * output })` types the field as that fn and validates what a signature
269
+ * CAN be validated for - the value is a function, and a plain closure
270
+ * gets the declared input checked at its door on every call.
271
+ *
272
+ * `optional` / `default` work like on `v.string()` etc., so a prop in
273
+ * `v.object({...})` can be a fn type and still omittable.
274
+ *
275
+ * This exists apart from a handler-less `v.fn({ input, output })` for
276
+ * INLINE use: `v.fn`'s handler overloads return a callable, which makes
277
+ * TypeScript defer any inline `v.fn(...)` call inside another generic
278
+ * call's arguments (higher-order inference) - the enclosing `v.object`/
279
+ * `v.var` then loses its shape inference entirely. `v.fn.type` returns a
280
+ * plain carrier, so it composes inline anywhere.
281
+ */
282
+ readonly type: <I = unknown, O = unknown, D = never, Opt extends boolean = false>(signature?: {
283
+ input?: I;
284
+ output?: O;
285
+ default?: D;
286
+ optional?: Opt;
287
+ }) => {
288
+ readonly $fnSchema: {
289
+ input?: I;
290
+ output?: O;
291
+ };
292
+ } & ([Opt] extends [true] ? {
293
+ readonly optional: true;
294
+ } : unknown) & ([D] extends [never] ? unknown : {
295
+ readonly default: D;
296
+ });
297
+ <R>(fn: (ctx: Context<unknown, ScopeOf<[], Base, BasePL>, never, BaseFns, Fn<Base, BaseFns, BasePL, Prefix>>) => R): PublicFn<void, R, Prefix extends "" ? string : Prefix, unknown, readonly string[], NoErrors, ScopeOf<[], Base, BasePL>, BaseFns>;
298
+ <K extends LiteralString, R>(key: K, fn: (ctx: Context<unknown, ScopeOf<[], Base, BasePL>, never, BaseFns, Fn<Base, BaseFns, BasePL, `${Prefix}${K}`>>) => R): PublicFn<void, R, `${Prefix}${K}`, unknown, readonly string[], NoErrors, ScopeOf<[], Base, BasePL>, BaseFns>;
299
+ <const I, O, R extends InferReturn<O> | Promise<InferReturn<O>>, const PL extends readonly Module[] = [], const P extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], const Q extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], RO extends boolean = false, Er extends Record<string, unknown> = NoErrors>(options: OptionType<I, O, P, Q, PL, RO, Er>, fn: (ctx: Context<I, ScopeOf<PL, Base, readonly [...BasePL, ...PL]>, WithDerived<PL, BasePL, Q[number]>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, Fn<Base & ResolvedVars<PL>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, readonly [...BasePL, ...PL], Prefix>, RO, Er, readonly [...BasePL, ...PL]>) => R): PublicFn<WidenedArgs<I, readonly [...BasePL, ...PL]>, R, Prefix extends "" ? string : Prefix, I, P, Er, ScopeOf<PL, Base, readonly [...BasePL, ...PL]>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, O>;
300
+ <K extends LiteralString, const I, O, R extends InferReturn<O> | Promise<InferReturn<O>>, const PL extends readonly Module[] = [], const P extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], const Q extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], RO extends boolean = false, Er extends Record<string, unknown> = NoErrors>(key: K, options: OptionType<I, O, P, Q, PL, RO, Er>, fn: (ctx: Context<I, ScopeOf<PL, Base, readonly [...BasePL, ...PL]>, WithDerived<PL, BasePL, Q[number]>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, Fn<Base & ResolvedVars<PL>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, readonly [...BasePL, ...PL], `${Prefix}${K}`>, RO, Er, readonly [...BasePL, ...PL]>) => R): PublicFn<WidenedArgs<I, readonly [...BasePL, ...PL]>, R, `${Prefix}${K}`, I, P, Er, ScopeOf<PL, Base, readonly [...BasePL, ...PL]>, ApplyOns<ModuleFns<PL>, PL> & BaseFns, O>;
301
+ <K extends LiteralString>(key: K): Instance<Base, BaseFns, BasePL, `${Prefix}${K}`>;
302
+ <I, O, const PL extends readonly Module[] = [], const P extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], const Q extends readonly VarName<ScopeOf<PL, Base>>[] = readonly []>(options: OptionType<I, O, P, Q, PL>): Instance<Base & ResolvedVars<PL>, BaseFns & ApplyOns<ModuleFns<PL>, PL>, readonly [...BasePL, ...PL], Prefix, I, O>;
303
+ <K extends LiteralString, I, O, const PL extends readonly Module[] = [], const P extends readonly VarName<ScopeOf<PL, Base>>[] = readonly [], const Q extends readonly VarName<ScopeOf<PL, Base>>[] = readonly []>(key: K, options: OptionType<I, O, P, Q, PL>): Instance<Base & ResolvedVars<PL>, BaseFns & ApplyOns<ModuleFns<PL>, PL>, readonly [...BasePL, ...PL], `${Prefix}${K}`, I, O>;
304
+ }
305
+ /** Every target worth suggesting on a builder's `on`: the mounted fns'
306
+ * keys (prefix-stripped, so they are valid RELATIVE targets), the scope's
307
+ * var-write events by name, and the two wildcards. Arbitrary strings stay
308
+ * legal - these only feed completion. */
309
+ type OnTargetSuggest<Base, BaseFns, Prefix extends string> = FnTargetSuggest<BaseFns, Prefix> | `var.set.${keyof ScopeOf<[], Base> & string}` | "var.set.*" | `var.get.${keyof ScopeOf<[], Base> & string}` | "var.get.*" | "*";
310
+ type FnTargetSuggest<Fns, Prefix extends string> = { [K in keyof Fns]: Fns[K] extends FnDefination<any, any, infer FK, any, any, any> ? FK extends `${Prefix}${infer Rest}` ? Rest : never : never; }[keyof Fns];
311
+ type VarNameOfT<T extends string> = T extends `var.${"set" | "get"}.${infer N}` ? N extends `${string}*${string}` ? string : N : string;
312
+ /** The scope's value for a var-event target - `unknown` when inexact. */
313
+ type VarValueOfT<T extends string, Base> = VarNameOfT<T> extends keyof ScopeOf<[], Base> ? ScopeOf<[], Base>[VarNameOfT<T>] : unknown;
314
+ /** The fns among `Fns` whose key the (already prefixed) target hits. */
315
+ type MatchedFn<Fns, T extends string> = { [K in keyof Fns]: Fns[K] extends FnDefination<any, any, infer FK, any, any, any> ? TargetMatches<T, FK & string> extends true ? Fns[K] : never : never; }[keyof Fns];
316
+ /** The intercepted input: the matched fn's (a union under wildcards),
317
+ * or an open record when the target names nothing the builder knows. */
318
+ type MatchedInput<F> = [F] extends [never] ? Record<string, any> : F extends FnDefination<any, any, any, infer I, any, any> ? InferInput<I> : never;
319
+ /** What `next()` resolves to: the matched fn's own result. */
320
+ type MatchedResult<F> = [F] extends [never] ? any : F extends FnDefination<any, infer R, any, any, any, any> ? Awaited<R> : never;
321
+ /** What a builder-scoped `on` handler sees: vars and `use` fns directly
322
+ * on `c` from the builder, `input` from the TARGET fn when known. */
323
+ type OnContext<Base, BaseFns, F, Ext = unknown> = {
324
+ input: MatchedInput<F> & (unknown extends Ext ? unknown : InferInput<Ext>);
325
+ types: typeof vTypes;
326
+ fn: unknown;
327
+ } & VarScope<ScopeOf<[], Base>, never> & UseApi<BaseFns>;
328
+ /** `v.on`, scoped: string targets get the builder's key prefix; the
329
+ * handler's `c` and `next()` are typed against the matched target fn. */
330
+ interface InstanceOn<Base, BaseFns, Prefix extends string> {
331
+ /** A fn REFERENCE targets its own key - never prefixed, fully typed
332
+ * from the fn itself plus the builder's scope. */
333
+ <F extends FnDefination<any, any, string, any, any, any>>(target: F, handler: (c: OnContext<Base, BaseFns, F>, next: () => Promise<MatchedResult<F>>) => any): OnEntry<F["key"]>;
334
+ /** Var-write events: never prefixed (vars are global), and `value`
335
+ * is typed from the builder's scope when the target is exact. */
336
+ <T extends `var.set.${keyof ScopeOf<[], Base> & string}` | "var.set.*" | `var.set.${string}`>(target: T, handler: (c: VarSetContext<VarNameOfT<T>> & {
337
+ value: VarValueOfT<T, Base>;
338
+ }, next: () => void) => void): OnEntry<T>;
339
+ /** Var-read events: `next()` yields the stored value and the handler's
340
+ * return becomes the read result - typed from the scope when exact. */
341
+ <T extends `var.get.${keyof ScopeOf<[], Base> & string}` | "var.get.*" | `var.get.${string}`>(target: T, handler: (c: VarGetContext<VarNameOfT<T>>, next: () => VarValueOfT<T, Base>) => VarValueOfT<T, Base>): OnEntry<T>;
342
+ (target: RegExp, handler: (c: OnContext<Base, BaseFns, never>, next: () => Promise<any>) => any): OnEntry<string>;
343
+ <N extends OnTargetSuggest<Base, BaseFns, Prefix> | LiteralString>(target: N, handler: (c: OnContext<Base, BaseFns, MatchedFn<BaseFns, `${Prefix}${N}`>>, next: () => Promise<MatchedResult<MatchedFn<BaseFns, `${Prefix}${N}`>>>) => any): OnEntry<`${Prefix}${N}`>;
344
+ <const Ext>(target: RegExp, extend: {
345
+ input: Ext;
346
+ }, handler: (c: OnContext<Base, BaseFns, never, Ext>, next: () => Promise<any>) => any): OnEntry<string, Ext>;
347
+ <N extends OnTargetSuggest<Base, BaseFns, Prefix> | LiteralString, const Ext>(target: N, extend: {
348
+ input: Ext;
349
+ }, handler: (c: OnContext<Base, BaseFns, MatchedFn<BaseFns, `${Prefix}${N}`>, Ext>, next: () => Promise<MatchedResult<MatchedFn<BaseFns, `${Prefix}${N}`>>>) => any): OnEntry<`${Prefix}${N}`, Ext>;
350
+ }
351
+ type Instance<Base, BaseFns, PL extends readonly Module[] = [], Prefix extends string = "", I = unknown, O = unknown> = {
352
+ /** Same as `v.fn`, with this builder's key prefix and options baked in. */
353
+ fn: Fn<Base, BaseFns, PL, Prefix>;
354
+ /**
355
+ * A handler-less builder doubles as an input SCHEMA: used as `input`
356
+ * (or an input field) it declares "a FN from `input` to `output`" -
357
+ * the value crossing is the fn itself. Carries the declared schemas
358
+ * for inference here and validation at runtime (see `isFnSchema`).
359
+ */
360
+ readonly $fnSchema: {
361
+ input?: I;
362
+ output?: O;
363
+ };
364
+ /** Same as `v.on`, with the prefix on string targets and the handler
365
+ * typed against the matched target fn. */
366
+ on: InstanceOn<Base, BaseFns, Prefix>;
367
+ /**
368
+ * The context a handler on this builder receives - a TYPE carrier for
369
+ * `typeof f.ctx` (helper signatures, plugin contracts). Every handler
370
+ * context on this builder is assignable to it: `input` and `fn` are
371
+ * loosened since they vary per fn. A real context only exists per
372
+ * invocation, so this is `undefined` at runtime.
373
+ */
374
+ readonly ctx: Context<unknown, ScopeOf<[], Base, PL>, never, BaseFns, unknown>;
375
+ };
376
+ //#endregion
377
+ export { ArgsOf, BoundCall, Context, Fn, FnDefination, FnErrors, FnErrorsOf, InferReturn, Instance, InstanceOn, OptionType, ParentContext, UseApi, WidenedArgs, WithContext, WithSeed };
378
+ //# sourceMappingURL=fn.d.mts.map