import { IsAny } from "./type-utils.mjs"; import { AnyRouteDescriptor, RouteDescriptor } from "./route.mjs"; import { PluginStores, StoreEffect } from "./stores.mjs"; import { PluginHooks } from "./plugin.mjs"; import { RouteContext } from "./context.mjs"; //#region src/define-plugin.d.ts /** Invoke one of the plugin's routes from `actions`. */ type RunRoute = (route: RouteDescriptor, input: I) => Promise; /** * The models a client plugin may contribute extra fields to. Each optional key * maps a model name to the extra fields the plugin adds. */ type PluginSchema = { user?: object; }; type AnyUserFields = any; /** The fields declared for one model, or `Fallback` when there are none. */ type FieldsOf = F extends Record ? (T extends object ? T : Fallback) : Fallback; /** * The `user` fields a plugin itself declared via `schema` — used to type the * plugin's own `ctx`, so an action can read its own contributions off * `ctx.store.$session` without a cast. A plugin without a `user` schema sees the * base context (`unknown`); widened `any` stays `any` so a concrete plugin * remains assignable to `AnyClientPlugin`. */ type OwnUserFields = IsAny extends true ? AnyUserFields : FieldsOf; type ClientPlugin = { readonly id: Id; /** Default mount path relative to the client `basePath`, e.g. `"/magic-link"`; omit for the root (`""`). */ readonly basePath?: BasePath; readonly routes: Routes; readonly hooks?: PluginHooks; readonly actions?: (ctx: RouteContext>, run: RunRoute) => Actions; /** * Type-only declaration of the extra model fields this plugin contributes to * the client read surfaces — folded in only when the plugin is registered. * Declare it with {@link schema}. */ readonly schema?: Schema; /** * Reactive stores this plugin owns, declared with {@link defineStores}. Names * are global to the client: two plugins cannot claim the same one. */ readonly stores?: (ctx: RouteContext>) => Stores; /** Reactions to store writes, declared with {@link effect}. */ readonly effects?: readonly StoreEffect[]; }; type AnyClientPlugin = ClientPlugin; declare function defineRoutes(...routes: Routes): Routes; /** Register a plugin's stores, preserving each name for `$name` and `useName()`. */ declare function defineStores(stores: Stores): Stores; declare function defineClientPlugin, const BasePath extends string = "", Schema = unknown, const Stores extends PluginStores = Record>(def: ClientPlugin): ClientPlugin; /** * Declare the extra model fields a plugin contributes — type-only. The returned * value is a phantom (never read at runtime); actual values come from the * central session parse. * * @example * schema: schema<{ user: { twoFactorEnabled: boolean } }>(), */ declare function schema, never>>(): T; /** * Reject config keys a plugin does not declare. TypeScript skips * excess-property checking when the target is a type parameter, so a factory's * `const Config extends StrictConfig` has to do it. */ type StrictConfig = Allowed & Record, never>; /** A plugin's model names mapped to the app columns declared on each. */ type ModelFields = Record; /** The columns declared in a plugin's config, or none. */ type DeclaredFields = Config extends { fields: infer M; } ? M : unknown; /** Build a plugin's `fields()` declaration function, constrained to its own models. */ declare function defineFields(): , never>>() => T; //#endregion export { AnyClientPlugin, ClientPlugin, DeclaredFields, FieldsOf, ModelFields, PluginSchema, RunRoute, StrictConfig, defineClientPlugin, defineFields, defineRoutes, defineStores, schema };