first commit
This commit is contained in:
82
docs/api-stack/api/api-plugin-tenant/src/schemas/options.md
Normal file
82
docs/api-stack/api/api-plugin-tenant/src/schemas/options.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# `options`
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the Zod schema validated at the `createTenantPlugin` boundary
|
||||
plus the strategy-spec discriminated-union schema each strategy is
|
||||
parsed against. Boundary validation catches configuration mistakes at
|
||||
plugin-construction time — long before a request hits the resolver
|
||||
chain — and surfaces them as `TenantPluginError(INVALID_INPUT)` with
|
||||
the original `ZodError` carried as `cause` for developer feedback.
|
||||
|
||||
## Features
|
||||
|
||||
- `TenantStrategySpecSchema` — discriminated union over the seven
|
||||
strategy variants. Catches typos in the `type` field, missing
|
||||
required parameters per variant, and empty strings.
|
||||
- `TenantPluginOptionsSchema` — full options object validated as a
|
||||
unit. Applies defaults for `required` (`false`), `allowSuspended`
|
||||
(`false`), and `routePrefix` (`"/tenants"`).
|
||||
- Custom `z.custom` validators for `store`, `logger`, and the optional
|
||||
rate-limit `store` so duck-typing accepts any conforming object
|
||||
without the schema needing to know the full implementation surface.
|
||||
- `routePrefix` regex enforces leading `/`, no trailing `/` (unless
|
||||
the prefix is exactly `/`), and a conservative character set so the
|
||||
resulting Hono routes are predictable.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { TenantPluginOptionsSchema } from "@suaveplan/api-plugin-tenant";
|
||||
|
||||
const parsed = TenantPluginOptionsSchema.parse({
|
||||
strategies: [{ type: "header", headerName: "x-tenant-id" }],
|
||||
});
|
||||
console.log(parsed.routePrefix); // "/tenants" (default)
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
TenantPluginOptionsSchema,
|
||||
TenantStrategySpecSchema,
|
||||
} from "@suaveplan/api-plugin-tenant";
|
||||
|
||||
const strategyResult = TenantStrategySpecSchema.safeParse({
|
||||
type: "cookie",
|
||||
cookieName: "tenant",
|
||||
});
|
||||
if (!strategyResult.success) {
|
||||
console.error(strategyResult.error.message);
|
||||
}
|
||||
|
||||
const optionsResult = TenantPluginOptionsSchema.safeParse({
|
||||
strategies: [],
|
||||
});
|
||||
console.assert(!optionsResult.success); // strategies cannot be empty
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `TenantStrategySpecSchema: z.ZodDiscriminatedUnion` — accepts any of
|
||||
the seven strategy specs.
|
||||
- `TenantPluginOptionsSchema: z.ZodObject` — accepts the full options
|
||||
object; `parse` throws `ZodError`, `safeParse` returns a discriminated
|
||||
result.
|
||||
- `type TenantPluginOptionsInput = z.input<typeof TenantPluginOptionsSchema>` —
|
||||
pre-default-application input shape.
|
||||
- `type TenantPluginOptionsResolved = z.output<typeof TenantPluginOptionsSchema>` —
|
||||
post-default-application output shape.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The `betterAuth`-style escape hatches present in
|
||||
`@suaveplan/api-plugin-auth`'s options schema are not needed here
|
||||
because the plugin owns its full surface. The `store`, `logger`, and
|
||||
`rateLimit.store` slots use `z.custom` rather than a full structural
|
||||
schema so the validator does not need to enumerate every method —
|
||||
duck-typing on the few methods callers will actually hit is enough.
|
||||
This keeps the schema small and the error messages targeted: if a
|
||||
caller passes a partial store missing `create`, the error names
|
||||
`getById/create/update/delete` and points to the call site.
|
||||
Reference in New Issue
Block a user