typion 0.0.0-stage → 0.1.1

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -2
  3. package/bin/typion.js +7 -0
  4. package/dist/auth/better-auth.d.ts +13 -0
  5. package/dist/auth/better-auth.js +11 -0
  6. package/dist/auth/better-auth.js.map +1 -0
  7. package/dist/cli/index.d.ts +14 -0
  8. package/dist/cli/index.js +883 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/column-kinds-Bkm4NJI2.js +47 -0
  11. package/dist/column-kinds-Bkm4NJI2.js.map +1 -0
  12. package/dist/context-B4e2eREP.d.ts +2100 -0
  13. package/dist/contract/index.d.ts +137 -0
  14. package/dist/contract/index.js +42 -0
  15. package/dist/contract/index.js.map +1 -0
  16. package/dist/db/pglite.d.ts +12 -0
  17. package/dist/db/pglite.js +27 -0
  18. package/dist/db/pglite.js.map +1 -0
  19. package/dist/descriptor-Cc3mGp73.js +12 -0
  20. package/dist/descriptor-Cc3mGp73.js.map +1 -0
  21. package/dist/errors-ChDBxeS-.js +17 -0
  22. package/dist/errors-ChDBxeS-.js.map +1 -0
  23. package/dist/errors-D-CKO-px.js +114 -0
  24. package/dist/errors-D-CKO-px.js.map +1 -0
  25. package/dist/handler-BWVU8TCR.d.ts +23 -0
  26. package/dist/handler-_87bFkbP.js +565 -0
  27. package/dist/handler-_87bFkbP.js.map +1 -0
  28. package/dist/hono/index.d.ts +17 -0
  29. package/dist/hono/index.js +26 -0
  30. package/dist/hono/index.js.map +1 -0
  31. package/dist/http/index.d.ts +13 -0
  32. package/dist/http/index.js +2 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +1324 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/issues-DLqCBQT1.js +42 -0
  37. package/dist/issues-DLqCBQT1.js.map +1 -0
  38. package/dist/next/index.d.ts +8 -0
  39. package/dist/next/index.js +18 -0
  40. package/dist/next/index.js.map +1 -0
  41. package/dist/operations-D3rOacLX.js +1811 -0
  42. package/dist/operations-D3rOacLX.js.map +1 -0
  43. package/dist/schema/index.d.ts +18 -0
  44. package/dist/schema/index.js +3 -0
  45. package/dist/schema-Rzzq97cK.js +68 -0
  46. package/dist/schema-Rzzq97cK.js.map +1 -0
  47. package/dist/seed/index.d.ts +19 -0
  48. package/dist/seed/index.js +85 -0
  49. package/dist/seed/index.js.map +1 -0
  50. package/dist/structural-BZnjFmCs.js +247 -0
  51. package/dist/structural-BZnjFmCs.js.map +1 -0
  52. package/dist/testing/index.d.ts +26 -0
  53. package/dist/testing/index.js +92 -0
  54. package/dist/testing/index.js.map +1 -0
  55. package/dist/typion-Dh2BCSRz.js +1187 -0
  56. package/dist/typion-Dh2BCSRz.js.map +1 -0
  57. package/dist/validation/zod.d.ts +21 -0
  58. package/dist/validation/zod.js +84 -0
  59. package/dist/validation/zod.js.map +1 -0
  60. package/docs/README.md +145 -0
  61. package/docs/access.md +114 -0
  62. package/docs/auth.md +195 -0
  63. package/docs/collections.md +172 -0
  64. package/docs/database.md +76 -0
  65. package/docs/features/localization.md +112 -0
  66. package/docs/features/multi-tenant.md +166 -0
  67. package/docs/features/soft-delete.md +85 -0
  68. package/docs/features/versions.md +106 -0
  69. package/docs/hooks.md +106 -0
  70. package/docs/http.md +188 -0
  71. package/docs/queries.md +200 -0
  72. package/docs/testing.md +85 -0
  73. package/package.json +125 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["COLUMN","columnOf","fail","fail"],"sources":["../src/define/collection.ts","../src/features/localization.ts","../src/define/kit.ts","../src/define/relations.ts","../src/define/engine.ts","../src/features/multi-tenant.ts","../src/features/soft-delete.ts","../src/features/versions/history.ts","../src/features/versions/table.ts","../src/features/versions/index.ts","../src/features/index.ts","../src/define/setup.ts","../src/define/config.ts","../src/db/adapter.ts"],"sourcesContent":["import {\n type AnyPgColumnBuilder,\n type PgTable,\n type PgTableExtraConfigValue,\n pgTable,\n} from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport { defaultIdColumn, timestamps } from '../schema/columns.js'\nimport type {\n AnyCollection,\n CollectionDraft,\n FoldKinds,\n NoUnknownKeys,\n RegisteredPlugins,\n RelationHelpers,\n RelationSpec,\n StructureInput,\n TableOf,\n} from '../types/collection.js'\nimport type { AnyPlugin } from '../types/plugin.js'\n\nconst relationHelpers: RelationHelpers<string> = {\n one: (target, config) =>\n ({\n kind: 'one',\n target,\n from: config.from,\n to: config.to,\n optional: config.optional ?? true,\n }) as never,\n many: (target, config) =>\n ({\n kind: 'many',\n target,\n from: config.from,\n to: config.to,\n through: config.through,\n writable: config.writable ?? false,\n }) as never,\n}\n\nexport type RawStructure = {\n columns: Record<string, AnyPgColumnBuilder>\n relations?: (r: RelationHelpers<string>) => Record<string, RelationSpec>\n dbName?: string\n timestamps?: boolean\n public?: boolean\n idColumn?: string\n fields?: Record<string, unknown>\n}\n\n// `columns` is inferred on its own so the `relations` callback can offer the column keys.\nexport function collection<\n const N extends string,\n const C extends Record<string, AnyPgColumnBuilder>,\n const S extends StructureInput<RegisteredPlugins, C, S>,\n>(\n name: N,\n structure: S & { columns: C } & NoUnknownKeys<S, StructureInput<RegisteredPlugins, C, S>>,\n): CollectionDraft<N, TableOf<N, S, FoldKinds<RegisteredPlugins, S, 'columns'>>, S>\n// `unknown`: comparing the overload's draft with a general one would walk the types of every rule.\nexport function collection(name: string, structure: RawStructure): unknown {\n const relations = structure.relations?.(relationHelpers) ?? {}\n const state: { table: PgTable | undefined } = { table: undefined }\n const make = (behaviour: Readonly<Record<string, unknown>>) => ({\n name,\n '~structure': structure,\n '~runtime': {\n structure: structure as unknown as Readonly<Record<string, unknown>>,\n relations,\n behaviour,\n state,\n },\n get table(): PgTable {\n if (state.table === undefined) {\n throw new ConfigError(`Collection '${name}' has no table until a config includes it`)\n }\n return state.table\n },\n })\n return Object.assign(make({}), {\n define: (behaviour: object) => make(behaviour as never),\n }) as never\n}\n\n// The columns of a collection are known only once the plugins are, so the table is built by the config.\nexport function buildCollectionTable(plugins: readonly AnyPlugin[], entry: AnyCollection): PgTable {\n const { state } = entry['~runtime']\n if (state.table !== undefined) return state.table\n const options = entry['~runtime'].structure\n const structure = options as unknown as RawStructure\n const columns: Record<string, AnyPgColumnBuilder> = {}\n if (!('id' in structure.columns) && structure.idColumn === undefined) {\n columns.id = defaultIdColumn()\n }\n Object.assign(columns, structure.columns)\n if (structure.timestamps !== false) Object.assign(columns, timestamps())\n for (const plugin of plugins) {\n for (const [key, column] of Object.entries(plugin.collection?.columns?.(options) ?? {})) {\n if (key in columns) {\n throw new ConfigError(\n `Collection '${entry.name}': plugin '${plugin.id}' adds column '${key}', which the collection already declares`,\n )\n }\n columns[key] = column\n }\n }\n const indexes = entry['~runtime'].behaviour.indexes as\n ((t: Record<string, unknown>) => PgTableExtraConfigValue[]) | undefined\n state.table = pgTable(structure.dbName ?? entry.name, columns, indexes as never)\n return state.table\n}\n\n// Rules, hooks and validation come from `define()`; everything the plugins own is mapped to the engine's\n// entity options, and what no plugin claims is passed through for the engine to validate.\nexport function collectionEntityOptions(\n plugins: readonly AnyPlugin[],\n entry: AnyCollection,\n): Record<string, unknown> {\n const { structure, behaviour } = entry['~runtime']\n const consumed = new Set<string>(['columns', 'relations', 'dbName', 'timestamps', 'public'])\n for (const plugin of plugins) {\n for (const key of plugin.collection?.consumes ?? []) consumed.add(key)\n }\n const { indexes: _table, ...entityBehaviour } = behaviour\n const access = { ...(behaviour.access as object | undefined) }\n const out: Record<string, unknown> = {\n ...entityBehaviour,\n access: structure.public === true ? { ...access, read: true } : access,\n }\n for (const [key, value] of Object.entries(structure)) {\n if (!consumed.has(key)) out[key] = value\n }\n const links = Object.entries(entry['~runtime'].relations)\n .filter(([, spec]) => spec.kind === 'many' && spec.writable === true)\n .map(([key]) => key)\n if (links.length > 0) out.links = links\n for (const plugin of plugins) Object.assign(out, plugin.collection?.entity?.(structure))\n return out\n}\n","import type { $Type, SQL } from 'drizzle-orm'\nimport { sql } from 'drizzle-orm'\nimport {\n type AnyPgColumn,\n type AnyPgColumnBuilder,\n type IndexBuilder,\n index,\n uniqueIndex,\n jsonb,\n type PgJsonbBuilder,\n pgTable,\n} from 'drizzle-orm/pg-core'\nimport { type DefinedPlugin, defineFeaturePlugin } from '../define/plugin.js'\nimport { BadRequestError, ConfigError } from '../errors.js'\nimport type {\n CollectionKinds,\n ColumnKindSpec,\n ContextInput,\n Dialect,\n EntityMeta,\n Kinded,\n ReadModeFn,\n RegisteredPlugins,\n SeedColumnsInput,\n WriteModeFn,\n} from '../types/index.js'\nimport { defineColumnKind } from '../schema/index.js'\n\n// The marker the engine finds localized columns by; it survives `pgTable()` and the versions clone. Its meta is\n// the column each locale's value is checked as.\nexport const localizedKind = defineColumnKind<'localized', { readonly value: AnyPgColumn }>(\n 'localized',\n)\n\n// One jsonb object per column (`{ it: …, en: … }`), branded with what the engine needs to type reads and\n// writes. The default locale is required in the storage and insert type, so a resolved read of a notNull\n// column is honestly `T`: the fallback chain always ends on a value.\nexport type Localized<T, L extends string, D extends L> = { [K in D]: T } & {\n [K in Exclude<L, D>]?: T\n} & Kinded<{\n readonly plugin: 'localization'\n readonly read: {\n readonly resolved: T\n readonly strict: T | null\n readonly all: Localized<T, L, D>\n }\n readonly write: { readonly value: T; readonly all: Localized<T, L, D> }\n }>\n\nexport type LocaleReadMode = 'resolved' | 'strict' | 'all'\n\ntype StrictOf<C> = C extends { fallback: infer F }\n ? F extends false\n ? 'strict'\n : 'resolved'\n : 'resolved'\n\n// `locale: 'all'` returns the stored object, `fallback: false` gives `T | null`, anything else `T`. Read\n// with `infer` rather than `C['locale']` (an absent key would resolve to the constraint), and distributed\n// over the literal, so `locale: 'it' | 'all'` yields both shapes.\nexport interface LocalizationReadMode extends ReadModeFn {\n readonly mode: this['config'] extends { locale: infer L }\n ? L extends 'all'\n ? 'all'\n : StrictOf<this['config']>\n : StrictOf<this['config']>\n}\n\n// Writes take a plain value in the locale of the call, or `locale: 'all'` and the whole object.\nexport interface LocalizationWriteMode extends WriteModeFn {\n readonly mode: this['config'] extends { locale: infer L }\n ? L extends 'all'\n ? 'all'\n : 'value'\n : 'value'\n}\n\n// The locale a write goes to, or every locale at once.\ntype WriteState = { readonly locale: string } | 'all'\n\ntype LocaleState = {\n readonly mode: LocaleReadMode\n // Filters and ordering always target a concrete locale, even when the result is the raw object.\n readonly chain: readonly string[]\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => sameValue(item, b[i]))\n }\n if (isPlainObject(a) && isPlainObject(b)) {\n const keys = Object.keys(a)\n return keys.length === Object.keys(b).length && keys.every((k) => sameValue(a[k], b[k]))\n }\n return false\n}\n\n// `->>` yields text; comparing with a non-string needs the matching cast or Postgres compares as text.\nfunction castFor(sample: unknown): string | null {\n if (typeof sample === 'number' || typeof sample === 'bigint') return 'numeric'\n if (typeof sample === 'boolean') return 'boolean'\n if (sample instanceof Date) return 'timestamptz'\n return null\n}\n\nfunction localeExpr(\n dialect: Dialect,\n column: AnyPgColumn | SQL,\n chain: readonly string[],\n cast: string | null,\n): SQL {\n const parts = chain.map((locale) => dialect.jsonText(column, locale))\n const expr = parts.length === 1 ? (parts[0] as SQL) : sql`coalesce(${sql.join(parts, sql`, `)})`\n return cast === null ? expr : dialect.cast(expr, cast)\n}\n\nfunction assertLocales(locales: readonly string[], defaultLocale: string): void {\n if (locales.length === 0) throw new ConfigError('localization: locales must not be empty')\n if (new Set(locales).size !== locales.length) {\n throw new ConfigError('localization: locales must be unique')\n }\n if (!locales.includes(defaultLocale)) {\n throw new ConfigError(`localization: defaultLocale '${defaultLocale}' is not in locales`)\n }\n}\n\nexport type LocalizationOptions<L extends readonly [string, ...string[]], D extends L[number]> = {\n locales: L\n defaultLocale: D\n // Reads fall back to the default locale when the requested one has no value; default true.\n fallback?: boolean\n // Decides the locale of a call from its request or headers (a cookie, a path prefix). Without it, or\n // when it returns nothing, the `x-locale` header is read, then the default locale applies.\n locale?: (input: ContextInput) => string | undefined\n}\n\nexport type LocalizationColumnKinds<L extends readonly [string, ...string[]]> = {\n readMode: LocalizationReadMode\n filterMode: 'resolved'\n writeMode: LocalizationWriteMode\n readOptions: { locale?: L[number] | 'all' | undefined; fallback?: boolean | undefined }\n writeOptions: { locale?: L[number] | 'all' }\n}\n\n// Each feature's plugin type is named, never reached as `ReturnType<typeof localization<L, D>>`: that instantiation\n// expression cost the stress fixture 21,000 instantiations (ADR-077).\nexport interface LocalizationPlugin<\n L extends readonly [string, ...string[]],\n D extends L[number],\n> extends DefinedPlugin<\n 'localization',\n {},\n {},\n { locale: L[number] },\n {},\n {},\n {},\n {},\n {},\n CollectionKinds,\n {},\n {},\n {},\n LocalizationColumnKinds<L>,\n { locale?: L[number] },\n never,\n never\n> {\n readonly locales: L\n readonly defaultLocale: D\n}\n\nexport function localization<\n const L extends readonly [string, ...string[]],\n const D extends L[number],\n>(options: LocalizationOptions<L, D>): LocalizationPlugin<L, D> {\n const { locales, defaultLocale } = options\n assertLocales(locales, defaultLocale)\n const fallback = options.fallback ?? true\n\n const resolve = (locale: unknown): L[number] => {\n if (locale === undefined) return defaultLocale\n if (typeof locale !== 'string' || !locales.includes(locale)) {\n throw new BadRequestError(\n `Unknown locale '${String(locale)}' (expected one of ${locales.join(', ')})`,\n )\n }\n return locale\n }\n\n const stateOf = (ctxLocale: string, locale: unknown, strict: unknown): LocaleState => {\n const all = locale === 'all'\n const effective = all || locale === undefined ? ctxLocale : resolve(locale)\n const withFallback = strict !== false && fallback\n const chain = withFallback ? [...new Set([effective, defaultLocale])] : [effective]\n return { mode: all ? 'all' : withFallback ? 'resolved' : 'strict', chain }\n }\n\n const project = (value: unknown, state: LocaleState): unknown => {\n if (state.mode === 'all' || !isPlainObject(value)) return value\n for (const locale of state.chain) {\n const item = value[locale]\n if (item !== undefined && item !== null) return item\n }\n return null\n }\n\n const kind: ColumnKindSpec<LocaleState, WriteState> = {\n project: (values, state) => values.map((value) => project(value, state)),\n expression: ({ column, state, sample, dialect }) =>\n localeExpr(dialect, column, state.chain, castFor(sample)),\n // A plain value goes to one locale and is merged into the stored object under the row lock, so the\n // validator still sees every locale; a nullable column with no locale left holds null again.\n write: ({ value, stored, state }) => {\n if (state === 'all') return value\n const next = { ...(isPlainObject(stored) ? stored : {}), [state.locale]: value }\n return value === null && Object.values(next).every((item) => item === null) ? null : next\n },\n // Only the default locale of a NOT NULL column must hold a value: the fallback chain ends there. A\n // locale-scoped update merges into the stored object, so update mode never demands it.\n validation: (column, mode) => ({\n type: 'keyed',\n keyName: 'locale',\n keys: locales,\n required: column.notNull && mode !== 'update' ? [defaultLocale] : [],\n nonNull: column.notNull ? [defaultLocale] : [],\n value: localizedKind.metaOf(column.column)?.value,\n }),\n diff: (before, after) => {\n if (!isPlainObject(before) || !isPlainObject(after)) return { before, after }\n const b: Record<string, unknown> = {}\n const a: Record<string, unknown> = {}\n for (const locale of new Set([...Object.keys(before), ...Object.keys(after)])) {\n if (sameValue(before[locale], after[locale])) continue\n b[locale] = before[locale] ?? null\n a[locale] = after[locale] ?? null\n }\n return { before: b, after: a }\n },\n }\n\n const plugin = defineFeaturePlugin({\n id: 'localization',\n columnKinds: {\n $types: {} as LocalizationColumnKinds<L>,\n readOptions: { locale: 'string', fallback: 'boolean' },\n writeOptions: { locale: 'string' },\n read: ({ options: given, ctx }) =>\n stateOf(ctx.locale as string, given.locale, given.fallback),\n write: ({ options: given, ctx }): WriteState =>\n given.locale === 'all' ? 'all' : { locale: resolve(given.locale ?? ctx.locale) },\n kinds: { localized: kind },\n },\n contextOptions: { $type: {} as { locale?: L[number] } },\n requestHeaders: ['x-locale'],\n context: (_base, input) => ({\n locale: resolve(\n input.options?.locale ??\n options.locale?.(input) ??\n input.headers?.get('x-locale') ??\n undefined,\n ),\n }),\n seed: {\n // Random text would break a read: the value of a localized column is an object keyed by locale. One\n // value per row, so a unique index per locale does not stop the seed.\n columns: (entity: EntityMeta, input: SeedColumnsInput) => {\n const columns: Record<string, unknown> = {}\n for (const key of entity.kindKeys) {\n if (entity.columns[key]?.kind !== localizedKind.id) continue\n const values = Array.from({ length: input.count }, (_, i) => ({\n [defaultLocale]: `${entity.name} ${key} ${i + 1}`,\n }))\n // In one weighted group: drizzle-seed reads a bare object in `values` as a group of its own.\n columns[key] = input.generators.valuesFromArray({\n values: [{ weight: 1, values }],\n isUnique: true,\n })\n }\n return columns\n },\n },\n })\n\n // `locales` and `defaultLocale` sit on the plugin because an application reads them: a language switcher,\n // the locale a form writes.\n return Object.assign(plugin, { locales, defaultLocale })\n}\n\ntype RegisteredLocalization = Extract<RegisteredPlugins[number], { readonly id: 'localization' }>\n\ntype LocalesOf<P> = P extends {\n readonly locales: readonly (infer L extends string)[]\n readonly defaultLocale: infer D extends string\n}\n ? { locale: L; default: D }\n : { locale: string; default: string }\n\n// Without localization in the setup, a localized column has no locales to be typed in.\ntype LocalizationConfigured = [RegisteredLocalization] extends [never]\n ? { readonly '~error': 'localized() needs defineSetup({ localization })' }\n : unknown\n\ntype RegisteredLocale = LocalesOf<RegisteredLocalization>['locale']\ntype RegisteredDefault = LocalesOf<RegisteredLocalization>['default'] & RegisteredLocale\n\n// What the builder's column holds; `$type<T>()` puts T beside the data type rather than over it.\ntype BuilderData<B extends AnyPgColumnBuilder> = B['_'] extends { $type: infer T }\n ? T\n : B['_']['data']\n\n// Each locale's value lives in a jsonb object, so it must come back from JSON as it went in: a date or a\n// bigint would come back a string.\ntype JsonSafe<B extends AnyPgColumnBuilder> =\n BuilderData<B> extends Date | bigint | Uint8Array\n ? {\n readonly '~error': 'a localized value is stored as JSON: use text, numbers, booleans, enums or json'\n }\n : unknown\n\nfunction isJsonSafe(dataType: string): boolean {\n return (\n dataType.startsWith('string') ||\n dataType.startsWith('number') ||\n dataType === 'boolean' ||\n dataType === 'object json'\n )\n}\n\n// A localized column for a collection: one jsonb object per row, typed with the builder's own type in the\n// locales of the registered plugin, and each locale's value checked as that builder's column would be.\nexport function localized<B extends AnyPgColumnBuilder>(\n builder: B & JsonSafe<B> & LocalizationConfigured,\n): $Type<PgJsonbBuilder, Localized<BuilderData<B>, RegisteredLocale, RegisteredDefault>> {\n const name = (builder as unknown as { config: { name: string } }).config.name\n const value = pgTable('localized', { value: builder as AnyPgColumnBuilder }).value\n if (!isJsonSafe(value.dataType)) {\n throw new ConfigError(\n `localized(): a ${value.dataType} value would not survive JSON; use text, numbers, booleans, enums or json`,\n )\n }\n const column = name === '' ? jsonb() : jsonb(name)\n return localizedKind.mark(column.$type(), { value }) as never\n}\n\n// One locale's value as SQL, for an index of your own: `uniqueIndex('pages_path').on(t.tenantId,\n// localizedValue(t.path, 'it'))`.\nexport function localizedValue(column: AnyPgColumn, locale: RegisteredLocale): SQL {\n return sql`(${column}->>${sql.raw(`'${(locale as string).replace(/'/g, \"''\")}'`)})`\n}\n\n// A btree on the extracted text is what `coalesce(col->>'loc', …)` filters and ordering can use; one index\n// per locale, named by the caller, in the collection's `define({ indexes })`.\nexport function localizedIndex(\n name: string,\n column: AnyPgColumn,\n locale: RegisteredLocale,\n): IndexBuilder {\n return index(name).on(localizedValue(column, locale))\n}\n\n// Unique within one locale (a slug per language); `.where(…)` narrows it further, to the rows not deleted.\nexport function localizedUnique(\n name: string,\n column: AnyPgColumn,\n locale: RegisteredLocale,\n): IndexBuilder {\n return uniqueIndex(name).on(localizedValue(column, locale))\n}\n","import { is } from 'drizzle-orm'\nimport {\n getTableConfig,\n isPgEnum,\n isPgSchema,\n type PgEnum,\n type PgSchema,\n PgTable,\n pgSchema,\n} from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\n\nexport type KitEntry = PgTable | PgEnum<any> | PgSchema<string>\nexport type KitSchema = Readonly<Record<string, KitEntry>>\n\nexport type KitSchemaInput = {\n readonly tables: Readonly<Record<string, PgTable | PgEnum<any>>>\n readonly pgSchema: PgSchema<string>\n readonly generated: Readonly<Record<string, PgTable>>\n readonly pluginTables: Readonly<Record<string, PgTable>>\n}\n\nexport function isKitEntry(value: unknown): value is KitEntry {\n return is(value, PgTable) || isPgEnum(value) || isPgSchema(value)\n}\n\n// pushSchema/generateDrizzleJson classify `Object.values(imports)`: nested objects are ignored and a\n// table in a pg schema only gets its `CREATE SCHEMA` when the PgSchema object itself is present, so the\n// record is flat and carries one PgSchema per schema name referenced by any table or enum.\nexport function buildKitSchema(input: KitSchemaInput): KitSchema {\n const out: Record<string, KitEntry> = {}\n const owners = new Map<string, string>()\n const add = (group: string, entries: Readonly<Record<string, KitEntry>>) => {\n for (const [key, value] of Object.entries(entries)) {\n const owner = owners.get(key)\n if (owner !== undefined) {\n throw new ConfigError(`Schema key '${key}' is used by both ${owner} and ${group}`)\n }\n owners.set(key, group)\n out[key] = value\n }\n }\n add('tables', input.tables)\n add('generated', input.generated)\n add('plugins', input.pluginTables)\n\n const schemas = new Map<string, PgSchema<string>>()\n schemas.set(input.pgSchema.schemaName, input.pgSchema)\n for (const value of Object.values(out)) {\n const name = is(value, PgTable)\n ? getTableConfig(value).schema\n : isPgEnum(value)\n ? value.schema\n : undefined\n if (name !== undefined && name !== 'public' && !schemas.has(name)) {\n schemas.set(name, pgSchema(name))\n }\n }\n for (const [name, schema] of schemas) {\n if (owners.has(name)) {\n throw new ConfigError(`Schema key '${name}' collides with the pg schema of the same name`)\n }\n out[name] = schema\n }\n return out\n}\n\nexport type GeneratedTables = Readonly<Record<string, PgTable>> & {\n readonly $names: readonly string[]\n}\n\nexport function buildGenerated(\n derived: Readonly<Record<string, PgTable>>,\n pluginTables: Readonly<Record<string, PgTable>>,\n): GeneratedTables {\n // Plugin tables are static exports of their own subpath; only the tables the plugins derive per entity need\n // the `export const { … } = def.generated` line, so `$names` lists those alone.\n return {\n ...pluginTables,\n ...derived,\n $names: Object.keys(derived),\n } as unknown as GeneratedTables\n}\n","import {\n type AnyRelations,\n type AnyRelationsBuilderConfig,\n buildRelations,\n createRelationsHelper,\n getTableColumns,\n is,\n type Relation,\n type RelationsBuilderColumn,\n type RelationsBuilderJunctionColumn,\n type RelationsRecord,\n} from 'drizzle-orm'\nimport { PgTable } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\n\nexport type RelationFragment = {\n readonly owner: string\n readonly config: AnyRelationsBuilderConfig\n}\n\n// Drizzle's helper is typed per schema; the engine drives it with string keys, so a loose view of the\n// same object is used internally and the precise type is re-asserted by the definition step.\ntype BuilderColumn = RelationsBuilderColumn<string> | RelationsBuilderJunctionColumn<string>\ntype BuilderTable = Record<string, RelationsBuilderColumn<string>>\ntype RelationFn = (config: Record<string, unknown>) => Relation\nexport type LooseHelper = Record<string, BuilderTable> & {\n one: Record<string, RelationFn>\n many: Record<string, RelationFn>\n}\n\nexport function mergeRelationConfigs(\n fragments: readonly RelationFragment[],\n): AnyRelationsBuilderConfig {\n const merged: Record<string, Record<string, unknown>> = {}\n const owners = new Map<string, string>()\n for (const { owner, config } of fragments) {\n for (const [table, record] of Object.entries(config)) {\n if (record === undefined) continue\n const target = merged[table] ?? {}\n merged[table] = target\n for (const [key, relation] of Object.entries(record)) {\n const id = `${table}.${key}`\n const previous = owners.get(id)\n if (previous !== undefined) {\n throw new ConfigError(\n `Relation '${id}' is declared twice (by ${previous} and by ${owner})`,\n )\n }\n owners.set(id, owner)\n target[key] = relation\n }\n }\n }\n return merged as AnyRelationsBuilderConfig\n}\n\nfunction wrapDrizzleError(error: unknown): never {\n if (error instanceof ConfigError) throw error\n const message = error instanceof Error ? error.message : String(error)\n throw new ConfigError(message, 'config', { cause: error })\n}\n\nexport function resolveRelations(\n tables: Readonly<Record<string, PgTable>>,\n build: (r: LooseHelper) => readonly RelationFragment[],\n): AnyRelations {\n const helper = createRelationsHelper(tables) as unknown as LooseHelper\n try {\n return buildRelations(tables, mergeRelationConfigs(build(helper)))\n } catch (error) {\n wrapDrizzleError(error)\n }\n}\n\nexport function tablesOnly(schema: Readonly<Record<string, unknown>>): Record<string, PgTable> {\n const out: Record<string, PgTable> = {}\n for (const [key, value] of Object.entries(schema)) if (is(value, PgTable)) out[key] = value\n return out\n}\n\nfunction columnKey(table: PgTable, column: unknown, context: string): string {\n for (const [key, candidate] of Object.entries(getTableColumns(table))) {\n if (candidate === column) return key\n }\n throw new ConfigError(`${context}: relation column does not belong to its table`)\n}\n\nfunction single<T>(items: T[]): T | T[] {\n return items.length === 1 ? (items[0] as T) : items\n}\n\n// Rebuilds every relation of `source` with a table derived from it as the new source: explicit from/to\n// (reversed relations were resolved in the first pass, so no reverse lookup can be ambiguous),\n// junction columns re-pointed through the fresh helper, alias/where/optional carried verbatim.\nexport function mirrorRelations(\n r: LooseHelper,\n resolved: AnyRelations,\n source: string,\n mirror: string,\n): RelationsRecord {\n const config = resolved[source]\n if (config === undefined) throw new ConfigError(`No relations entry for '${source}'`)\n const out: Record<string, Relation> = {}\n const mirrorTable = r[mirror]\n if (mirrorTable === undefined) throw new ConfigError(`No table '${mirror}' in the merged schema`)\n for (const [key, rel] of Object.entries(config.relations)) {\n const context = `relations -> ${mirror}.${key}`\n const target = rel.targetTableName\n const targetTable = r[target]\n if (targetTable === undefined) throw new ConfigError(`${context}: unknown target '${target}'`)\n const sourceTable = rel.sourceTable as PgTable\n const targetPg = rel.targetTable as PgTable\n let from: BuilderColumn[] = rel.sourceColumns.map((c) => {\n const column = mirrorTable[columnKey(sourceTable, c, context)]\n if (column === undefined)\n throw new ConfigError(`${context}: the derived table lacks a column`)\n return column\n })\n let to: BuilderColumn[] = rel.targetColumns.map((c) => {\n const column = targetTable[columnKey(targetPg, c, context)]\n if (column === undefined) throw new ConfigError(`${context}: target lacks a column`)\n return column\n })\n const through = rel.through\n if (through !== undefined) {\n const junction = (cfg: { tableName: string; key: string }) => {\n const column = r[cfg.tableName]?.[cfg.key]\n if (column === undefined) {\n throw new ConfigError(\n `${context}: junction column '${cfg.tableName}.${cfg.key}' not found`,\n )\n }\n return column\n }\n from = from.map((c, i) => {\n const via = through.source[i]\n if (via === undefined) throw new ConfigError(`${context}: junction columns mismatch`)\n return (c as RelationsBuilderColumn<string>).through(junction(via._))\n })\n to = to.map((c, i) => {\n const via = through.target[i]\n if (via === undefined) throw new ConfigError(`${context}: junction columns mismatch`)\n return (c as RelationsBuilderColumn<string>).through(junction(via._))\n })\n }\n const cfg: Record<string, unknown> = { from: single(from), to: single(to) }\n if (rel.alias !== undefined) cfg.alias = rel.alias\n if (rel.where !== undefined) cfg.where = rel.where\n if (rel.relationType === 'one') {\n cfg.optional = (rel as { optional?: boolean }).optional ?? true\n const one = r.one[target]\n if (one === undefined) throw new ConfigError(`${context}: unknown target '${target}'`)\n out[key] = one(cfg)\n } else {\n const many = r.many[target]\n if (many === undefined) throw new ConfigError(`${context}: unknown target '${target}'`)\n out[key] = many(cfg)\n }\n }\n return out\n}\n","import type {\n AnyRelations,\n ExtractTablesFromSchema,\n ExtractTablesWithRelations,\n RelationsBuilder,\n RelationsBuilderConfig,\n} from 'drizzle-orm'\nimport { is } from 'drizzle-orm'\nimport { isPgEnum, type PgEnum, type PgSchema, PgTable } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport { typion } from '../schema/pg-schema.js'\nimport type { FullCtx } from '../types/context.js'\nimport type { AnyEntities, EntitiesOf, EntityDef, EntityOptions } from '../types/entity.js'\nimport type { TypionDefinition, EntityMeta } from '../types/meta.js'\nimport type {\n AnyPlugin,\n DependenciesError,\n MergeAll,\n MergeConfigs,\n PluginEntities,\n PluginRuntime,\n PluginTables,\n RequirementsError,\n} from '../types/plugin.js'\nimport type { ValidationAdapter } from '../types/runtime.js'\nimport { buildEntityMeta, defineEntity } from './entity.js'\nimport { buildGenerated, buildKitSchema } from './kit.js'\nimport { resolvePlugins } from './plugin.js'\nimport {\n type LooseHelper,\n mirrorRelations,\n type RelationFragment,\n resolveRelations,\n tablesOnly,\n} from './relations.js'\n\nexport type EngineOptions = {\n schema?: PgSchema<string>\n validation?: ValidationAdapter\n maxLimit?: number\n}\n\nexport type UserTables = Record<string, PgTable | PgEnum<any>>\n\nexport type AllTables<\n T extends UserTables,\n P extends readonly AnyPlugin[],\n> = ExtractTablesFromSchema<T & PluginTables<P>>\n\n// Without plugins the user's config is used as is, so relation records stay the exact literal types\n// (the merge helpers would otherwise wrap each record in `{} & …`).\nexport type MergedRelations<\n C,\n P extends readonly AnyPlugin[],\n T extends UserTables,\n> = ExtractTablesWithRelations<\n [P[number]] extends [never] ? C & {} : MergeConfigs<MergeAll<P>, C>,\n AllTables<T, P>\n>\n\nexport type BlueprintTypes<\n TCtx extends object,\n R extends AnyRelations,\n P extends readonly AnyPlugin[],\n> = {\n ctx: TCtx\n relations: R\n plugins: P\n}\n\nexport type DefinitionTypes<\n TCtx extends object,\n T extends UserTables,\n P extends readonly AnyPlugin[],\n R extends AnyRelations,\n E extends AnyEntities,\n> = {\n ctx: TCtx\n tables: T\n plugins: P\n entities: E & PluginEntities<P>\n relations: R\n}\n\nexport interface Blueprint<\n TCtx extends object,\n T extends UserTables,\n P extends readonly AnyPlugin[],\n R extends AnyRelations,\n> {\n readonly $types: BlueprintTypes<TCtx, R, P>\n entity<N extends keyof R & string, const O extends EntityOptions<R, N, FullCtx<TCtx, P>, P>>(\n name: N,\n options?: O,\n ): EntityDef<N, O>\n entities<const E extends EntitiesOf<R> & AnyEntities>(\n entities: E,\n ): TypionDefinition<DefinitionTypes<TCtx, T, P, R, E>>\n}\n\nexport interface PluginsStep<\n TCtx extends object,\n T extends UserTables,\n P extends readonly AnyPlugin[],\n> {\n plugins<const P2 extends readonly AnyPlugin[]>(\n plugins: P2 & RequirementsError<T, P2> & DependenciesError<P2>,\n ): PluginsStep<TCtx, T, P2>\n relations<C extends RelationsBuilderConfig<AllTables<T, P>>>(\n cb: (r: RelationsBuilder<AllTables<T, P>>) => C,\n ): Blueprint<TCtx, T, P, MergedRelations<C, P, T>>\n}\n\nexport interface TablesStep<TCtx extends object> {\n tables<T extends UserTables>(tables: T): PluginsStep<TCtx, T, []>\n}\n\nconst RESERVED_ENTITY_NAMES = new Set(['_rpc', '_plugins', 'entity'])\nconst DEFAULT_MAX_LIMIT = 100\n\ntype Settings = {\n readonly pgSchema: PgSchema<string>\n readonly validation: ValidationAdapter | null\n readonly maxLimit: number\n}\n\ntype RelationsCallback = (r: LooseHelper) => Record<string, unknown>\n\ntype BlueprintState = Settings & {\n readonly tables: UserTables\n readonly plugins: readonly PluginRuntime[]\n readonly userRelations: RelationsCallback\n readonly resolved: AnyRelations\n}\n\nfunction pluginTablesOf(plugins: readonly PluginRuntime[]): Record<string, PgTable> {\n const out: Record<string, PgTable> = {}\n for (const plugin of plugins) Object.assign(out, plugin.tables)\n return out\n}\n\nfunction fragmentsOf(\n r: LooseHelper,\n userRelations: RelationsCallback,\n plugins: readonly PluginRuntime[],\n): RelationFragment[] {\n const fragments: RelationFragment[] = []\n for (const plugin of plugins) {\n const build = plugin.spec.relations\n if (build !== undefined) {\n fragments.push({ owner: `plugin '${plugin.id}'`, config: build(r as never) })\n }\n }\n fragments.push({ owner: 'the engine relations', config: userRelations(r) as never })\n return fragments\n}\n\nfunction assertEntityName(\n name: string,\n def: EntityDef<string, unknown>,\n relations: AnyRelations,\n plugins: readonly PluginRuntime[],\n) {\n if (def.name !== name) {\n throw new ConfigError(`Entity registered as '${name}' is defined as '${def.name}'`, 'config', {\n entity: name,\n })\n }\n if (RESERVED_ENTITY_NAMES.has(name) || name.startsWith('$')) {\n throw new ConfigError(`Entity name '${name}' is reserved`, 'config', { entity: name })\n }\n if (plugins.some((p) => p.id === name)) {\n throw new ConfigError(\n `Entity name '${name}' collides with the plugin of the same id`,\n 'config',\n {\n entity: name,\n },\n )\n }\n if (!(name in relations)) {\n throw new ConfigError(`Entity '${name}' does not name a table of the engine`, 'config', {\n entity: name,\n })\n }\n}\n\ntype Derived = {\n readonly tables: Record<string, PgTable>\n // Derived table key → the entity whose relations it mirrors, and the plugin that derived it.\n readonly mirrors: Map<string, { entity: string; plugin: string }>\n // Entity → plugin id → the tables that plugin derived for it.\n readonly byEntity: Map<string, Map<string, Record<string, PgTable>>>\n}\n\n// The tables the plugins derive from the entities' (a history), before the relations are built: a derived table\n// may mirror its entity's relations, and every one of them reaches drizzle-kit.\nfunction deriveTables(\n state: BlueprintState,\n entities: readonly { def: EntityDef<string, unknown> }[],\n taken: Readonly<Record<string, PgTable>>,\n): Derived {\n const out: Derived = { tables: {}, mirrors: new Map(), byEntity: new Map() }\n const names = new Set(entities.map(({ def }) => def.name))\n for (const { def } of entities) {\n const options = typeof def.options === 'object' && def.options !== null ? def.options : {}\n const table = state.resolved[def.name]?.table as PgTable\n for (const plugin of state.plugins) {\n const derive = plugin.traits?.derive\n if (derive === undefined) continue\n const tables = derive({\n entity: def.name,\n table,\n options: options as Readonly<Record<string, unknown>>,\n schema: state.pgSchema,\n })\n if (tables === null) continue\n const own: Record<string, PgTable> = {}\n for (const [key, entry] of Object.entries(tables)) {\n if (!is(entry.table, PgTable)) {\n throw new ConfigError(\n `Plugin '${plugin.id}' derives '${key}' for entity '${def.name}', which is not a pg table`,\n 'config',\n { entity: def.name },\n )\n }\n if (key in taken || key in out.tables || names.has(key)) {\n throw new ConfigError(\n `Plugin '${plugin.id}' derives a table '${key}' for entity '${def.name}', and the key is taken`,\n 'config',\n { entity: def.name },\n )\n }\n out.tables[key] = entry.table\n own[key] = entry.table\n if (entry.mirror === true) out.mirrors.set(key, { entity: def.name, plugin: plugin.id })\n }\n let byPlugin = out.byEntity.get(def.name)\n if (byPlugin === undefined) {\n byPlugin = new Map()\n out.byEntity.set(def.name, byPlugin)\n }\n byPlugin.set(plugin.id, own)\n }\n }\n return out\n}\n\nfunction buildDefinition(\n state: BlueprintState,\n userEntities: Readonly<Record<string, EntityDef<string, unknown>>>,\n): TypionDefinition<any> {\n const entities: { def: EntityDef<string, unknown>; owner: EntityMeta['owner'] }[] = []\n const names = new Set<string>()\n for (const [name, def] of Object.entries(userEntities)) {\n assertEntityName(name, def, state.resolved, state.plugins)\n names.add(name)\n entities.push({ def, owner: 'user' })\n }\n for (const plugin of state.plugins) {\n for (const [name, def] of Object.entries(plugin.entities)) {\n if (names.has(name)) {\n throw new ConfigError(\n `Entity '${name}' is defined both by the engine and by plugin '${plugin.id}'`,\n 'config',\n { entity: name },\n )\n }\n assertEntityName(name, def, state.resolved, state.plugins)\n names.add(name)\n entities.push({ def, owner: { plugin: plugin.id } })\n }\n }\n\n const pluginTables = pluginTablesOf(state.plugins)\n const userTables = tablesOnly(state.tables)\n const derived = deriveTables(state, entities, { ...userTables, ...pluginTables })\n\n const allTables = { ...userTables, ...pluginTables, ...derived.tables }\n const relations = resolveRelations(allTables, (r) => {\n const fragments = fragmentsOf(r, state.userRelations, state.plugins)\n for (const [key, { entity, plugin }] of derived.mirrors) {\n fragments.push({\n owner: `plugin '${plugin}'`,\n config: { [key]: mirrorRelations(r, state.resolved, entity, key) } as never,\n })\n }\n return fragments\n })\n\n const meta: Record<string, EntityMeta> = {}\n for (const { def, owner } of entities) {\n meta[def.name] = buildEntityMeta({\n name: def.name,\n options: def.options,\n table: relations[def.name]?.table as PgTable,\n relations,\n plugins: state.plugins,\n derived: derived.byEntity.get(def.name) ?? new Map(),\n maxLimit: state.maxLimit,\n owner,\n })\n }\n\n return {\n $types: undefined as never,\n relations,\n schema: buildKitSchema({\n tables: state.tables,\n pgSchema: state.pgSchema,\n generated: derived.tables,\n pluginTables,\n }),\n generated: buildGenerated(derived.tables, pluginTables) as never,\n entities: meta,\n plugins: state.plugins,\n pgSchema: state.pgSchema,\n maxLimit: state.maxLimit,\n validation: state.validation,\n }\n}\n\n// The runtime chain is untyped internally: instantiating the public step types over `any` makes\n// TypeScript walk drizzle's builder types and give up (TS2590); the single cast is in defineEngine.\ntype RuntimeBlueprint = {\n $types: never\n entity: typeof defineEntity\n entities: (\n entities: Readonly<Record<string, EntityDef<string, unknown>>>,\n ) => TypionDefinition<any>\n}\ntype RuntimePluginsStep = {\n plugins: (plugins: readonly AnyPlugin[]) => RuntimePluginsStep\n relations: (cb: RelationsCallback) => RuntimeBlueprint\n}\ntype RuntimeTablesStep = { tables: (tables: UserTables) => RuntimePluginsStep }\n\nfunction blueprintOf(state: BlueprintState): RuntimeBlueprint {\n return {\n $types: undefined as never,\n entity: defineEntity,\n entities: (userEntities) => buildDefinition(state, userEntities),\n }\n}\n\nfunction pluginsStepOf(\n settings: Settings,\n tables: UserTables,\n pluginDefs: readonly AnyPlugin[],\n): RuntimePluginsStep {\n const plugins = resolvePlugins(pluginDefs, tables)\n return {\n plugins: (next) => pluginsStepOf(settings, tables, next),\n relations: (userRelations) => {\n const resolved = resolveRelations(\n { ...tablesOnly(tables), ...pluginTablesOf(plugins) },\n (r) => fragmentsOf(r, userRelations, plugins),\n )\n return blueprintOf({ ...settings, tables, plugins, userRelations, resolved })\n },\n }\n}\n\nfunction tablesStepOf(settings: Settings): RuntimeTablesStep {\n return {\n tables: (tables) => {\n for (const [key, value] of Object.entries(tables)) {\n if (!is(value, PgTable) && !isPgEnum(value)) {\n throw new ConfigError(`tables.${key} is neither a pg table nor a pg enum`)\n }\n }\n return pluginsStepOf(settings, tables, [])\n },\n }\n}\n\nexport function defineEngine<TCtx extends object>(options: EngineOptions = {}): TablesStep<TCtx> {\n const maxLimit = options.maxLimit ?? DEFAULT_MAX_LIMIT\n if (!Number.isInteger(maxLimit) || maxLimit < 1) {\n throw new ConfigError('defineEngine: maxLimit must be a positive integer')\n }\n const step: RuntimeTablesStep = tablesStepOf({\n pgSchema: options.schema ?? typion,\n validation: options.validation ?? null,\n maxLimit,\n })\n return step as unknown as TablesStep<TCtx>\n}\n","import type {\n AnyPgColumnBuilder,\n PgIntegerBuilder,\n PgTextBuilder,\n PgUUIDBuilder,\n SetNotNull,\n} from 'drizzle-orm/pg-core'\nimport { type DefinedPlugin, defineFeaturePlugin } from '../define/plugin.js'\nimport { BadRequestError, ConfigError, ForbiddenError } from '../errors.js'\nimport type { CollectionKinds, EntityMeta } from '../types/index.js'\nimport type { EntityTraits } from '../types/traits.js'\n\nconst COLUMN = 'tenantId'\n\n// What a tenant id is: the data type of the column the plugin is given.\nexport type TenantIdOf<B> = B extends { readonly _: { readonly $type: infer T } }\n ? T\n : B extends { readonly _: { readonly data: infer T } }\n ? T\n : unknown\n\n// The tenant columns most applications use, as interfaces. The plugin's type carries the column's builder, and\n// TypeScript walks a builder wherever the plugins are, since Drizzle's builders count as generic: a uuid column\n// cost 13,500 instantiations and 33 more per read on the stress fixture, and as an interface it costs none\n// (ADR-074). Any other column works the same, at that cost.\ntype UuidBuilder = SetNotNull<PgUUIDBuilder>\ntype TextBuilder = SetNotNull<PgTextBuilder<[string, ...string[]]>>\ntype IntegerBuilder = SetNotNull<PgIntegerBuilder>\nexport interface UuidTenantColumn extends UuidBuilder {}\nexport interface TextTenantColumn extends TextBuilder {}\nexport interface IntegerTenantColumn extends IntegerBuilder {}\n\ntype Same<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false\n\nexport type TenantColumnOf<B> =\n Same<B, UuidBuilder> extends true\n ? UuidTenantColumn\n : Same<B, TextBuilder> extends true\n ? TextTenantColumn\n : Same<B, IntegerBuilder> extends true\n ? IntegerTenantColumn\n : B\n\n// What the application's context must carry: the caller's tenant, null when there is none.\nexport type TenantContext<T = string> = { tenantId: T | null }\n\nexport type MultiTenantCollectionOptions = { tenant?: boolean }\n\nexport interface MultiTenantKinds<B> extends CollectionKinds {\n readonly columns: this['options'] extends { tenant: true } ? { tenantId: B } : {}\n readonly entity: this['options'] extends { tenant: true } ? { tenant: true } : {}\n}\n\n// What a collection with `tenant: true` passes to its entity.\nexport type MultiTenantEntityOptions = { tenant?: true }\n\n// `$system({ reason, unscoped: true })` reads and writes every tenant's rows.\nexport type MultiTenantSystemOptions = { unscoped?: boolean }\n\n// What the plugin adds to the context: whether the call crosses tenants, which only a system call can.\nexport type MultiTenantContext = { readonly unscoped: boolean }\n\ntype Enabled = { tenant: true }\n\nexport interface MultiTenantTraits extends EntityTraits {\n readonly entityOptions: MultiTenantEntityOptions\n readonly governs: Enabled\n readonly managed: this['given'] extends Enabled ? typeof COLUMN : never\n}\n\ntype MultiTenantState = { readonly column: string }\n\nfunction columnOf(state: unknown): string {\n return (state as MultiTenantState).column\n}\n\nfunction fail(entity: string, message: string): never {\n throw new ConfigError(`Entity '${entity}': ${message}`, 'config', { entity })\n}\n\n// The tenant column of an entity, or null where the plugin does not act.\nexport function tenantColumn(entity: EntityMeta): string | null {\n const trait = entity.traits.multiTenant\n return trait === undefined ? null : columnOf(trait.state)\n}\n\n// Collections that opt in get the tenant column, and every read and write stays in the tenant of the context,\n// system mode included: only `$system({ unscoped: true })` crosses tenants.\nexport type MultiTenantOptions<B extends AnyPgColumnBuilder> = {\n column: () => B\n // Which tenant generated rows belong to; `defineConfig({ seed: { values: { tenant } } })` overrides it.\n seedTenant?: TenantIdOf<B>\n}\n\n// Over the column as `TenantColumnOf` names it and the tenant id, never over the builder: a generic alias here is a\n// reference TypeScript keeps with its arguments, and a builder among them cost the stress fixture 13,500\n// instantiations and 34 more per read (ADR-077).\nexport interface MultiTenantPlugin<C, T> extends DefinedPlugin<\n 'multiTenant',\n {},\n {},\n MultiTenantContext,\n {},\n {},\n {},\n {},\n {},\n MultiTenantKinds<C>,\n MultiTenantCollectionOptions,\n MultiTenantSystemOptions,\n TenantContext<T>,\n never,\n {},\n MultiTenantTraits,\n never\n> {}\n\nexport function multiTenant<B extends AnyPgColumnBuilder>(\n options: MultiTenantOptions<B>,\n): MultiTenantPlugin<TenantColumnOf<B>, TenantIdOf<B>> {\n return defineFeaturePlugin({\n id: 'multiTenant',\n needsContext: { $type: {} as TenantContext<TenantIdOf<B>> },\n systemOptions: { $type: {} as MultiTenantSystemOptions },\n context: (base, input): MultiTenantContext => {\n const unscoped = input.options?.unscoped\n if (unscoped !== undefined && typeof unscoped !== 'boolean') {\n throw new BadRequestError('unscoped must be a boolean')\n }\n if (unscoped === true && base.mode !== 'system') {\n throw new BadRequestError(\n 'unscoped is an option of $system(): a caller always has a tenant',\n )\n }\n return {\n unscoped: base.mode === 'system' && (unscoped === true || input.callerLookup === true),\n }\n },\n traits: {\n $types: {} as MultiTenantTraits,\n resolve: ({ entity, options: given, columns }) => {\n const option = given.tenant\n if (option === undefined || option === false) return null\n if (option !== true) fail(entity, 'tenant must be true')\n if (columns[COLUMN] === undefined) fail(entity, `tenant needs a column '${COLUMN}'`)\n return { state: { column: COLUMN } satisfies MultiTenantState, managed: [COLUMN] }\n },\n partition: ({ entity, state, ctx }) => {\n // Only a system call can have asked for it: a user-mode context of the same name is not the plugin's.\n if (ctx.mode === 'system' && ctx.unscoped === true) return undefined\n const tenant = ctx.tenantId\n if (tenant === null || tenant === undefined) {\n const hint =\n ctx.mode === 'system'\n ? ' (pass it through $system({ ctx }) or cross tenants with $system({ unscoped: true }))'\n : ''\n throw new ForbiddenError(\n `Entity '${entity.name}' belongs to a tenant, and the context has none${hint}`,\n { entity: entity.name, rule: 'tenant' },\n )\n }\n return { [columnOf(state)]: tenant }\n },\n },\n seed: {\n columns: (entity, { generators, values }) => {\n const column = tenantColumn(entity)\n if (column === null) return {}\n const tenant = values.tenant ?? options.seedTenant\n if (tenant === undefined && entity.columns[column]?.notNull === true) {\n throw new Error(\n `Collection '${entity.name}' belongs to a tenant: give one with multiTenant({ seedTenant }) or defineConfig({ seed: { values: { tenant } } })`,\n )\n }\n return { [column]: generators.default({ defaultValue: tenant ?? null }) }\n },\n },\n collection: {\n $options: {} as MultiTenantCollectionOptions,\n $kinds: {} as MultiTenantKinds<TenantColumnOf<B>>,\n consumes: ['tenant'],\n columns: (collection): Record<string, AnyPgColumnBuilder> =>\n collection.tenant === true ? { [COLUMN]: options.column() } : {},\n entity: (collection) => (collection.tenant === true ? { tenant: true } : {}),\n },\n })\n}\n","import { sql } from 'drizzle-orm'\nimport { type AnyPgColumn, type IndexBuilder, timestamp, uniqueIndex } from 'drizzle-orm/pg-core'\nimport { type DefinedPlugin, defineFeaturePlugin } from '../define/plugin.js'\nimport { ConfigError } from '../errors.js'\nimport type { CollectionKinds, EntityMeta } from '../types/index.js'\nimport type { EntityIdOf, EntityRowOf, EntityTraits } from '../types/traits.js'\nimport type { Descriptor } from '../contract/descriptor.js'\n\nfunction softDeleteColumns() {\n return { deletedAt: timestamp('deleted_at', { withTimezone: true }) }\n}\n\n// A unique index over the rows that are not deleted: a deleted row keeps its values without blocking a new\n// row that takes them.\nexport function softUnique(\n name: string,\n deletedAt: AnyPgColumn,\n): { on(...cols: [AnyPgColumn, ...AnyPgColumn[]]): IndexBuilder } {\n return {\n on: (...cols) =>\n uniqueIndex(name)\n .on(...cols)\n .where(sql`${deletedAt} is null`),\n }\n}\n\nexport type SoftDeleteCollectionOptions = { softDelete?: boolean }\n\nexport interface SoftDeleteKinds extends CollectionKinds {\n readonly columns: this['options'] extends { softDelete: true }\n ? ReturnType<typeof softDeleteColumns>\n : {}\n readonly entity: this['options'] extends { softDelete: true } ? { softDelete: true } : {}\n}\n\n// What a collection with `softDelete: true` passes to its entity.\nexport type SoftDeleteEntityOptions = { softDelete?: true }\n\nexport type SoftDeleteReadOptions = { withDeleted?: boolean | undefined }\nexport type SoftDeleteDeleteOptions = { hard?: boolean }\n\ntype Enabled = { softDelete: true }\n\n// `this` is only available at the top of the interface's members, so the shapes that use it are aliases.\nexport type SoftDeleteApi<T extends EntityTraits> = {\n restore(id: EntityIdOf<T>): Promise<EntityRowOf<T>>\n}\n\nexport type SoftDeleteQueries<T extends EntityTraits> = {\n restore(input: {\n id: EntityIdOf<T>\n }): Descriptor<T['name'] & string, 'restore', { id: EntityIdOf<T> }, EntityRowOf<T>>\n}\n\nexport interface SoftDeleteTraits extends EntityTraits {\n readonly entityOptions: SoftDeleteEntityOptions\n readonly governs: Enabled\n readonly managed: this['given'] extends Enabled ? 'deletedAt' : never\n readonly optionsOn: this['given'] extends Enabled ? 'read' | 'delete' : never\n readonly optionTypes: { read: SoftDeleteReadOptions; delete: SoftDeleteDeleteOptions }\n readonly operations: 'restore'\n readonly api: this['given'] extends Enabled ? SoftDeleteApi<this> : {}\n readonly queries: this['given'] extends Enabled ? SoftDeleteQueries<this> : {}\n}\n\ntype SoftDeleteState = { readonly column: string }\n\nconst COLUMN = 'deletedAt'\n\nfunction columnOf(state: unknown): string {\n return (state as SoftDeleteState).column\n}\n\nfunction fail(entity: string, message: string): never {\n throw new ConfigError(`Entity '${entity}': ${message}`, 'config', { entity })\n}\n\n// The soft-delete column of an entity, or null where the plugin does not act.\nexport function softDeleteColumn(entity: EntityMeta): string | null {\n const trait = entity.traits.softDelete\n return trait === undefined ? null : columnOf(trait.state)\n}\n\n// Deleted rows keep their row and their id; every read hides them unless it asks for `withDeleted`, and\n// `delete(id, { hard: true })` removes them for good.\nexport type SoftDeletePlugin = DefinedPlugin<\n 'softDelete',\n {},\n {},\n {},\n {},\n {},\n {},\n {},\n {},\n SoftDeleteKinds,\n SoftDeleteCollectionOptions,\n {},\n {},\n never,\n {},\n SoftDeleteTraits,\n never\n>\n\nexport function softDelete(): SoftDeletePlugin {\n return defineFeaturePlugin({\n id: 'softDelete',\n traits: {\n $types: {} as SoftDeleteTraits,\n options: { read: { withDeleted: 'boolean' }, delete: { hard: 'boolean' } },\n resolve: ({ entity, options, columns }) => {\n const option = options.softDelete\n if (option === undefined || option === false) return null\n if (option !== true) fail(entity, 'softDelete must be true')\n // The collection adds the column; a table built any other way must carry the same one.\n const column = columns[COLUMN]\n if (column === undefined || column.dataType !== 'object date' || column.notNull) {\n fail(entity, `softDelete needs a nullable timestamp column '${COLUMN}'`)\n }\n return { state: { column: COLUMN } satisfies SoftDeleteState, managed: [COLUMN] }\n },\n filter: ({ state, operation, options }) => {\n const column = columnOf(state)\n if (operation === 'restore') return { [column]: { isNotNull: true } }\n // A hard delete may remove a row that is already soft-deleted, and reaches deleted rows through\n // the relations of its filter.\n if (options.withDeleted === true || options.hard === true) return undefined\n return { [column]: { isNull: true } }\n },\n remove: ({ state, options, now, update }) =>\n options.hard === true ? undefined : update({ [columnOf(state)]: now }),\n operations: {\n restore: {\n args: ['id'],\n route: { method: 'POST', path: ':id/restore' },\n run: ({ state, input, kit }) => kit.update(input.id, { [columnOf(state)]: null }),\n },\n },\n },\n seed: {\n // Generated rows are alive; seeding deleted ones is what a test does on purpose.\n columns: (entity, { generators }) => {\n const column = softDeleteColumn(entity)\n return column === null ? {} : { [column]: generators.default({ defaultValue: null }) }\n },\n },\n collection: {\n $options: {} as SoftDeleteCollectionOptions,\n $kinds: {} as SoftDeleteKinds,\n consumes: ['softDelete'],\n columns: (options) => (options.softDelete === true ? softDeleteColumns() : {}),\n entity: (options) => (options.softDelete === true ? { softDelete: true } : {}),\n },\n })\n}\n","import { and, desc, eq, inArray, sql } from 'drizzle-orm'\nimport type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core'\nimport type { AnyDb, AnyRow, AnyTx, BaseContext, EntityMeta } from '../../types/index.js'\nimport type { PendingDraftPolicy, VersionRef, VersionState } from './types.js'\n\ntype Tx = AnyTx | AnyDb\n\n// What `resolve` found for one entity.\nexport type VersionsState = {\n readonly key: string\n readonly table: PgTable\n readonly drafts: boolean\n readonly max: number | null\n readonly onPendingDraft: PendingDraftPolicy\n}\n\nexport const STATUS = 'status'\nexport const PUBLISHED_AT = 'publishedAt'\n\nexport function col(table: PgTable, key: string): AnyPgColumn {\n return (table as unknown as Record<string, AnyPgColumn>)[key] as AnyPgColumn\n}\n\nexport function stateOf(state: VersionsState, doc: AnyRow): VersionState {\n if (!state.drafts) return 'published'\n return doc[STATUS] === 'published' ? 'published' : 'draft'\n}\n\n// The entity's columns of a version row, without the bookkeeping.\nexport function entityData(entity: EntityMeta, row: AnyRow): AnyRow {\n const out: AnyRow = {}\n for (const key of Object.keys(entity.columns)) out[key] = row[key]\n return out\n}\n\nfunction generatedAlways(entity: EntityMeta, key: string): boolean {\n const column = entity.columns[key]?.column\n return column?.generated?.type === 'always' || column?.generatedIdentity?.type === 'always'\n}\n\n// The content of a version is everything except identity, the columns the plugins manage and what the\n// database or Drizzle fills in: restoring or publishing content must not resurrect an old status, deletion or\n// tenant.\nexport function contentPatch(entity: EntityMeta, from: AnyRow, to: AnyRow): AnyRow {\n const skip = new Set([entity.pk.key, ...entity.managedKeys])\n const patch: AnyRow = {}\n for (const key of Object.keys(entity.columns)) {\n if (skip.has(key) || generatedAlways(entity, key)) continue\n if (entity.columns[key]?.column.onUpdateFn !== undefined) continue\n if (!equal(from[key], to[key])) patch[key] = to[key]\n }\n return patch\n}\n\n// jsonb columns compare by value, and a key holding undefined is a key that is not there.\nexport function equal(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (a instanceof Date || b instanceof Date) {\n return a instanceof Date && b instanceof Date && a.getTime() === b.getTime()\n }\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => equal(item, b[i]))\n }\n const left = a as Record<string, unknown>\n const right = b as Record<string, unknown>\n const keys = new Set([...Object.keys(left), ...Object.keys(right)])\n for (const key of keys) {\n if (!equal(left[key], right[key])) return false\n }\n return true\n}\n\nasync function latestVersion(tx: Tx, entity: EntityMeta, state: VersionsState, id: unknown) {\n const { table } = state\n const rows = (await tx\n .select()\n .from(table)\n .where(and(eq(col(table, entity.pk.key), id), eq(col(table, 'versionIsLatest'), true)))\n .limit(1)) as AnyRow[]\n return rows[0] ?? null\n}\n\n// A published document with a newer draft version: that draft is what `publish`, `discardDraft` and a draft\n// write build on.\nexport async function pendingDraft(\n tx: Tx,\n entity: EntityMeta,\n state: VersionsState,\n row: AnyRow,\n): Promise<AnyRow | null> {\n if (!state.drafts || row[STATUS] !== 'published') return null\n const latest = await latestVersion(tx, entity, state, row[entity.pk.key])\n return latest !== null && latest.versionState === 'draft' ? entityData(entity, latest) : null\n}\n\n// The document row is locked by the engine, so max()+1 cannot race: numbering is gapless per document and the\n// partial unique index on the latest flag is only a backstop.\nexport async function recordVersion(\n tx: Tx,\n entity: EntityMeta,\n state: VersionsState,\n doc: AnyRow,\n versionState: VersionState,\n operation: string,\n ctx: BaseContext,\n): Promise<VersionRef> {\n const { table } = state\n const idColumn = col(table, entity.pk.key)\n const id = doc[entity.pk.key]\n const [next] = (await tx\n .select({\n value: sql<number>`coalesce(max(${col(table, 'versionNumber')}), 0) + 1`.mapWith(Number),\n })\n .from(table)\n .where(eq(idColumn, id))) as { value: number }[]\n await tx\n .update(table)\n .set({ versionIsLatest: false } as never)\n .where(and(eq(idColumn, id), eq(col(table, 'versionIsLatest'), true)))\n const [row] = (await tx\n .insert(table)\n .values({\n ...entityData(entity, doc),\n versionNumber: next?.value ?? 1,\n versionIsLatest: true,\n versionState,\n versionOperation: operation,\n versionCreatedBy: ctx.actorId,\n versionMode: ctx.mode,\n versionSystemReason: ctx.systemReason,\n versionRequestId: ctx.requestId,\n } as never)\n .returning()) as AnyRow[]\n await prune(tx, entity, state, id)\n return {\n versionId: row?.versionId as string,\n versionNumber: row?.versionNumber as number,\n state: versionState,\n }\n}\n\n// Retention keeps the newest `max` versions, and never drops the latest one or the last published one (the\n// state a draft would be discarded back to).\nasync function prune(tx: Tx, entity: EntityMeta, state: VersionsState, id: unknown) {\n if (state.max === null) return\n const { table } = state\n const rows = (await tx\n .select({\n id: col(table, 'versionId'),\n state: col(table, 'versionState'),\n latest: col(table, 'versionIsLatest'),\n })\n .from(table)\n .where(eq(col(table, entity.pk.key), id))\n .orderBy(desc(col(table, 'versionNumber')))) as { id: string; state: string; latest: boolean }[]\n if (rows.length <= state.max) return\n const keep = new Set(rows.slice(0, state.max).map((r) => r.id))\n const lastPublished = rows.find((r) => r.state === 'published')\n if (lastPublished !== undefined) keep.add(lastPublished.id)\n const latest = rows.find((r) => r.latest)\n if (latest !== undefined) keep.add(latest.id)\n const drop = rows.filter((r) => !keep.has(r.id)).map((r) => r.id)\n if (drop.length > 0) await tx.delete(table).where(inArray(col(table, 'versionId'), drop))\n}\n\nexport function toVersion(entity: EntityMeta, row: AnyRow): AnyRow {\n const data: AnyRow = {}\n for (const key of entity.visibleKeys) data[key] = row[key]\n return {\n versionId: row.versionId,\n versionNumber: row.versionNumber,\n state: row.versionState,\n operation: row.versionOperation,\n isLatest: row.versionIsLatest,\n createdAt: row.versionCreatedAt,\n createdBy: row.versionCreatedBy,\n mode: row.versionMode,\n systemReason: row.versionSystemReason,\n requestId: row.versionRequestId,\n data,\n }\n}\n","import { getTableColumns, getTableName, sql } from 'drizzle-orm'\nimport {\n type AnyPgColumn,\n type AnyPgColumnBuilder,\n boolean,\n type ExtraConfigColumn,\n foreignKey,\n getTableConfig,\n index,\n integer,\n type PgSchema,\n type PgTable,\n text,\n timestamp,\n unique,\n uniqueIndex,\n uuid,\n} from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../../errors.js'\nimport { cloneColumn } from '../../schema/index.js'\n\n// The two columns the publish workflow writes on a collection with drafts.\nexport function draftColumns() {\n return {\n status: text('status', { enum: ['draft', 'published'] })\n .notNull()\n .default('draft'),\n publishedAt: timestamp('published_at', { withTimezone: true }),\n }\n}\n\nexport const VERSION_STATES = ['draft', 'published'] as const\nexport const VERSION_MODES = ['user', 'system'] as const\n\n// Names are prefixed `version_` on purpose: they can never clash with a cloned column, which is enforced below\n// rather than assumed. Enum-like columns are text so value changes never produce ALTER TYPE (ARCHITECTURE §5);\n// the operation is open, since another plugin's operation (`restore`) is recorded under its own name.\nexport const VERSION_COLUMNS = () => ({\n versionId: uuid('version_id').primaryKey().defaultRandom(),\n versionNumber: integer('version_number').notNull(),\n versionIsLatest: boolean('version_is_latest').notNull().default(false),\n versionState: text('version_state', { enum: VERSION_STATES }).notNull(),\n versionOperation: text('version_operation').notNull(),\n versionCreatedAt: timestamp('version_created_at', { withTimezone: true }).notNull().defaultNow(),\n versionCreatedBy: text('version_created_by'),\n versionMode: text('version_mode', { enum: VERSION_MODES }).notNull(),\n versionSystemReason: text('version_system_reason'),\n versionRequestId: text('version_request_id'),\n})\n\nexport const VERSION_COLUMN_PREFIX = 'version_'\n\nexport type BuildVersionsTableOptions = { schema: PgSchema<string>; name?: string }\n\nfunction singlePrimaryKey(source: PgTable): { key: string; column: AnyPgColumn } {\n const tableName = getTableName(source)\n const cfg = getTableConfig(source)\n if (cfg.primaryKeys.length > 0) {\n throw new ConfigError(\n `Versioned table '${tableName}' has a composite primary key; versions need a single-column pk`,\n )\n }\n const pks = Object.entries(getTableColumns(source)).filter(([, c]) => c.primary)\n const first = pks[0]\n if (first === undefined || pks.length !== 1) {\n throw new ConfigError(\n `Versioned table '${tableName}' must have exactly one primary-key column (found ${pks.length})`,\n )\n }\n return { key: first[0], column: first[1] }\n}\n\n// Every column of the source, cloned, after the bookkeeping columns; the document id is the source's primary\n// key, which a version row references (cascading on delete) but does not own.\nexport function buildVersionsTable(source: PgTable, opts: BuildVersionsTableOptions): PgTable {\n const sourceName = getTableName(source)\n const name = opts.name ?? `${sourceName}_versions`\n const pk = singlePrimaryKey(source)\n const bookkeeping = VERSION_COLUMNS() as Record<string, AnyPgColumnBuilder>\n const cloned: Record<string, AnyPgColumnBuilder> = {}\n for (const [key, column] of Object.entries(getTableColumns(source))) {\n if (key in bookkeeping || column.name.startsWith(VERSION_COLUMN_PREFIX)) {\n throw new ConfigError(\n `Versioned table '${sourceName}': column '${key}' ('${column.name}') collides with the ` +\n `version_* bookkeeping columns`,\n )\n }\n // The document id is always written explicitly, so its generator default is dropped (§5.1 DDL).\n cloned[key] = cloneColumn(column, { keepDefault: key !== pk.key })\n }\n const columns = { ...bookkeeping, ...cloned }\n return opts.schema.table(name, columns, (t: Record<string, ExtraConfigColumn>) => {\n const id = t[pk.key] as ExtraConfigColumn\n const number = t.versionNumber as ExtraConfigColumn\n const latest = t.versionIsLatest as ExtraConfigColumn\n const createdAt = t.versionCreatedAt as ExtraConfigColumn\n return [\n foreignKey({ name: `${name}_doc_fk`, columns: [id], foreignColumns: [pk.column] }).onDelete(\n 'cascade',\n ),\n unique(`${name}_doc_number`).on(id, number),\n uniqueIndex(`${name}_latest`)\n .on(id)\n .where(sql`${latest}`),\n index(`${name}_created`).on(id, createdAt.desc()),\n ]\n }) as PgTable\n}\n","import { and, desc, eq, is } from 'drizzle-orm'\nimport { PgTable } from 'drizzle-orm/pg-core'\nimport { type DefinedPlugin, defineFeaturePlugin } from '../../define/plugin.js'\nimport {\n BadRequestError,\n ConfigError,\n InvalidStateError,\n NotFoundError,\n UnsupportedError,\n} from '../../errors.js'\nimport type { AnyRow, EntityMeta } from '../../types/index.js'\nimport type { KitReadInput, OperationKit } from '../../types/traits.js'\nimport {\n col,\n contentPatch,\n entityData,\n equal,\n PUBLISHED_AT,\n pendingDraft,\n recordVersion,\n STATUS,\n stateOf,\n toVersion,\n type VersionsState,\n} from './history.js'\nimport { buildVersionsTable, draftColumns } from './table.js'\nimport type {\n PendingDraftPolicy,\n VersionsCollectionOptions,\n VersionsKinds,\n VersionsTraits,\n VersionState,\n} from './types.js'\n\nexport { buildVersionsTable, draftColumns, VERSION_COLUMNS } from './table.js'\nexport type { BuildVersionsTableOptions } from './table.js'\nexport type * from './types.js'\n\ntype Parsed = {\n readonly drafts: boolean\n readonly max: number | null\n readonly onPendingDraft: PendingDraftPolicy\n readonly table: PgTable | undefined\n}\n\nfunction fail(entity: string, message: string): never {\n throw new ConfigError(`Entity '${entity}': ${message}`, 'config', { entity })\n}\n\nfunction parse(entity: string, option: unknown): Parsed | null {\n if (option === undefined || option === false) return null\n if (option !== true && (typeof option !== 'object' || option === null)) {\n fail(entity, 'versions must be true or an object')\n }\n const opts = (option === true ? {} : option) as Record<string, unknown>\n for (const key of Object.keys(opts)) {\n if (!['drafts', 'max', 'onPendingDraft', 'table'].includes(key)) {\n fail(entity, `versions.${key} is not an option`)\n }\n }\n const { drafts, max, onPendingDraft, table } = opts\n if (drafts !== undefined && typeof drafts !== 'boolean') {\n fail(entity, 'versions.drafts must be a boolean')\n }\n if (max !== undefined && (!Number.isInteger(max) || (max as number) < 1)) {\n fail(entity, 'versions.max must be a positive integer')\n }\n if (\n onPendingDraft !== undefined &&\n onPendingDraft !== 'supersede' &&\n onPendingDraft !== 'reject'\n ) {\n fail(entity, `versions.onPendingDraft must be 'supersede' or 'reject'`)\n }\n if (table !== undefined && !is(table, PgTable)) fail(entity, 'versions.table is not a pg table')\n return {\n drafts: drafts === true,\n max: (max as number | undefined) ?? null,\n onPendingDraft: (onPendingDraft as PendingDraftPolicy | undefined) ?? 'supersede',\n table: table as PgTable | undefined,\n }\n}\n\nfunction keyOf(entity: string): string {\n return `${entity}Versions`\n}\n\nfunction versionsState(state: unknown): VersionsState {\n return state as VersionsState\n}\n\n// The versions table of an entity, or null where the plugin does not act.\nexport function versionsTable(entity: EntityMeta): PgTable | null {\n const trait = entity.traits.versions\n return trait === undefined ? null : versionsState(trait.state).table\n}\n\n// The name each change is recorded under: this plugin's own vocabulary, another plugin's operation by its name.\nfunction recordedAs(operation: string, draft: boolean): string {\n if (operation === 'update') return draft ? 'draft' : 'update'\n if (operation === 'versions.restore') return 'restoreVersion'\n if (operation === 'discardDraft') return 'discard'\n return operation\n}\n\nfunction assertId(entity: EntityMeta, id: unknown) {\n if (id === undefined || id === null) {\n throw new BadRequestError(`${entity.name}: an id is required`, { entity: entity.name })\n }\n}\n\nfunction history(\n entity: EntityMeta,\n state: VersionsState,\n { executor, partition }: KitReadInput,\n id: unknown,\n) {\n const { table } = state\n // The history of a row stays in the row's partition; what the plugins hide from the row as it is now does not\n // apply to its past.\n const conditions = [\n eq(col(table, entity.pk.key), id),\n ...Object.entries(partition).map(([key, value]) => eq(col(table, key), value)),\n ]\n return { executor, table, conditions }\n}\n\nasync function loadVersion(\n entity: EntityMeta,\n state: VersionsState,\n input: KitReadInput,\n id: unknown,\n versionId: unknown,\n): Promise<AnyRow> {\n if (typeof versionId !== 'string') throw new BadRequestError('versionId must be a string')\n const { executor, table, conditions } = history(entity, state, input, id)\n const rows = (await executor\n .select()\n .from(table)\n .where(and(...conditions, eq(col(table, 'versionId'), versionId)))\n .limit(1)) as AnyRow[]\n const row = rows[0]\n if (row === undefined) {\n throw new NotFoundError(`Version '${versionId}' of ${entity.name} '${String(id)}' not found`, {\n entity: entity.name,\n })\n }\n return row\n}\n\nfunction readVersions(kit: OperationKit, fn: (input: KitReadInput) => Promise<unknown>) {\n return kit.read(fn, { rule: 'readVersions' })\n}\n\n// Every change of a versioned collection appends a version: its history, which `versions` lists, compares and\n// restores. With drafts, a published document keeps its live row while edits go to a draft version, which\n// `publish` makes live; plain reads see published rows only, and `draft: true` reads the latest drafts.\nexport type VersionsPlugin = DefinedPlugin<\n 'versions',\n {},\n {},\n {},\n {},\n {},\n {},\n {},\n {},\n VersionsKinds,\n VersionsCollectionOptions,\n {},\n {},\n never,\n {},\n VersionsTraits,\n never\n>\n\nexport function versions(): VersionsPlugin {\n return defineFeaturePlugin({\n id: 'versions',\n traits: {\n $types: {} as VersionsTraits,\n options: {\n read: { draft: 'boolean' },\n create: { draft: 'boolean', publish: 'boolean' },\n update: { draft: 'boolean' },\n },\n rules: { readDrafts: 'filter', readVersions: 'boolean', publish: 'filter' },\n hookArgs: {\n change: { draft: false },\n afterChange: { previousDraft: null, version: null },\n afterDelete: { version: null },\n },\n derive: ({ entity, table, options, schema }) => {\n const parsed = parse(entity, options.versions)\n if (parsed === null) return null\n return {\n [keyOf(entity)]: {\n table: parsed.table ?? buildVersionsTable(table, { schema }),\n mirror: true,\n },\n }\n },\n resolve: ({ entity, options, columns, derived }) => {\n const parsed = parse(entity, options.versions)\n if (parsed === null) return null\n if (parsed.drafts) {\n for (const key of [STATUS, PUBLISHED_AT]) {\n if (!(key in columns)) {\n fail(\n entity,\n `versions.drafts needs a column '${key}' (add draftColumns() to the table)`,\n )\n }\n }\n const values = columns[STATUS]?.enumValues\n if (values !== undefined && !(values.includes('draft') && values.includes('published'))) {\n fail(entity, `versions.drafts needs status to allow 'draft' and 'published'`)\n }\n }\n const key = keyOf(entity)\n const state: VersionsState = {\n key,\n table: derived[key] as PgTable,\n drafts: parsed.drafts,\n max: parsed.max,\n onPendingDraft: parsed.onPendingDraft,\n }\n return parsed.drafts\n ? { state, managed: [STATUS, PUBLISHED_AT], options: ['read', 'create', 'update'] }\n : { state, options: [], rules: ['readVersions'] }\n },\n // A draft is hidden from readers, not from the writes that edit it.\n filter: ({ state, writing }) =>\n versionsState(state).drafts && !writing ? { [STATUS]: { eq: 'published' } } : undefined,\n source: ({ state, options }) =>\n options.draft === true\n ? {\n table: versionsState(state).key,\n filter: { versionIsLatest: { eq: true } },\n rule: 'readDrafts',\n }\n : undefined,\n create: ({ state, options, row, now }) => {\n if (!versionsState(state).drafts) return undefined\n const publish = options.publish === true\n return {\n set: publish ? { [STATUS]: 'published', [PUBLISHED_AT]: row[PUBLISHED_AT] ?? now } : {},\n rules: publish ? ['publish'] : [],\n args: { change: { draft: options.draft === true } },\n }\n },\n update: async ({ entity, state: raw, operation, options, row, tx }) => {\n const state = versionsState(raw)\n if (!state.drafts) return undefined\n const pending = await pendingDraft(tx, entity, state, row)\n const after = { afterChange: { previousDraft: pending } }\n if (operation === 'publish' || operation === 'unpublish') return { args: after }\n if (operation === 'discardDraft') return { base: pending ?? row, keep: true, args: after }\n // A restore writes a draft of a published document unless told otherwise; an update only when asked.\n const draft =\n (options.draft ?? operation === 'versions.restore') === true &&\n row[STATUS] === 'published'\n if (draft) {\n return { base: pending ?? row, keep: true, args: { ...after, change: { draft: true } } }\n }\n if (pending !== null && state.onPendingDraft === 'reject') {\n throw new InvalidStateError(\n `${entity.name} '${String(row[entity.pk.key])}' has a pending draft: publish or discard it first`,\n { entity: entity.name },\n )\n }\n return { args: after }\n },\n record: async ({ entity, state: raw, operation, step, row, written, tx, ctx }) => {\n const state = versionsState(raw)\n // A removed row takes its history with it (the foreign key cascades).\n if (step === 'delete' && written) return undefined\n // Another plugin may keep a write too; only this plugin's kept writes are drafts.\n const draft = step === 'update' && !written && state.drafts\n const versionState: VersionState =\n operation === 'discardDraft' ? 'published' : draft ? 'draft' : stateOf(state, row)\n const version = await recordVersion(\n tx,\n entity,\n state,\n row,\n versionState,\n step === 'update' ? recordedAs(operation, draft) : operation,\n ctx,\n )\n return { version }\n },\n operations: {\n publish: {\n args: ['id'],\n route: { method: 'POST', path: ':id/publish' },\n run: ({ entity, state, input, kit }) =>\n kit.update(\n input.id,\n async ({ row, tx, now }) => {\n const pending = await pendingDraft(tx, entity, versionsState(state), row)\n if (row[STATUS] === 'published' && pending === null) return undefined\n return {\n ...(pending === null ? {} : contentPatch(entity, row, pending)),\n [STATUS]: 'published',\n [PUBLISHED_AT]: now,\n }\n },\n { rule: 'publish' },\n ),\n },\n unpublish: {\n args: ['id'],\n route: { method: 'POST', path: ':id/unpublish' },\n run: ({ entity, input, kit }) =>\n kit.update(\n input.id,\n ({ row }) => {\n if (row[STATUS] !== 'published') {\n throw new InvalidStateError(\n `${entity.name} '${String(input.id)}' is not published`,\n {\n entity: entity.name,\n },\n )\n }\n return { [STATUS]: 'draft' }\n },\n { rule: 'publish' },\n ),\n },\n discardDraft: {\n args: ['id'],\n route: { method: 'POST', path: ':id/discard-draft' },\n // History is append-only: discarding records the live state again instead of deleting the draft.\n run: ({ entity, state, input, kit }) =>\n kit.update(input.id, async ({ row, tx }) => {\n const pending = await pendingDraft(tx, entity, versionsState(state), row)\n return pending === null ? undefined : contentPatch(entity, pending, row)\n }),\n },\n 'versions.list': {\n args: ['id'],\n options: { limit: 'number', offset: 'number', state: 'string' },\n route: { method: 'GET', path: ':id/versions' },\n run: ({ entity, state, input, kit }) => {\n assertId(entity, input.id)\n const limit = input.limit ?? entity.maxLimit\n const offset = input.offset ?? 0\n for (const [name, value] of [\n ['limit', limit],\n ['offset', offset],\n ] as const) {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {\n throw new BadRequestError(`${name} must be a non-negative integer`)\n }\n }\n if ((limit as number) > entity.maxLimit) {\n throw new BadRequestError(`limit exceeds the maximum of ${entity.maxLimit}`)\n }\n if (\n input.state !== undefined &&\n input.state !== 'draft' &&\n input.state !== 'published'\n ) {\n throw new BadRequestError(`state must be 'draft' or 'published'`)\n }\n return readVersions(kit, async (read) => {\n const { executor, table, conditions } = history(\n entity,\n versionsState(state),\n read,\n input.id,\n )\n const rows = (await executor\n .select()\n .from(table)\n .where(\n and(\n ...conditions,\n input.state === undefined\n ? undefined\n : eq(col(table, 'versionState'), input.state),\n ),\n )\n .orderBy(desc(col(table, 'versionNumber')))\n .limit(limit as number)\n .offset(offset as number)) as AnyRow[]\n return rows.map((row) => toVersion(entity, row))\n })\n },\n },\n 'versions.get': {\n args: ['id', 'versionId'],\n route: { method: 'GET', path: ':id/versions/:versionId' },\n run: ({ entity, state, input, kit }) => {\n assertId(entity, input.id)\n return readVersions(kit, async (read) =>\n toVersion(\n entity,\n await loadVersion(entity, versionsState(state), read, input.id, input.versionId),\n ),\n )\n },\n },\n 'versions.diff': {\n args: ['id', 'from', 'to'],\n route: { method: 'GET', path: ':id/diff' },\n run: ({ entity, state, input, kit }) => {\n assertId(entity, input.id)\n return readVersions(kit, async (read) => {\n const before = await loadVersion(\n entity,\n versionsState(state),\n read,\n input.id,\n input.from,\n )\n const after = await loadVersion(\n entity,\n versionsState(state),\n read,\n input.id,\n input.to,\n )\n const out: { field: string; before: unknown; after: unknown }[] = []\n for (const key of entity.visibleKeys) {\n if (!equal(before[key], after[key])) {\n out.push({ field: key, before: before[key], after: after[key] })\n }\n }\n return out\n })\n },\n },\n 'versions.restore': {\n args: ['id', 'versionId'],\n options: { draft: 'boolean' },\n route: { method: 'POST', path: ':id/versions/:versionId/restore' },\n run: ({ entity, state: raw, input, kit }) => {\n const state = versionsState(raw)\n if (typeof input.versionId !== 'string') {\n throw new BadRequestError('versionId must be a string')\n }\n if (input.draft === true && !state.drafts) {\n throw new UnsupportedError(`Entity '${entity.name}' has no drafts`, {\n entity: entity.name,\n })\n }\n return kit.update(\n input.id,\n async ({ row, tx }) => {\n const { table } = state\n const rows = (await tx\n .select()\n .from(table)\n .where(\n and(\n eq(col(table, entity.pk.key), input.id),\n eq(col(table, 'versionId'), input.versionId),\n ),\n )\n .limit(1)) as AnyRow[]\n const version = rows[0]\n if (version === undefined) {\n throw new NotFoundError(\n `Version '${input.versionId}' of ${entity.name} '${String(input.id)}' not found`,\n { entity: entity.name },\n )\n }\n return contentPatch(entity, row, entityData(entity, version))\n },\n { options: { draft: input.draft } },\n )\n },\n },\n },\n },\n seed: {\n // A generated row is a published one: a draft would be invisible to every plain read.\n columns: (entity, { generators }) => {\n const trait = entity.traits.versions\n return trait !== undefined && versionsState(trait.state).drafts\n ? {\n [STATUS]: generators.default({ defaultValue: 'published' }),\n [PUBLISHED_AT]: generators.default({ defaultValue: new Date() }),\n }\n : {}\n },\n },\n collection: {\n $options: {} as VersionsCollectionOptions,\n $kinds: {} as VersionsKinds,\n consumes: ['versions'],\n columns: (options) =>\n typeof options.versions === 'object' &&\n options.versions !== null &&\n (options.versions as { drafts?: unknown }).drafts === true\n ? draftColumns()\n : {},\n entity: (options) => (options.versions === undefined ? {} : { versions: options.versions }),\n },\n })\n}\n","import type { Assume } from 'drizzle-orm'\nimport type { AnyPgColumnBuilder } from 'drizzle-orm/pg-core'\nimport type { AnyPlugin } from '../types/plugin.js'\nimport { localization, type LocalizationOptions, type LocalizationPlugin } from './localization.js'\nimport {\n multiTenant,\n type MultiTenantOptions,\n type MultiTenantPlugin,\n type TenantColumnOf,\n type TenantIdOf,\n} from './multi-tenant.js'\nimport { softDelete, type SoftDeletePlugin } from './soft-delete.js'\nimport { versions, type VersionsPlugin } from './versions/index.js'\n\nexport type Locales = readonly [string, ...string[]]\n\n// Soft delete and versions take no global option: every config has them, and a collection opts in.\nexport type DefaultFeaturePlugins = readonly [VersionsPlugin, SoftDeletePlugin]\n\n// The core's order, which decides the columns a collection ends up with.\nexport type FeaturePlugins<L, D, B> = readonly [\n ...([L] extends [never]\n ? []\n : [LocalizationPlugin<Assume<L, Locales>, Assume<D, Assume<L, Locales>[number]>>]),\n VersionsPlugin,\n SoftDeletePlugin,\n ...([B] extends [never] ? [] : [MultiTenantPlugin<TenantColumnOf<B>, TenantIdOf<B>>]),\n]\n\nexport type FeaturesOptions<\n L extends Locales,\n D extends L[number],\n B extends AnyPgColumnBuilder,\n> = {\n localization?: LocalizationOptions<L, D>\n multiTenant?: MultiTenantOptions<B>\n}\n\nexport const FEATURE_IDS: ReadonlySet<string> = new Set([\n 'localization',\n 'versions',\n 'softDelete',\n 'multiTenant',\n])\n\nexport function featurePlugins(\n options: FeaturesOptions<Locales, string, AnyPgColumnBuilder>,\n): AnyPlugin[] {\n const plugins: AnyPlugin[] = []\n if (options.localization !== undefined) plugins.push(localization(options.localization) as never)\n plugins.push(versions() as never, softDelete() as never)\n if (options.multiTenant !== undefined) plugins.push(multiTenant(options.multiTenant) as never)\n return plugins\n}\n","import type { Assume } from 'drizzle-orm'\nimport type { AnyPgColumnBuilder } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport {\n type DefaultFeaturePlugins,\n FEATURE_IDS,\n featurePlugins,\n type FeaturePlugins,\n type FeaturesOptions,\n type Locales,\n} from '../features/index.js'\nimport type { LocalizationPlugin } from '../features/localization.js'\nimport type { AnyPlugin, DependenciesError } from '../types/plugin.js'\nimport { checkDependencies } from './plugin.js'\n\n// An interface, so that TypeScript takes the setup as a reference and looks no further than the tuple. The plugins\n// are the core's way of building the features and the application's plugins, not something it reads.\nexport interface TypionSetup<TPlugins extends readonly AnyPlugin[]> {\n readonly '~plugins': TPlugins\n}\n\nexport type AnySetup = TypionSetup<readonly AnyPlugin[]>\n\nexport type DefaultSetup = TypionSetup<DefaultFeaturePlugins>\n\n// What an application reads of its localization: a language switcher, the locale a form writes.\nexport interface SetupLocalization<L extends Locales, D extends L[number]> {\n readonly locales: L\n readonly defaultLocale: D\n}\n\n// The features first, in the core's order, then the application's plugins: what a config installs.\nexport type SetupPlugins<L, D, B, P extends readonly AnyPlugin[]> = readonly [\n ...FeaturePlugins<L, D, B>,\n ...P,\n]\n\nexport type Setup<L, D, B, P extends readonly AnyPlugin[]> = TypionSetup<SetupPlugins<L, D, B, P>> &\n ([L] extends [never]\n ? {}\n : {\n readonly localization: SetupLocalization<\n Assume<L, Locales>,\n Assume<D, Assume<L, Locales>[number]>\n >\n })\n\nexport type SetupOptions<\n L extends Locales,\n D extends L[number],\n B extends AnyPgColumnBuilder,\n P extends readonly AnyPlugin[],\n> = FeaturesOptions<L, D, B> & {\n // Checked where the list is written: a plugin comes after those it depends on.\n plugins?: P & DependenciesError<P>\n}\n\n// Everything that shapes the collections' types, in one constant registered next to the config: the features\n// configured for the application (soft delete and versions need no line, a collection turns them on) and the plugins\n// installed. A constant of its own because the collections are typed from it, and a config they read would depend on\n// itself.\nexport function defineSetup<\n const L extends Locales = never,\n const D extends L[number] = never,\n B extends AnyPgColumnBuilder = never,\n const P extends readonly AnyPlugin[] = readonly [],\n>(options: SetupOptions<L, D, B, P>): Setup<L, D, B, P> {\n const plugins = featurePlugins(options as never)\n const ids = new Set(plugins.map((plugin) => plugin.id))\n for (const plugin of (options.plugins ?? []) as readonly AnyPlugin[]) {\n if (FEATURE_IDS.has(plugin.id)) {\n throw new ConfigError(`Plugin '${plugin.id}' has the name of a feature of the core`)\n }\n if (ids.has(plugin.id)) throw new ConfigError(`Plugin '${plugin.id}' is installed twice`)\n ids.add(plugin.id)\n plugins.push(plugin)\n }\n checkDependencies(plugins)\n const out: Record<string, unknown> = { '~plugins': Object.freeze(plugins) }\n const localization = plugins.find((plugin) => plugin.id === 'localization') as\n LocalizationPlugin<Locales, string> | undefined\n if (localization !== undefined) {\n out.localization = Object.freeze({\n locales: localization.locales,\n defaultLocale: localization.defaultLocale,\n })\n }\n return Object.freeze(out) as never\n}\n\nexport function defaultSetup(): DefaultSetup {\n return { '~plugins': featurePlugins({}) as never }\n}\n","import { getTableColumns, is } from 'drizzle-orm'\nimport { isPgEnum, type PgEnum, PgTable } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport { localizedKind } from '../features/localization.js'\nimport { readColumnKind } from '../schema/column-kinds.js'\nimport type {\n AnyCollection,\n ByName,\n ConfigOptions,\n ConfigTables,\n ConfigTypes,\n RelationSpec,\n TypionConfig,\n} from '../types/collection.js'\nimport type { TypionDefinition } from '../types/meta.js'\nimport { buildCollectionTable, collectionEntityOptions } from './collection.js'\nimport { defineEngine } from './engine.js'\nimport { type AnySetup, type DefaultSetup, defaultSetup } from './setup.js'\n\ntype LooseColumn = { through(column: unknown): unknown }\ntype LooseRelationsBuilder = Record<string, Record<string, LooseColumn>> & {\n one: Record<string, (config: Record<string, unknown>) => unknown>\n many: Record<string, (config: Record<string, unknown>) => unknown>\n}\n\n// drizzle-kit creates an enum only when the enum itself is in the schema it is given, so the enums the columns\n// use are collected rather than left to the application to list.\nfunction enumsOf(tables: Iterable<PgTable>): Map<PgEnum<any>, string> {\n const out = new Map<PgEnum<any>, string>()\n for (const table of tables) {\n for (const column of Object.values(getTableColumns(table))) {\n const candidate = (column as { enum?: unknown }).enum\n if (isPgEnum(candidate)) out.set(candidate, candidate.enumName)\n }\n }\n return out\n}\n\nfunction relationConfig(\n r: LooseRelationsBuilder,\n name: string,\n field: string,\n spec: RelationSpec,\n collections: ReadonlySet<string>,\n plainTables: ReadonlySet<string>,\n): unknown {\n const where = `Relation '${name}.${field}'`\n if (!collections.has(spec.target)) {\n throw new ConfigError(\n `${where} targets '${spec.target}', which is not a collection of this config`,\n )\n }\n const source = r[name]!\n const target = r[spec.target]!\n const from = source[spec.from]\n const to = target[spec.to]\n if (from === undefined) {\n throw new ConfigError(`${where}: collection '${name}' has no column '${spec.from}'`)\n }\n if (to === undefined) {\n throw new ConfigError(`${where}: collection '${spec.target}' has no column '${spec.to}'`)\n }\n if (spec.kind === 'one') return r.one[spec.target]!({ from, to, optional: spec.optional })\n const through = spec.through\n if (through === undefined) return r.many[spec.target]!({ from, to })\n if (!plainTables.has(through.table)) {\n throw new ConfigError(\n `${where} goes through '${through.table}', which is not in the config's tables (a collection cannot be the join: its rules would be bypassed)`,\n )\n }\n const join = r[through.table]!\n const joinFrom = join[through.from]\n const joinTo = join[through.to]\n if (joinFrom === undefined || joinTo === undefined) {\n throw new ConfigError(\n `${where}: table '${through.table}' has no column '${joinFrom === undefined ? through.from : through.to}'`,\n )\n }\n return r.many[spec.target]!({ from: from.through(joinFrom), to: to.through(joinTo) })\n}\n\nexport function defineConfig<\n S extends AnySetup = DefaultSetup,\n const Cs extends readonly AnyCollection[] = readonly [],\n TCtx extends object = {},\n const Tb extends ConfigTables = {},\n>(\n options: ConfigOptions<S, Cs, TCtx, Tb>,\n): TypionConfig<ConfigTypes<TCtx, S['~plugins'], ByName<Cs>, Tb>>\nexport function defineConfig(\n options: ConfigOptions<AnySetup, readonly AnyCollection[], object, ConfigTables>,\n): TypionConfig<any> {\n const plugins = (options.setup ?? defaultSetup())['~plugins']\n const ids = new Set(plugins.map((plugin) => plugin.id))\n\n const collections: Record<string, AnyCollection> = {}\n const tables: Record<string, PgTable | PgEnum<any>> = {}\n for (const entry of options.collections) {\n if (entry.name in collections) {\n throw new ConfigError(`Collection '${entry.name}' is listed twice`)\n }\n collections[entry.name] = entry\n const table = buildCollectionTable(plugins, entry)\n tables[entry.name] = table\n // A tenant collection with no partition to keep it would read every tenant's rows: it fails closed here.\n const tenant = entry['~runtime'].structure.tenant\n if (tenant !== undefined && tenant !== false && !ids.has('multiTenant')) {\n throw new ConfigError(\n `Collection '${entry.name}' belongs to a tenant, and the setup configures no multi-tenancy (defineSetup({ multiTenant }))`,\n )\n }\n if (!ids.has('localization')) {\n for (const [key, column] of Object.entries(getTableColumns(table))) {\n if (readColumnKind(column) === localizedKind.id) {\n throw new ConfigError(\n `Collection '${entry.name}': column '${key}' is localized, and the setup configures no localization (defineSetup({ localization }))`,\n )\n }\n }\n }\n }\n const plainTables = new Set<string>()\n for (const [key, value] of Object.entries(options.tables ?? {})) {\n if (key in collections) {\n throw new ConfigError(`tables.${key} has the name of a collection`)\n }\n tables[key] = value\n if (is(value, PgTable)) plainTables.add(key)\n }\n const listed = new Set(Object.values(tables))\n for (const [found, enumName] of enumsOf(\n Object.values(tables).filter((value): value is PgTable => is(value, PgTable)),\n )) {\n if (listed.has(found)) continue\n if (enumName in tables) {\n throw new ConfigError(\n `Enum '${enumName}' is used by a column, and the config already has a table or an enum under that key`,\n )\n }\n tables[enumName] = found\n }\n\n const names = new Set(Object.keys(collections))\n\n // The chain is the internal API this layer compiles to; its generics are of no use here.\n const blueprint = (\n defineEngine<object>({\n maxLimit: options.maxLimit,\n validation: options.validation,\n }) as any\n )\n .tables(tables)\n .plugins(plugins)\n .relations((r: LooseRelationsBuilder) => {\n const config: Record<string, Record<string, unknown>> = {}\n for (const [name, entry] of Object.entries(collections)) {\n const record: Record<string, unknown> = {}\n for (const [field, spec] of Object.entries(entry['~runtime'].relations)) {\n record[field] = relationConfig(r, name, field, spec, names, plainTables)\n }\n config[name] = record\n }\n return config\n })\n\n const entities: Record<string, unknown> = {}\n for (const [name, entry] of Object.entries(collections)) {\n entities[name] = blueprint.entity(name, collectionEntityOptions(plugins, entry))\n }\n const definition = blueprint.entities(entities) as TypionDefinition<any>\n return {\n definition,\n schema: definition.schema,\n db: options.db,\n context: options.context,\n migrations: options.migrations,\n seed: options.seed,\n onAfterCommitError: options.onAfterCommitError,\n checkSchema: options.checkSchema,\n }\n}\n","import type { AnyRelations } from 'drizzle-orm'\nimport type { PgAsyncDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport type { DbAdapter } from '../types/collection.js'\n\n// Wraps any Drizzle instance: `dbAdapter((relations) => drizzle(process.env.DATABASE_URL!, { relations }))`.\n// The connection is opened on the first `getTypion`, not when the config module is imported, so drizzle-kit\n// and the CLI can read the config without a database.\nexport function dbAdapter(\n connect: (relations: AnyRelations) => PgAsyncDatabase<PgQueryResultHKT, any>,\n options: { close?: () => Promise<void>; url?: string } = {},\n): DbAdapter {\n return {\n connect,\n // `url: process.env.DATABASE_URL` given and empty would otherwise reach the driver, whose defaults (the system\n // user, a local socket) fail with a message about something else.\n check: () => {\n if ('url' in options && (options.url === undefined || options.url === '')) {\n throw new ConfigError(\n \"The config's database url is empty: set the variable it reads (DATABASE_URL?) in the environment or in .env\",\n )\n }\n },\n ...(options.close === undefined ? {} : { close: options.close }),\n // `url` is what `typion db studio` opens; without it the command says so instead of guessing.\n ...(options.url === undefined ? {} : { credentials: () => ({ url: options.url }) }),\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ //#region src/validation/issues.ts
2
+ function normalizePath(path) {
3
+ if (path === void 0) return [];
4
+ return path.map((segment) => typeof segment === "object" && segment !== null ? segment.key : segment);
5
+ }
6
+ function normalizeIssues(issues) {
7
+ return issues.map((issue) => ({
8
+ path: normalizePath(issue.path),
9
+ message: issue.message
10
+ }));
11
+ }
12
+ function prefixIssues(issues, prefix) {
13
+ return issues.map((issue) => ({
14
+ message: issue.message,
15
+ path: [...prefix, ...normalizePath(issue.path)]
16
+ }));
17
+ }
18
+ function issueAt(message, path = []) {
19
+ return {
20
+ message,
21
+ path: [...path]
22
+ };
23
+ }
24
+ function isStandardSchema(value) {
25
+ return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"]?.validate === "function";
26
+ }
27
+ function isPromiseLike(value) {
28
+ return typeof value?.then === "function";
29
+ }
30
+ function runStandard(schema, value) {
31
+ const result = schema["~standard"].validate(value);
32
+ if (isPromiseLike(result)) return Promise.resolve(result).then(normalizeResult);
33
+ return normalizeResult(result);
34
+ }
35
+ function normalizeResult(result) {
36
+ if (result.issues === void 0) return result;
37
+ return { issues: normalizeIssues(result.issues) };
38
+ }
39
+ //#endregion
40
+ export { prefixIssues as a, normalizeIssues as i, isStandardSchema as n, runStandard as o, issueAt as r, isPromiseLike as t };
41
+
42
+ //# sourceMappingURL=issues-DLqCBQT1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issues-DLqCBQT1.js","names":[],"sources":["../src/validation/issues.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport type { ValidationIssue } from '../errors.js'\n\nexport type IssuePath = StandardSchemaV1.Issue['path']\n\nexport function normalizePath(path: IssuePath | undefined): PropertyKey[] {\n if (path === undefined) return []\n return path.map((segment) =>\n typeof segment === 'object' && segment !== null ? segment.key : segment,\n )\n}\n\nexport function normalizeIssues(issues: readonly StandardSchemaV1.Issue[]): ValidationIssue[] {\n return issues.map((issue) => ({ path: normalizePath(issue.path), message: issue.message }))\n}\n\nexport function prefixIssues(\n issues: readonly StandardSchemaV1.Issue[],\n prefix: readonly PropertyKey[],\n): StandardSchemaV1.Issue[] {\n return issues.map((issue) => ({\n message: issue.message,\n path: [...prefix, ...normalizePath(issue.path)],\n }))\n}\n\nexport function issueAt(\n message: string,\n path: readonly PropertyKey[] = [],\n): StandardSchemaV1.Issue {\n return { message, path: [...path] }\n}\n\nexport function isStandardSchema(value: unknown): value is StandardSchemaV1 {\n return (\n typeof value === 'object' &&\n value !== null &&\n '~standard' in value &&\n typeof (value as { '~standard'?: { validate?: unknown } })['~standard']?.validate === 'function'\n )\n}\n\nexport function isPromiseLike<T>(value: T | PromiseLike<T>): value is PromiseLike<T> {\n return typeof (value as { then?: unknown } | null)?.then === 'function'\n}\n\n// Runs a Standard Schema and hands back normalized issues; the async branch only exists because the\n// spec allows `validate` to return a promise, so a synchronous caller keeps a synchronous result.\nexport function runStandard(\n schema: StandardSchemaV1,\n value: unknown,\n): StandardSchemaV1.Result<unknown> | Promise<StandardSchemaV1.Result<unknown>> {\n const result = schema['~standard'].validate(value)\n if (isPromiseLike(result)) return Promise.resolve(result).then(normalizeResult)\n return normalizeResult(result)\n}\n\nfunction normalizeResult(\n result: StandardSchemaV1.Result<unknown>,\n): StandardSchemaV1.Result<unknown> {\n if (result.issues === undefined) return result\n return { issues: normalizeIssues(result.issues) }\n}\n"],"mappings":";AAKA,SAAgB,cAAc,MAA4C;CACxE,IAAI,SAAS,KAAA,GAAW,OAAO,CAAC;CAChC,OAAO,KAAK,KAAK,YACf,OAAO,YAAY,YAAY,YAAY,OAAO,QAAQ,MAAM,OAClE;AACF;AAEA,SAAgB,gBAAgB,QAA8D;CAC5F,OAAO,OAAO,KAAK,WAAW;EAAE,MAAM,cAAc,MAAM,IAAI;EAAG,SAAS,MAAM;CAAQ,EAAE;AAC5F;AAEA,SAAgB,aACd,QACA,QAC0B;CAC1B,OAAO,OAAO,KAAK,WAAW;EAC5B,SAAS,MAAM;EACf,MAAM,CAAC,GAAG,QAAQ,GAAG,cAAc,MAAM,IAAI,CAAC;CAChD,EAAE;AACJ;AAEA,SAAgB,QACd,SACA,OAA+B,CAAC,GACR;CACxB,OAAO;EAAE;EAAS,MAAM,CAAC,GAAG,IAAI;CAAE;AACpC;AAEA,SAAgB,iBAAiB,OAA2C;CAC1E,OACE,OAAO,UAAU,YACjB,UAAU,QACV,eAAe,SACf,OAAQ,MAAmD,YAAY,EAAE,aAAa;AAE1F;AAEA,SAAgB,cAAiB,OAAoD;CACnF,OAAO,OAAQ,OAAqC,SAAS;AAC/D;AAIA,SAAgB,YACd,QACA,OAC8E;CAC9E,MAAM,SAAS,OAAO,YAAY,CAAC,SAAS,KAAK;CACjD,IAAI,cAAc,MAAM,GAAG,OAAO,QAAQ,QAAQ,MAAM,CAAC,CAAC,KAAK,eAAe;CAC9E,OAAO,gBAAgB,MAAM;AAC/B;AAEA,SAAS,gBACP,QACkC;CAClC,IAAI,OAAO,WAAW,KAAA,GAAW,OAAO;CACxC,OAAO,EAAE,QAAQ,gBAAgB,OAAO,MAAM,EAAE;AAClD"}
@@ -0,0 +1,8 @@
1
+ import { Jt as HandlerOptionsOf, ba as PluginContextOptions, fn as TypionAppOf, pn as TypionConfig, un as TypesOf } from "../context-B4e2eREP.js";
2
+ import { t as RouteHandlers } from "../handler-BWVU8TCR.js";
3
+ //#region src/next/index.d.ts
4
+ type ContextOptionsOf<C> = PluginContextOptions<TypesOf<C>['plugins']>;
5
+ export declare function getApp<const C extends TypionConfig<any>>(config: C, options?: ContextOptionsOf<C>): Promise<TypionAppOf<C>>;
6
+ export declare function routeHandlers<const C extends TypionConfig<any>>(config: C, options: HandlerOptionsOf<C>): Promise<RouteHandlers>;
7
+ //#endregion
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ import { n as getTypion } from "../typion-Dh2BCSRz.js";
2
+ import { n as toRouteHandlers, t as createHandler } from "../handler-_87bFkbP.js";
3
+ import "../http/index.js";
4
+ import { headers } from "next/headers";
5
+ import { connection } from "next/server";
6
+ //#region src/next/index.ts
7
+ async function getApp(config, options = {}) {
8
+ await connection();
9
+ return await (await getTypion(config)).$fromHeaders(await headers(), options);
10
+ }
11
+ async function routeHandlers(config, options) {
12
+ const typion = await getTypion(config);
13
+ return toRouteHandlers(createHandler(typion, options));
14
+ }
15
+ //#endregion
16
+ export { getApp, routeHandlers };
17
+
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/next/index.ts"],"sourcesContent":["import { headers } from 'next/headers'\nimport { connection } from 'next/server'\nimport { createHandler, toRouteHandlers } from '../http/index.js'\nimport { getTypion } from '../runtime/typion.js'\nimport type { HandlerOptionsOf, TypesOf, TypionAppOf, TypionConfig } from '../types/collection.js'\nimport type { PluginContextOptions } from '../types/kinds.js'\n\ntype ContextOptionsOf<C> = PluginContextOptions<TypesOf<C>['plugins']>\n\n// The instance bound to the current request. Server components and server actions have no `Request`, so the\n// context factory of the config is given the headers Next resolves for them. `options` are the installed\n// plugins' binding options (`{ locale }` with localization).\nexport async function getApp<const C extends TypionConfig<any>>(\n config: C,\n options: ContextOptionsOf<C> = {} as ContextOptionsOf<C>,\n): Promise<TypionAppOf<C>> {\n // The caller is per request: with Cache Components on, a prerender stops here, before the instance reads the clock\n // to bind them, which Next refuses outside a request.\n await connection()\n const typion = await getTypion(config)\n return (await typion.$fromHeaders(await headers(), options as never)) as TypionAppOf<C>\n}\n\n// `export const { GET, POST, … } = await routeHandlers(config, { transports: [rest(), rpc()] })` in\n// app/api/[...path]/route.ts.\nexport async function routeHandlers<const C extends TypionConfig<any>>(\n config: C,\n options: HandlerOptionsOf<C>,\n) {\n const typion = await getTypion(config)\n return toRouteHandlers(createHandler(typion as never, options as never))\n}\n"],"mappings":";;;;;;AAYA,eAAsB,OACpB,QACA,UAA+B,CAAC,GACP;CAGzB,MAAM,WAAW;CAEjB,OAAQ,OAAM,MADO,UAAU,MAAM,EAAA,CAChB,aAAa,MAAM,QAAQ,GAAG,OAAgB;AACrE;AAIA,eAAsB,cACpB,QACA,SACA;CACA,MAAM,SAAS,MAAM,UAAU,MAAM;CACrC,OAAO,gBAAgB,cAAc,QAAiB,OAAgB,CAAC;AACzE"}