better-call 0.0.0-experimental.06264e12

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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +254 -0
  3. package/dist/error.cjs +67 -0
  4. package/dist/error.cjs.map +1 -0
  5. package/dist/error.d.cts +46 -0
  6. package/dist/error.d.mts +46 -0
  7. package/dist/error.mjs +64 -0
  8. package/dist/error.mjs.map +1 -0
  9. package/dist/fn.cjs +335 -0
  10. package/dist/fn.cjs.map +1 -0
  11. package/dist/fn.d.cts +312 -0
  12. package/dist/fn.d.mts +312 -0
  13. package/dist/fn.mjs +335 -0
  14. package/dist/fn.mjs.map +1 -0
  15. package/dist/index.cjs +37 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +46 -0
  18. package/dist/index.d.mts +46 -0
  19. package/dist/index.mjs +24 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/module.cjs +111 -0
  22. package/dist/module.cjs.map +1 -0
  23. package/dist/module.d.cts +249 -0
  24. package/dist/module.d.mts +249 -0
  25. package/dist/module.mjs +102 -0
  26. package/dist/module.mjs.map +1 -0
  27. package/dist/plugins/http.cjs +185 -0
  28. package/dist/plugins/http.cjs.map +1 -0
  29. package/dist/plugins/http.d.cts +1261 -0
  30. package/dist/plugins/http.d.mts +1261 -0
  31. package/dist/plugins/http.mjs +175 -0
  32. package/dist/plugins/http.mjs.map +1 -0
  33. package/dist/plugins/read-only.cjs +19 -0
  34. package/dist/plugins/read-only.cjs.map +1 -0
  35. package/dist/plugins/read-only.d.cts +17 -0
  36. package/dist/plugins/read-only.d.mts +17 -0
  37. package/dist/plugins/read-only.mjs +19 -0
  38. package/dist/plugins/read-only.mjs.map +1 -0
  39. package/dist/schema.cjs +167 -0
  40. package/dist/schema.cjs.map +1 -0
  41. package/dist/schema.d.cts +225 -0
  42. package/dist/schema.d.mts +225 -0
  43. package/dist/schema.mjs +159 -0
  44. package/dist/schema.mjs.map +1 -0
  45. package/dist/scope.d.cts +18 -0
  46. package/dist/scope.d.mts +18 -0
  47. package/dist/storage.cjs +256 -0
  48. package/dist/storage.cjs.map +1 -0
  49. package/dist/storage.d.cts +195 -0
  50. package/dist/storage.d.mts +195 -0
  51. package/dist/storage.mjs +253 -0
  52. package/dist/storage.mjs.map +1 -0
  53. package/dist/types.d.cts +8 -0
  54. package/dist/types.d.mts +8 -0
  55. package/dist/var.cjs +162 -0
  56. package/dist/var.cjs.map +1 -0
  57. package/dist/var.d.cts +36 -0
  58. package/dist/var.d.mts +36 -0
  59. package/dist/var.mjs +154 -0
  60. package/dist/var.mjs.map +1 -0
  61. package/package.json +92 -0
@@ -0,0 +1,111 @@
1
+ const require_schema = require("./schema.cjs");
2
+ //#region src/module.ts
3
+ /**
4
+ * Does an `on` target hit fn key `key`? Exact match, `*` wildcards
5
+ * ("*", "sign_up.*", "/sign-up/*" - a `*` spans anything), a RegExp, or a
6
+ * list (any member hitting counts).
7
+ */
8
+ const matchesTarget = (target, key) => {
9
+ if (Array.isArray(target)) return target.some((member) => matchesTarget(member, key));
10
+ if (target instanceof RegExp) return target.test(key);
11
+ const name = target;
12
+ if (name === key) return true;
13
+ if (!name.includes("*")) return false;
14
+ const pattern = name.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
15
+ return new RegExp(`^${pattern}$`).test(key);
16
+ };
17
+ const isFn = (value) => typeof value === "function" && value?.$fn === true;
18
+ /**
19
+ * Guard the module list: modules are plain records, and passing a bare
20
+ * fn/var/extension/`on` entry is almost always a mistake (a bare fn would
21
+ * otherwise look like a factory and get CALLED). Fail loudly instead.
22
+ */
23
+ const resolveModules = (modules) => modules.map((mod) => {
24
+ if (isFn(mod) || require_schema.isVar(mod) || isVarExtension(mod) || isOn(mod)) {
25
+ const bare = mod;
26
+ const name = bare.key ?? bare.name ?? (bare.target !== void 0 ? String(bare.target) : "member");
27
+ throw new Error(`modules are objects - wrap the member: use([{ ${name} }]), not use([${name}])`);
28
+ }
29
+ return mod ?? {};
30
+ });
31
+ /** Collect every exported fn from a set of plugin modules. */
32
+ const collectFns = (modules) => {
33
+ const fns = {};
34
+ for (const mod of resolveModules(modules)) for (const [name, value] of Object.entries(mod)) if (isFn(value)) fns[name] = value;
35
+ return fns;
36
+ };
37
+ /**
38
+ * A plain-record member that GROUPS other members - not itself branded
39
+ * (fn, var, on entry, var extension) but holding at least one such member,
40
+ * transitively. Storages and other `$`-surfaced objects fail the member
41
+ * test and stay opaque values.
42
+ */
43
+ const isNamespace = (value) => {
44
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
45
+ const proto = Object.getPrototypeOf(value);
46
+ if (proto !== Object.prototype && proto !== null) return false;
47
+ if (require_schema.isVar(value) || isOn(value) || isVarExtension(value)) return false;
48
+ return Object.values(value).some((m) => isFn(m) || require_schema.isVar(m) || isOn(m) || isVarExtension(m) || isNamespace(m));
49
+ };
50
+ /**
51
+ * Every exported fn AND var, with plain-record GROUPS kept as nested
52
+ * namespaces: `use: [{ cookie: { setCookie } }]` lands the fn on
53
+ * `c.cookie.setCookie`. A var member becomes an ALIAS under its export
54
+ * name (`{ cookie: { options: cookieOptions } }` -> `c.cookie.options`
55
+ * reads/writes the var). Groups holding nothing (however deep) drop out.
56
+ */
57
+ const collectUsable = (modules) => {
58
+ const walk = (mod) => {
59
+ const out = {};
60
+ for (const [name, value] of Object.entries(mod)) if (isFn(value) || require_schema.isVar(value)) out[name] = value;
61
+ else if (isNamespace(value)) {
62
+ const nested = walk(value);
63
+ if (Object.keys(nested).length > 0) out[name] = nested;
64
+ }
65
+ return out;
66
+ };
67
+ const fns = {};
68
+ for (const mod of resolveModules(modules)) Object.assign(fns, walk(mod));
69
+ return fns;
70
+ };
71
+ const isOn = (value) => value?.$on === true;
72
+ function on(target, extendOrHandler, maybeHandler) {
73
+ const resolveOne = (member) => isFn(member) ? member.key : member;
74
+ const resolved = Array.isArray(target) ? target.map(resolveOne) : resolveOne(target);
75
+ return typeof extendOrHandler === "function" ? {
76
+ $on: true,
77
+ target: resolved,
78
+ handler: extendOrHandler
79
+ } : {
80
+ $on: true,
81
+ target: resolved,
82
+ extend: extendOrHandler,
83
+ handler: maybeHandler
84
+ };
85
+ }
86
+ const isVarExtension = (value) => value?.$varExtend === true;
87
+ function extendVar(target, schema) {
88
+ return typeof target === "string" ? {
89
+ $varExtend: true,
90
+ name: target,
91
+ schema
92
+ } : {
93
+ $varExtend: true,
94
+ name: target.name,
95
+ schema,
96
+ base: target
97
+ };
98
+ }
99
+ //#endregion
100
+ exports.collectFns = collectFns;
101
+ exports.collectUsable = collectUsable;
102
+ exports.extendVar = extendVar;
103
+ exports.isFn = isFn;
104
+ exports.isNamespace = isNamespace;
105
+ exports.isOn = isOn;
106
+ exports.isVarExtension = isVarExtension;
107
+ exports.matchesTarget = matchesTarget;
108
+ exports.on = on;
109
+ exports.resolveModules = resolveModules;
110
+
111
+ //# sourceMappingURL=module.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.cjs","names":["isVar"],"sources":["../src/module.ts"],"sourcesContent":["import type { FnDefination } from \"./fn\";\nimport { type InferArgs, type InferInput, isVar, type vTypes } from \"./schema\";\nimport type {\n\tLiteralString,\n\tMembers,\n\tPrettify,\n\tUnionToIntersection,\n} from \"./types\";\nimport type { VarDefination } from \"./var\";\n\nexport type Interceptor = (c: any, next: () => Promise<any>) => any;\n\n/**\n * What a GLOBAL `v.on` handler sees. Without a builder there is no scope\n * to infer, but the context's shape is always the same - so the default\n * is structured with loose leaves, never `any`: `c.input.code` works,\n * `c.tpyo` does not. Mount the entry on a builder's `on` for real types.\n */\nexport type OnDefaultContext = {\n\tinput: Record<string, any>;\n\ttypes: typeof vTypes;\n\tfn: unknown;\n\t/** Vars and used fns live directly on `c` - untyped here; mount the\n\t * entry on a builder's `on` for real types. */\n\t[key: string]: any;\n};\n\nexport type OnEntry<N extends string, Ext = unknown> = {\n\t$on: true;\n\t/** Exact key, a `*` wildcard pattern, a RegExp, or a LIST of any of\n\t * those - one handler mounted on several events at once. */\n\ttarget: N | RegExp | readonly (string | RegExp)[];\n\t/** Extra input fields this mount adds to the target fn. */\n\textend?: { input?: Ext };\n\thandler: Interceptor;\n};\n\n/**\n * Does an `on` target hit fn key `key`? Exact match, `*` wildcards\n * (\"*\", \"sign_up.*\", \"/sign-up/*\" - a `*` spans anything), a RegExp, or a\n * list (any member hitting counts).\n */\nexport const matchesTarget = (\n\ttarget: string | RegExp | readonly (string | RegExp)[],\n\tkey: string,\n): boolean => {\n\tif (Array.isArray(target)) {\n\t\treturn (target as readonly (string | RegExp)[]).some((member) =>\n\t\t\tmatchesTarget(member, key),\n\t\t);\n\t}\n\tif (target instanceof RegExp) return target.test(key);\n\t// Array.isArray cannot narrow a readonly array out of the union.\n\tconst name = target as string;\n\tif (name === key) return true;\n\tif (!name.includes(\"*\")) return false;\n\tconst pattern = name\n\t\t.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t.replace(/\\*/g, \".*\");\n\treturn new RegExp(`^${pattern}$`).test(key);\n};\n\n/**\n * The type-level half of `matchesTarget`, for input extensions: exact\n * keys and single-`*` patterns narrow call sites; RegExp targets (typed\n * `string`) intercept and validate at runtime but cannot narrow.\n */\nexport type TargetMatches<N, K extends string> = N extends \"*\"\n\t? true\n\t: N extends `${infer Pre}*${infer Suf}`\n\t\t? K extends `${Pre}${string}`\n\t\t\t? Suf extends \"\"\n\t\t\t\t? true\n\t\t\t\t: K extends `${string}${Suf}`\n\t\t\t\t\t? true\n\t\t\t\t\t: false\n\t\t\t: false\n\t\t: N extends K\n\t\t\t? true\n\t\t\t: false;\n\n/**\n * A module is the unit of composition: a RECORD of members - vars, fns,\n * `on` entries, var extensions - usually just what a file exports\n * (`import * as twoFactor`) or a curated bundle. \"Plugin\" is not a\n * concept, only a usage: mounting someone else's module. Always an\n * object, never a bare member: `use: [{ createUser }]`, not\n * `use: [createUser]`. The `never` marks reject bare members at the type\n * level; `resolveModules` rejects them at runtime.\n */\nexport type Module = Record<string, unknown> & {\n\t$var?: never;\n\t$varExtend?: never;\n\t/** Rejects a bare `on` ENTRY (`$on: true`) while letting a storage\n\t * through - its `$on` is the hook-mounting METHOD, not the brand. */\n\t$on?: (...args: never[]) => unknown;\n\t$fn?: never;\n};\n\n/** A module member that can NEST other members: a plain record that is\n * not itself branded. Fn defs are callable, so they never match. */\ntype GroupMember<V> = V extends\n\t| { $var: true }\n\t| { $on: true }\n\t| { $varExtend: true }\n\t| ((...args: any[]) => any)\n\t| readonly unknown[]\n\t? never\n\t: V extends Record<string, unknown>\n\t\t? V\n\t\t: never;\n\ntype VarEntryUnion<M> = {\n\t[K in keyof M]: M[K] extends VarDefination<infer N, infer T, any, any>\n\t\t? { [P in N]: T }\n\t\t: M[K] extends VarExtension<infer N, any, infer BT>\n\t\t\t? unknown extends BT\n\t\t\t\t? never\n\t\t\t\t: { [P in N]: BT }\n\t\t\t: [GroupMember<M[K]>] extends [never]\n\t\t\t\t? never\n\t\t\t\t: VarEntryUnion<GroupMember<M[K]>>;\n}[keyof M];\n\n/**\n * Vars a module exports, keyed by their DECLARED name, not export name.\n * Distributes over `M`: without that, a union of modules collapses to\n * `keyof A & keyof B` and every var is lost. The `[never]` guard matters\n * too - `UnionToIntersection<never>` is `unknown`, and one var-less module\n * in the union would absorb every other module's vars into `unknown`.\n */\nexport type VarsFrom<M> = M extends unknown\n\t? [VarEntryUnion<M>] extends [never]\n\t\t? never\n\t\t: UnionToIntersection<VarEntryUnion<M>>\n\t: never;\n\nexport type ModuleVars<PL> = UnionToIntersection<VarsFrom<Members<PL>>>;\n\n/** Depth budget for nested groups: unbranded records can be arbitrarily\n * deep (schema shapes, values), so the walk stops after a few levels\n * instead of blowing the instantiation limit. */\ntype GroupDepth = [never, 0, 1, 2];\n\n/** A nested GROUP's fns: only real groups holding at least one fn\n * (within the depth budget) survive - everything else drops from the\n * surface. */\ntype GroupFns<V, D extends number> = [D] extends [never]\n\t? never\n\t: [GroupMember<V>] extends [never]\n\t\t? never\n\t\t: [keyof FnEntries<GroupMember<V>, D>] extends [never]\n\t\t\t? never\n\t\t\t: FnEntries<GroupMember<V>, D>;\n\ntype FnEntries<M, D extends number = 3> = {\n\t[K in keyof M as M[K] extends FnDefination<any, any, any, any, any, any>\n\t\t? K\n\t\t: M[K] extends VarDefination<any, any, any, any>\n\t\t\t? K\n\t\t\t: [GroupFns<M[K], GroupDepth[D]>] extends [never]\n\t\t\t\t? never\n\t\t\t\t: K]: M[K] extends FnDefination<any, any, any, any, any, any>\n\t\t? M[K]\n\t\t: M[K] extends VarDefination<any, any, any, any>\n\t\t\t? M[K]\n\t\t\t: GroupFns<M[K], GroupDepth[D]>;\n};\n\n/** Fns and vars a module exports, keyed by EXPORT name. A plain-record\n * member is a GROUP: its members stay nested under the member's name\n * (`use: [{ cookie: { setCookie } }]` -> `c.cookie.setCookie`). A var\n * member is an ALIAS onto the var - `{ cookie: { options: cookieOptions } }`\n * reads and writes the `cookieOptions` var through `c.cookie.options`. */\nexport type FnsFrom<M> = M extends unknown ? FnEntries<M> : never;\n\nexport type ModuleFns<PL> = UnionToIntersection<FnsFrom<Members<PL>>>;\n\nexport const isFn = (value: any): value is FnDefination<any, any> =>\n\ttypeof value === \"function\" && value?.$fn === true;\n\n/**\n * Guard the module list: modules are plain records, and passing a bare\n * fn/var/extension/`on` entry is almost always a mistake (a bare fn would\n * otherwise look like a factory and get CALLED). Fail loudly instead.\n */\nexport const resolveModules = (\n\tmodules: readonly Module[],\n): Record<string, unknown>[] =>\n\tmodules.map((mod) => {\n\t\tif (isFn(mod) || isVar(mod) || isVarExtension(mod) || isOn(mod)) {\n\t\t\tconst bare = mod as { key?: string; name?: string; target?: unknown };\n\t\t\tconst name =\n\t\t\t\tbare.key ??\n\t\t\t\tbare.name ??\n\t\t\t\t(bare.target !== undefined ? String(bare.target) : \"member\");\n\t\t\tthrow new Error(\n\t\t\t\t`modules are objects - wrap the member: use([{ ${name} }]), not use([${name}])`,\n\t\t\t);\n\t\t}\n\t\treturn (mod ?? {}) as Record<string, unknown>;\n\t});\n\n/** Collect every exported fn from a set of plugin modules. */\nexport const collectFns = (\n\tmodules: readonly Module[],\n): Record<string, FnDefination<any, any>> => {\n\tconst fns: Record<string, FnDefination<any, any>> = {};\n\tfor (const mod of resolveModules(modules)) {\n\t\tfor (const [name, value] of Object.entries(mod)) {\n\t\t\tif (isFn(value)) fns[name] = value;\n\t\t}\n\t}\n\treturn fns;\n};\n\n/**\n * A plain-record member that GROUPS other members - not itself branded\n * (fn, var, on entry, var extension) but holding at least one such member,\n * transitively. Storages and other `$`-surfaced objects fail the member\n * test and stay opaque values.\n */\nexport const isNamespace = (\n\tvalue: unknown,\n): value is Record<string, unknown> => {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== Object.prototype && proto !== null) return false;\n\tif (isVar(value) || isOn(value) || isVarExtension(value)) return false;\n\treturn Object.values(value).some(\n\t\t(m) =>\n\t\t\tisFn(m) || isVar(m) || isOn(m) || isVarExtension(m) || isNamespace(m),\n\t);\n};\n\n/**\n * Every exported fn AND var, with plain-record GROUPS kept as nested\n * namespaces: `use: [{ cookie: { setCookie } }]` lands the fn on\n * `c.cookie.setCookie`. A var member becomes an ALIAS under its export\n * name (`{ cookie: { options: cookieOptions } }` -> `c.cookie.options`\n * reads/writes the var). Groups holding nothing (however deep) drop out.\n */\nexport const collectUsable = (\n\tmodules: readonly Module[],\n): Record<string, unknown> => {\n\tconst walk = (mod: Record<string, unknown>): Record<string, unknown> => {\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [name, value] of Object.entries(mod)) {\n\t\t\tif (isFn(value) || isVar(value)) {\n\t\t\t\tout[name] = value;\n\t\t\t} else if (isNamespace(value)) {\n\t\t\t\tconst nested = walk(value);\n\t\t\t\tif (Object.keys(nested).length > 0) out[name] = nested;\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t};\n\tconst fns: Record<string, unknown> = {};\n\tfor (const mod of resolveModules(modules)) Object.assign(fns, walk(mod));\n\treturn fns;\n};\n\nexport const isOn = (value: any): value is OnEntry<string> =>\n\tvalue?.$on === true;\n\n/**\n * Mount onto another fn by name. The handler replaces that fn's body and\n * receives `next` - call it to delegate, or don't.\n *\n * Sounder than a before/after hook: it has the target's signature, runs\n * INSIDE the target's contract checks (so skipping `next` still has to\n * satisfy `provides`), and composes as a stack.\n *\n * The middle argument extends the target's INPUT: those fields are\n * validated alongside the fn's own, land on `c.input`, and - through\n * `ApplyOns` - become required at every call site that mounts this entry.\n */\n/** The var name a `var.set.…`/`var.get.…` target addresses - literal when\n * exact. */\ntype VarNameOf<T extends string> = T extends `var.${\"set\" | \"get\"}.${infer N}`\n\t? N extends `${string}*${string}`\n\t\t? string\n\t\t: N\n\t: string;\n\n/** What a `var.set.…` handler receives. Writes are synchronous, so the\n * handler must be too - call `next()` to let the write land, skip it to\n * cancel, throw to abort. */\nexport type VarSetContext<N extends string = string> = {\n\t/** The var being written. */\n\tname: N;\n\t/** The incoming value. */\n\tvalue: unknown;\n\t/** The fn frame performing the write. */\n\tfn: string;\n\t/** Every other property reads the scope's vars directly. */\n\t[key: string]: unknown;\n};\n\n/** What a `var.get.…` handler receives. Reads are synchronous, so the\n * handler must be too - `next()` yields the stored value and whatever the\n * handler returns becomes the read result. */\nexport type VarGetContext<N extends string = string> = {\n\t/** The var being read. */\n\tname: N;\n\t/** The fn frame performing the read. */\n\tfn: string;\n\t/** Every other property reads the scope's vars (raw - no get hooks). */\n\t[key: string]: unknown;\n};\n\ntype FnInputOf<F> =\n\tF extends FnDefination<any, any, any, infer I, any, any>\n\t\t? InferInput<I>\n\t\t: never;\n\ntype FnResultOf<F> =\n\tF extends FnDefination<any, infer R, any, any, any, any> ? Awaited<R> : never;\n\nexport function on<T extends \"var.set.*\" | `var.set.${string}`>(\n\ttarget: T,\n\thandler: (c: VarSetContext<VarNameOf<T>>, next: () => void) => void,\n): OnEntry<T>;\nexport function on<T extends \"var.get.*\" | `var.get.${string}`>(\n\ttarget: T,\n\thandler: (c: VarGetContext<VarNameOf<T>>, next: () => unknown) => unknown,\n): OnEntry<T>;\nexport function on<F extends FnDefination<any, any, string, any, any, any>>(\n\ttarget: F,\n\thandler: (\n\t\tc: Omit<OnDefaultContext, \"input\"> & { input: FnInputOf<F> },\n\t\tnext: () => Promise<FnResultOf<F>>,\n\t) => any,\n): OnEntry<F[\"key\"]>;\nexport function on<\n\tF extends FnDefination<any, any, string, any, any, any>,\n\tconst Ext,\n>(\n\ttarget: F,\n\textend: { input: Ext },\n\thandler: (\n\t\tc: Omit<OnDefaultContext, \"input\"> & {\n\t\t\tinput: FnInputOf<F> & InferInput<Ext>;\n\t\t},\n\t\tnext: () => Promise<FnResultOf<F>>,\n\t) => any,\n): OnEntry<F[\"key\"], Ext>;\nexport function on(\n\ttargets: readonly (\n\t\t| LiteralString\n\t\t| RegExp\n\t\t| FnDefination<any, any, string, any, any, any>\n\t)[],\n\thandler: (c: OnDefaultContext, next: () => Promise<any>) => any,\n): OnEntry<string>;\nexport function on(\n\ttarget: RegExp,\n\thandler: (c: OnDefaultContext, next: () => Promise<any>) => any,\n): OnEntry<string>;\nexport function on<N extends \"*\" | LiteralString>(\n\ttarget: N,\n\thandler: (c: OnDefaultContext, next: () => Promise<any>) => any,\n): OnEntry<N>;\nexport function on<const Ext>(\n\ttarget: RegExp,\n\textend: { input: Ext },\n\thandler: (\n\t\tc: Omit<OnDefaultContext, \"input\"> & {\n\t\t\tinput: InferInput<Ext> & Record<string, any>;\n\t\t},\n\t\tnext: () => Promise<any>,\n\t) => any,\n): OnEntry<string, Ext>;\nexport function on<N extends LiteralString, const Ext>(\n\ttarget: N,\n\textend: { input: Ext },\n\thandler: (\n\t\tc: Omit<OnDefaultContext, \"input\"> & {\n\t\t\tinput: InferInput<Ext> & Record<string, any>;\n\t\t},\n\t\tnext: () => Promise<any>,\n\t) => any,\n): OnEntry<N, Ext>;\nexport function on(\n\ttarget:\n\t\t| string\n\t\t| RegExp\n\t\t| FnDefination<any, any, string, any, any, any>\n\t\t| readonly (\n\t\t\t\t| string\n\t\t\t\t| RegExp\n\t\t\t\t| FnDefination<any, any, string, any, any, any>\n\t\t )[],\n\textendOrHandler: any,\n\tmaybeHandler?: any,\n): OnEntry<string, any> {\n\t// A fn reference targets its own key - no string to typo. A LIST\n\t// resolves member-wise: one handler, several events.\n\tconst resolveOne = (member: unknown) =>\n\t\tisFn(member)\n\t\t\t? (member as { key: string }).key\n\t\t\t: (member as string | RegExp);\n\tconst resolved = (\n\t\tArray.isArray(target) ? target.map(resolveOne) : resolveOne(target)\n\t) as string | RegExp | readonly (string | RegExp)[];\n\treturn typeof extendOrHandler === \"function\"\n\t\t? { $on: true, target: resolved, handler: extendOrHandler }\n\t\t: {\n\t\t\t\t$on: true,\n\t\t\t\ttarget: resolved,\n\t\t\t\textend: extendOrHandler,\n\t\t\t\thandler: maybeHandler,\n\t\t\t};\n}\n\n/* ----------------------------- var extension ------------------------------ */\n\nexport type VarExtension<N extends string, S, BaseT = unknown> = {\n\t$varExtend: true;\n\tname: N;\n\tschema: S;\n\t/** The var being extended, when handed by reference. */\n\tbase?: VarDefination<N, BaseT, any, any>;\n};\n\nexport const isVarExtension = (\n\tvalue: any,\n): value is VarExtension<string, any> => value?.$varExtend === true;\n\n/**\n * Extend a var's shape from a module. Where `customize` mints a NEW var\n * definition to re-export, an extension is a mountable value: every scope\n * or fn that `use`s the module containing it sees the var widened, and\n * nothing that doesn't mount it is affected.\n *\n * Handed the var by REFERENCE, the extension carries it: mounting just\n * the extension brings the var itself, merged by its declared key - no\n * need to also mount the base var.\n */\nexport function extendVar<N extends LiteralString, S, BaseT>(\n\ttarget: VarDefination<N, BaseT, any, any>,\n\tschema: S,\n): VarExtension<N, S, BaseT>;\nexport function extendVar<N extends LiteralString, S>(\n\ttarget: N,\n\tschema: S,\n): VarExtension<N, S>;\nexport function extendVar(\n\ttarget: VarDefination<string, any, any, any> | string,\n\tschema: any,\n): VarExtension<string, any, any> {\n\treturn typeof target === \"string\"\n\t\t? { $varExtend: true, name: target, schema }\n\t\t: { $varExtend: true, name: target.name, schema, base: target };\n}\n\ntype VarExtEntry<M, K extends string> = M extends unknown\n\t? {\n\t\t\t[P in keyof M]: M[P] extends VarExtension<K, infer S>\n\t\t\t\t? InferInput<S>\n\t\t\t\t: never;\n\t\t}[keyof M]\n\t: never;\n\n/**\n * Shape additions modules in `PL` mount on var `K`. Resolves to `unknown`\n * when none - which intersects away harmlessly.\n */\nexport type VarExtensionsFor<PL, K extends string> = UnionToIntersection<\n\tVarExtEntry<Members<PL>, K>\n>;\n\ntype VarExtArgsEntry<M, K extends string> = M extends unknown\n\t? {\n\t\t\t[P in keyof M]: M[P] extends VarExtension<K, infer S>\n\t\t\t\t? InferArgs<S>\n\t\t\t\t: never;\n\t\t}[keyof M]\n\t: never;\n\n/** The ARGS side of the same extensions - what a caller must send. */\nexport type VarExtensionArgsFor<PL, K extends string> = UnionToIntersection<\n\tVarExtArgsEntry<Members<PL>, K>\n>;\n\n/** The args side of every VAR named `K` a module set declares - a\n * `customize`d re-export shadows by NAME, so mounting it counts as a\n * declaration about the same var. Schema-less vars contribute nothing. */\ntype VarShadowArgsEntry<M, K extends string> = M extends unknown\n\t? {\n\t\t\t[P in keyof M]: M[P] extends VarDefination<K, any, infer S, any>\n\t\t\t\t? unknown extends S\n\t\t\t\t\t? never\n\t\t\t\t\t: [NonNullable<S>] extends [never]\n\t\t\t\t\t\t? never\n\t\t\t\t\t\t: InferArgs<NonNullable<S>>\n\t\t\t\t: never;\n\t\t}[keyof M]\n\t: never;\n\n/**\n * Everything a module set says about var `K`'s ARGS side: extensions\n * mounted on it, intersected with every same-name var declaration. This is\n * what widens a fn schema whose input references `K` (see `WidenSchemaFns`)\n * - `unknown` when the scope adds nothing, which intersects away.\n */\nexport type VarArgsInScope<PL, K extends string> = VarExtensionArgsFor<PL, K> &\n\t([VarShadowArgsEntry<Members<PL>, K>] extends [never]\n\t\t? unknown\n\t\t: UnionToIntersection<VarShadowArgsEntry<Members<PL>, K>>);\n\ntype VarFieldKeys<I> = {\n\t[K in keyof I]: I[K] extends { $var: true } ? K : never;\n}[keyof I];\n\n/**\n * Extra args a fn must accept because its INPUT references vars that `PL`\n * extends. Whole-var input (`input: user`) merges at the top level; a var\n * used as a field widens that field. `unknown` when nothing applies.\n */\nexport type InputVarExtra<PL, I> = I extends {\n\t$var: true;\n\tname: infer N extends string;\n}\n\t? VarExtensionArgsFor<PL, N>\n\t: [VarFieldKeys<I>] extends [never]\n\t\t? unknown\n\t\t: {\n\t\t\t\t[K in keyof I as I[K] extends { $var: true }\n\t\t\t\t\t? K\n\t\t\t\t\t: never]: I[K] extends {\n\t\t\t\t\t$var: true;\n\t\t\t\t\tname: infer N extends string;\n\t\t\t\t}\n\t\t\t\t\t? VarExtensionArgsFor<PL, N>\n\t\t\t\t\t: unknown;\n\t\t\t};\n\n/* ------------------------------- extension -------------------------------- */\n\ntype ExtEntryArgs<M, K extends string> = M extends unknown\n\t? {\n\t\t\t[P in keyof M]: M[P] extends OnEntry<infer N, infer E>\n\t\t\t\t? unknown extends E\n\t\t\t\t\t? never\n\t\t\t\t\t: TargetMatches<N, K> extends true\n\t\t\t\t\t\t? InferArgs<E>\n\t\t\t\t\t\t: never\n\t\t\t\t: never;\n\t\t}[keyof M]\n\t: never;\n\n/** Args added onto fn `K` by every extending `on` entry in `PL`. */\nexport type ExtendedArgs<PL, K extends string> = UnionToIntersection<\n\tExtEntryArgs<Members<PL>, K>\n>;\n\n/**\n * Rewrite a fn's type with the input extensions the module set `PL`\n * mounts on it. This is how a plugin's extra field becomes REQUIRED at\n * the call site, even though the fn itself never declared it.\n */\nexport type ApplyOn<F, PL> =\n\tF extends FnDefination<\n\t\tinfer A,\n\t\tinfer R,\n\t\tinfer K,\n\t\tinfer I,\n\t\tinfer P,\n\t\tinfer Er,\n\t\tinfer W,\n\t\tinfer O\n\t>\n\t\t? unknown extends ExtendedArgs<PL, K & string> & InputVarExtra<PL, I>\n\t\t\t? F\n\t\t\t: FnDefination<\n\t\t\t\t\tPrettify<\n\t\t\t\t\t\t([A] extends [void] ? unknown : A) &\n\t\t\t\t\t\t\tExtendedArgs<PL, K & string> &\n\t\t\t\t\t\t\tInputVarExtra<PL, I>\n\t\t\t\t\t>,\n\t\t\t\t\tR,\n\t\t\t\t\tK & string,\n\t\t\t\t\tI,\n\t\t\t\t\tP,\n\t\t\t\t\tEr,\n\t\t\t\t\tW,\n\t\t\t\t\tO\n\t\t\t\t>\n\t\t: F;\n\nexport type ApplyOns<Fns, PL> = { [P in keyof Fns]: ApplyOn<Fns[P], PL> };\n\n/* -------------------------------- derived --------------------------------- */\n\ntype DerivedNamesEntry<Mod, Q> = Mod extends unknown\n\t? {\n\t\t\t[K in keyof Mod]: Mod[K] extends VarDefination<\n\t\t\t\tinfer N,\n\t\t\t\tany,\n\t\t\t\tany,\n\t\t\t\tinfer Src\n\t\t\t>\n\t\t\t\t? [Src] extends [never]\n\t\t\t\t\t? never\n\t\t\t\t\t: Src extends Q\n\t\t\t\t\t\t? N\n\t\t\t\t\t\t: never\n\t\t\t\t: never;\n\t\t}[keyof Mod]\n\t: never;\n\n/**\n * Expand a `requires` set with every var DERIVED from a required source:\n * requiring `request` makes `method`, `path`, ... non-null too, because\n * they are computed from it.\n */\nexport type WithDerived<PL, BasePL, Q> =\n\t| Q\n\t| DerivedNamesEntry<Members<PL> | Members<BasePL>, Q>;\n"],"mappings":"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"}
@@ -0,0 +1,249 @@
1
+ import { LiteralString, Members, Prettify, UnionToIntersection } from "./types.cjs";
2
+ import { InferArgs, InferInput, vTypes } from "./schema.cjs";
3
+ import { VarDefination } from "./var.cjs";
4
+ import { FnDefination } from "./fn.cjs";
5
+ //#region src/module.d.ts
6
+ type Interceptor = (c: any, next: () => Promise<any>) => any;
7
+ /**
8
+ * What a GLOBAL `v.on` handler sees. Without a builder there is no scope
9
+ * to infer, but the context's shape is always the same - so the default
10
+ * is structured with loose leaves, never `any`: `c.input.code` works,
11
+ * `c.tpyo` does not. Mount the entry on a builder's `on` for real types.
12
+ */
13
+ type OnDefaultContext = {
14
+ input: Record<string, any>;
15
+ types: typeof vTypes;
16
+ fn: unknown;
17
+ /** Vars and used fns live directly on `c` - untyped here; mount the
18
+ * entry on a builder's `on` for real types. */
19
+ [key: string]: any;
20
+ };
21
+ type OnEntry<N extends string, Ext = unknown> = {
22
+ $on: true;
23
+ /** Exact key, a `*` wildcard pattern, a RegExp, or a LIST of any of
24
+ * those - one handler mounted on several events at once. */
25
+ target: N | RegExp | readonly (string | RegExp)[];
26
+ /** Extra input fields this mount adds to the target fn. */
27
+ extend?: {
28
+ input?: Ext;
29
+ };
30
+ handler: Interceptor;
31
+ };
32
+ /**
33
+ * The type-level half of `matchesTarget`, for input extensions: exact
34
+ * keys and single-`*` patterns narrow call sites; RegExp targets (typed
35
+ * `string`) intercept and validate at runtime but cannot narrow.
36
+ */
37
+ type TargetMatches<N, K extends string> = N extends "*" ? true : N extends `${infer Pre}*${infer Suf}` ? K extends `${Pre}${string}` ? Suf extends "" ? true : K extends `${string}${Suf}` ? true : false : false : N extends K ? true : false;
38
+ /**
39
+ * A module is the unit of composition: a RECORD of members - vars, fns,
40
+ * `on` entries, var extensions - usually just what a file exports
41
+ * (`import * as twoFactor`) or a curated bundle. "Plugin" is not a
42
+ * concept, only a usage: mounting someone else's module. Always an
43
+ * object, never a bare member: `use: [{ createUser }]`, not
44
+ * `use: [createUser]`. The `never` marks reject bare members at the type
45
+ * level; `resolveModules` rejects them at runtime.
46
+ */
47
+ type Module = Record<string, unknown> & {
48
+ $var?: never;
49
+ $varExtend?: never;
50
+ /** Rejects a bare `on` ENTRY (`$on: true`) while letting a storage
51
+ * through - its `$on` is the hook-mounting METHOD, not the brand. */
52
+ $on?: (...args: never[]) => unknown;
53
+ $fn?: never;
54
+ };
55
+ /** A module member that can NEST other members: a plain record that is
56
+ * not itself branded. Fn defs are callable, so they never match. */
57
+ type GroupMember<V> = V extends {
58
+ $var: true;
59
+ } | {
60
+ $on: true;
61
+ } | {
62
+ $varExtend: true;
63
+ } | ((...args: any[]) => any) | readonly unknown[] ? never : V extends Record<string, unknown> ? V : never;
64
+ type VarEntryUnion<M> = { [K in keyof M]: M[K] extends VarDefination<infer N, infer T, any, any> ? { [P in N]: T; } : M[K] extends VarExtension<infer N, any, infer BT> ? unknown extends BT ? never : { [P in N]: BT; } : [GroupMember<M[K]>] extends [never] ? never : VarEntryUnion<GroupMember<M[K]>>; }[keyof M];
65
+ /**
66
+ * Vars a module exports, keyed by their DECLARED name, not export name.
67
+ * Distributes over `M`: without that, a union of modules collapses to
68
+ * `keyof A & keyof B` and every var is lost. The `[never]` guard matters
69
+ * too - `UnionToIntersection<never>` is `unknown`, and one var-less module
70
+ * in the union would absorb every other module's vars into `unknown`.
71
+ */
72
+ type VarsFrom<M> = M extends unknown ? [VarEntryUnion<M>] extends [never] ? never : UnionToIntersection<VarEntryUnion<M>> : never;
73
+ type ModuleVars<PL> = UnionToIntersection<VarsFrom<Members<PL>>>;
74
+ /** Depth budget for nested groups: unbranded records can be arbitrarily
75
+ * deep (schema shapes, values), so the walk stops after a few levels
76
+ * instead of blowing the instantiation limit. */
77
+ type GroupDepth = [never, 0, 1, 2];
78
+ /** A nested GROUP's fns: only real groups holding at least one fn
79
+ * (within the depth budget) survive - everything else drops from the
80
+ * surface. */
81
+ type GroupFns<V, D extends number> = [D] extends [never] ? never : [GroupMember<V>] extends [never] ? never : [keyof FnEntries<GroupMember<V>, D>] extends [never] ? never : FnEntries<GroupMember<V>, D>;
82
+ type FnEntries<M, D extends number = 3> = { [K in keyof M as M[K] extends FnDefination<any, any, any, any, any, any> ? K : M[K] extends VarDefination<any, any, any, any> ? K : [GroupFns<M[K], GroupDepth[D]>] extends [never] ? never : K]: M[K] extends FnDefination<any, any, any, any, any, any> ? M[K] : M[K] extends VarDefination<any, any, any, any> ? M[K] : GroupFns<M[K], GroupDepth[D]>; };
83
+ /** Fns and vars a module exports, keyed by EXPORT name. A plain-record
84
+ * member is a GROUP: its members stay nested under the member's name
85
+ * (`use: [{ cookie: { setCookie } }]` -> `c.cookie.setCookie`). A var
86
+ * member is an ALIAS onto the var - `{ cookie: { options: cookieOptions } }`
87
+ * reads and writes the `cookieOptions` var through `c.cookie.options`. */
88
+ type FnsFrom<M> = M extends unknown ? FnEntries<M> : never;
89
+ type ModuleFns<PL> = UnionToIntersection<FnsFrom<Members<PL>>>;
90
+ declare const isFn: (value: any) => value is FnDefination<any, any>;
91
+ /** Collect every exported fn from a set of plugin modules. */
92
+ declare const collectFns: (modules: readonly Module[]) => Record<string, FnDefination<any, any>>;
93
+ /**
94
+ * A plain-record member that GROUPS other members - not itself branded
95
+ * (fn, var, on entry, var extension) but holding at least one such member,
96
+ * transitively. Storages and other `$`-surfaced objects fail the member
97
+ * test and stay opaque values.
98
+ */
99
+ declare const isNamespace: (value: unknown) => value is Record<string, unknown>;
100
+ /**
101
+ * Every exported fn AND var, with plain-record GROUPS kept as nested
102
+ * namespaces: `use: [{ cookie: { setCookie } }]` lands the fn on
103
+ * `c.cookie.setCookie`. A var member becomes an ALIAS under its export
104
+ * name (`{ cookie: { options: cookieOptions } }` -> `c.cookie.options`
105
+ * reads/writes the var). Groups holding nothing (however deep) drop out.
106
+ */
107
+ declare const collectUsable: (modules: readonly Module[]) => Record<string, unknown>;
108
+ declare const isOn: (value: any) => value is OnEntry<string>;
109
+ /**
110
+ * Mount onto another fn by name. The handler replaces that fn's body and
111
+ * receives `next` - call it to delegate, or don't.
112
+ *
113
+ * Sounder than a before/after hook: it has the target's signature, runs
114
+ * INSIDE the target's contract checks (so skipping `next` still has to
115
+ * satisfy `provides`), and composes as a stack.
116
+ *
117
+ * The middle argument extends the target's INPUT: those fields are
118
+ * validated alongside the fn's own, land on `c.input`, and - through
119
+ * `ApplyOns` - become required at every call site that mounts this entry.
120
+ */
121
+ /** The var name a `var.set.…`/`var.get.…` target addresses - literal when
122
+ * exact. */
123
+ type VarNameOf<T extends string> = T extends `var.${"set" | "get"}.${infer N}` ? N extends `${string}*${string}` ? string : N : string;
124
+ /** What a `var.set.…` handler receives. Writes are synchronous, so the
125
+ * handler must be too - call `next()` to let the write land, skip it to
126
+ * cancel, throw to abort. */
127
+ type VarSetContext<N extends string = string> = {
128
+ /** The var being written. */
129
+ name: N;
130
+ /** The incoming value. */
131
+ value: unknown;
132
+ /** The fn frame performing the write. */
133
+ fn: string;
134
+ /** Every other property reads the scope's vars directly. */
135
+ [key: string]: unknown;
136
+ };
137
+ /** What a `var.get.…` handler receives. Reads are synchronous, so the
138
+ * handler must be too - `next()` yields the stored value and whatever the
139
+ * handler returns becomes the read result. */
140
+ type VarGetContext<N extends string = string> = {
141
+ /** The var being read. */
142
+ name: N;
143
+ /** The fn frame performing the read. */
144
+ fn: string;
145
+ /** Every other property reads the scope's vars (raw - no get hooks). */
146
+ [key: string]: unknown;
147
+ };
148
+ type FnInputOf<F> = F extends FnDefination<any, any, any, infer I, any, any> ? InferInput<I> : never;
149
+ type FnResultOf<F> = F extends FnDefination<any, infer R, any, any, any, any> ? Awaited<R> : never;
150
+ declare function on<T extends "var.set.*" | `var.set.${string}`>(target: T, handler: (c: VarSetContext<VarNameOf<T>>, next: () => void) => void): OnEntry<T>;
151
+ declare function on<T extends "var.get.*" | `var.get.${string}`>(target: T, handler: (c: VarGetContext<VarNameOf<T>>, next: () => unknown) => unknown): OnEntry<T>;
152
+ declare function on<F extends FnDefination<any, any, string, any, any, any>>(target: F, handler: (c: Omit<OnDefaultContext, "input"> & {
153
+ input: FnInputOf<F>;
154
+ }, next: () => Promise<FnResultOf<F>>) => any): OnEntry<F["key"]>;
155
+ declare function on<F extends FnDefination<any, any, string, any, any, any>, const Ext>(target: F, extend: {
156
+ input: Ext;
157
+ }, handler: (c: Omit<OnDefaultContext, "input"> & {
158
+ input: FnInputOf<F> & InferInput<Ext>;
159
+ }, next: () => Promise<FnResultOf<F>>) => any): OnEntry<F["key"], Ext>;
160
+ declare function on(targets: readonly (LiteralString | RegExp | FnDefination<any, any, string, any, any, any>)[], handler: (c: OnDefaultContext, next: () => Promise<any>) => any): OnEntry<string>;
161
+ declare function on(target: RegExp, handler: (c: OnDefaultContext, next: () => Promise<any>) => any): OnEntry<string>;
162
+ declare function on<N extends "*" | LiteralString>(target: N, handler: (c: OnDefaultContext, next: () => Promise<any>) => any): OnEntry<N>;
163
+ declare function on<const Ext>(target: RegExp, extend: {
164
+ input: Ext;
165
+ }, handler: (c: Omit<OnDefaultContext, "input"> & {
166
+ input: InferInput<Ext> & Record<string, any>;
167
+ }, next: () => Promise<any>) => any): OnEntry<string, Ext>;
168
+ declare function on<N extends LiteralString, const Ext>(target: N, extend: {
169
+ input: Ext;
170
+ }, handler: (c: Omit<OnDefaultContext, "input"> & {
171
+ input: InferInput<Ext> & Record<string, any>;
172
+ }, next: () => Promise<any>) => any): OnEntry<N, Ext>;
173
+ type VarExtension<N extends string, S, BaseT = unknown> = {
174
+ $varExtend: true;
175
+ name: N;
176
+ schema: S;
177
+ /** The var being extended, when handed by reference. */
178
+ base?: VarDefination<N, BaseT, any, any>;
179
+ };
180
+ declare const isVarExtension: (value: any) => value is VarExtension<string, any>;
181
+ /**
182
+ * Extend a var's shape from a module. Where `customize` mints a NEW var
183
+ * definition to re-export, an extension is a mountable value: every scope
184
+ * or fn that `use`s the module containing it sees the var widened, and
185
+ * nothing that doesn't mount it is affected.
186
+ *
187
+ * Handed the var by REFERENCE, the extension carries it: mounting just
188
+ * the extension brings the var itself, merged by its declared key - no
189
+ * need to also mount the base var.
190
+ */
191
+ declare function extendVar<N extends LiteralString, S, BaseT>(target: VarDefination<N, BaseT, any, any>, schema: S): VarExtension<N, S, BaseT>;
192
+ declare function extendVar<N extends LiteralString, S>(target: N, schema: S): VarExtension<N, S>;
193
+ type VarExtEntry<M, K extends string> = M extends unknown ? { [P in keyof M]: M[P] extends VarExtension<K, infer S> ? InferInput<S> : never; }[keyof M] : never;
194
+ /**
195
+ * Shape additions modules in `PL` mount on var `K`. Resolves to `unknown`
196
+ * when none - which intersects away harmlessly.
197
+ */
198
+ type VarExtensionsFor<PL, K extends string> = UnionToIntersection<VarExtEntry<Members<PL>, K>>;
199
+ type VarExtArgsEntry<M, K extends string> = M extends unknown ? { [P in keyof M]: M[P] extends VarExtension<K, infer S> ? InferArgs<S> : never; }[keyof M] : never;
200
+ /** The ARGS side of the same extensions - what a caller must send. */
201
+ type VarExtensionArgsFor<PL, K extends string> = UnionToIntersection<VarExtArgsEntry<Members<PL>, K>>;
202
+ /** The args side of every VAR named `K` a module set declares - a
203
+ * `customize`d re-export shadows by NAME, so mounting it counts as a
204
+ * declaration about the same var. Schema-less vars contribute nothing. */
205
+ type VarShadowArgsEntry<M, K extends string> = M extends unknown ? { [P in keyof M]: M[P] extends VarDefination<K, any, infer S, any> ? unknown extends S ? never : [NonNullable<S>] extends [never] ? never : InferArgs<NonNullable<S>> : never; }[keyof M] : never;
206
+ /**
207
+ * Everything a module set says about var `K`'s ARGS side: extensions
208
+ * mounted on it, intersected with every same-name var declaration. This is
209
+ * what widens a fn schema whose input references `K` (see `WidenSchemaFns`)
210
+ * - `unknown` when the scope adds nothing, which intersects away.
211
+ */
212
+ type VarArgsInScope<PL, K extends string> = VarExtensionArgsFor<PL, K> & ([VarShadowArgsEntry<Members<PL>, K>] extends [never] ? unknown : UnionToIntersection<VarShadowArgsEntry<Members<PL>, K>>);
213
+ type VarFieldKeys<I> = { [K in keyof I]: I[K] extends {
214
+ $var: true;
215
+ } ? K : never; }[keyof I];
216
+ /**
217
+ * Extra args a fn must accept because its INPUT references vars that `PL`
218
+ * extends. Whole-var input (`input: user`) merges at the top level; a var
219
+ * used as a field widens that field. `unknown` when nothing applies.
220
+ */
221
+ type InputVarExtra<PL, I> = I extends {
222
+ $var: true;
223
+ name: infer N extends string;
224
+ } ? VarExtensionArgsFor<PL, N> : [VarFieldKeys<I>] extends [never] ? unknown : { [K in keyof I as I[K] extends {
225
+ $var: true;
226
+ } ? K : never]: I[K] extends {
227
+ $var: true;
228
+ name: infer N extends string;
229
+ } ? VarExtensionArgsFor<PL, N> : unknown; };
230
+ type ExtEntryArgs<M, K extends string> = M extends unknown ? { [P in keyof M]: M[P] extends OnEntry<infer N, infer E> ? unknown extends E ? never : TargetMatches<N, K> extends true ? InferArgs<E> : never : never; }[keyof M] : never;
231
+ /** Args added onto fn `K` by every extending `on` entry in `PL`. */
232
+ type ExtendedArgs<PL, K extends string> = UnionToIntersection<ExtEntryArgs<Members<PL>, K>>;
233
+ /**
234
+ * Rewrite a fn's type with the input extensions the module set `PL`
235
+ * mounts on it. This is how a plugin's extra field becomes REQUIRED at
236
+ * the call site, even though the fn itself never declared it.
237
+ */
238
+ type ApplyOn<F, PL> = F extends FnDefination<infer A, infer R, infer K, infer I, infer P, infer Er, infer W, infer O> ? unknown extends ExtendedArgs<PL, K & string> & InputVarExtra<PL, I> ? F : FnDefination<Prettify<([A] extends [void] ? unknown : A) & ExtendedArgs<PL, K & string> & InputVarExtra<PL, I>>, R, K & string, I, P, Er, W, O> : F;
239
+ type ApplyOns<Fns, PL> = { [P in keyof Fns]: ApplyOn<Fns[P], PL>; };
240
+ type DerivedNamesEntry<Mod, Q> = Mod extends unknown ? { [K in keyof Mod]: Mod[K] extends VarDefination<infer N, any, any, infer Src> ? [Src] extends [never] ? never : Src extends Q ? N : never : never; }[keyof Mod] : never;
241
+ /**
242
+ * Expand a `requires` set with every var DERIVED from a required source:
243
+ * requiring `request` makes `method`, `path`, ... non-null too, because
244
+ * they are computed from it.
245
+ */
246
+ type WithDerived<PL, BasePL, Q> = Q | DerivedNamesEntry<Members<PL> | Members<BasePL>, Q>;
247
+ //#endregion
248
+ export { ApplyOn, ApplyOns, ExtendedArgs, FnsFrom, InputVarExtra, Interceptor, Module, ModuleFns, ModuleVars, OnDefaultContext, OnEntry, TargetMatches, VarArgsInScope, VarExtension, VarExtensionArgsFor, VarExtensionsFor, VarGetContext, VarSetContext, VarsFrom, WithDerived, collectFns, collectUsable, extendVar, isFn, isNamespace, isOn, isVarExtension, on };
249
+ //# sourceMappingURL=module.d.cts.map