typion 0.1.0 → 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.
@@ -1,4 +1,4 @@
1
- import { Wt as ContextFactory, a as MaybePromise, n as ContextInput, on as SystemTypion } from "../context-CpLQy7OI.js";
1
+ import { Gt as ContextFactoryInput, N as AnyDb, Wt as ContextFactory, a as MaybePromise } from "../context-B4e2eREP.js";
2
2
  //#region src/auth/better-auth.d.ts
3
3
  export type SessionProvider = {
4
4
  api: {
@@ -8,8 +8,6 @@ export type SessionProvider = {
8
8
  };
9
9
  };
10
10
  export type SessionOf<TAuth extends SessionProvider> = Awaited<ReturnType<TAuth['api']['getSession']>>;
11
- export declare function betterAuthContext<TAuth extends SessionProvider, TCtx extends object>(auth: TAuth, map: (session: SessionOf<TAuth>, input: ContextInput & {
12
- system: SystemTypion;
13
- }) => MaybePromise<TCtx>): ContextFactory<TCtx>;
11
+ export declare function betterAuthContext<TAuth extends SessionProvider, TCtx extends object>(auth: TAuth | ((db: AnyDb) => TAuth), map: (session: SessionOf<TAuth>, input: ContextFactoryInput) => MaybePromise<TCtx>): ContextFactory<TCtx>;
14
12
  //#endregion
15
13
  //# sourceMappingURL=better-auth.d.ts.map
@@ -2,7 +2,7 @@
2
2
  function betterAuthContext(auth, map) {
3
3
  return async (input) => {
4
4
  const headers = input.headers ?? input.request?.headers ?? new Headers();
5
- return map(await auth.api.getSession({ headers }), input);
5
+ return map(await ("api" in auth ? auth : auth(input.db)).api.getSession({ headers }), input);
6
6
  };
7
7
  }
8
8
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"better-auth.js","names":[],"sources":["../../src/auth/better-auth.ts"],"sourcesContent":["import type { ContextInput, MaybePromise } from '../types/context.js'\nimport type { ContextFactory, SystemTypion } from '../types/collection.js'\n\n// Structural on purpose: the engine never imports better-auth, so any auth library exposing the same\n// `api.getSession({ headers })` shape works, and better-auth stays an optional peer.\nexport type SessionProvider = {\n api: { getSession(options: { headers: Headers }): Promise<unknown> }\n}\n\nexport type SessionOf<TAuth extends SessionProvider> = Awaited<\n ReturnType<TAuth['api']['getSession']>\n>\n\n// The library says who signed in; `map` says who that is to the application. It gets the factory's input with\n// `system`, which crosses tenants, so it can look the caller up: their membership, their role (auth.md).\nexport function betterAuthContext<TAuth extends SessionProvider, TCtx extends object>(\n auth: TAuth,\n map: (\n session: SessionOf<TAuth>,\n input: ContextInput & { system: SystemTypion },\n ) => MaybePromise<TCtx>,\n): ContextFactory<TCtx> {\n return async (input) => {\n const headers = input.headers ?? input.request?.headers ?? new Headers()\n const session = (await auth.api.getSession({ headers })) as SessionOf<TAuth>\n return map(session, input)\n }\n}\n"],"mappings":";AAeA,SAAgB,kBACd,MACA,KAIsB;CACtB,OAAO,OAAO,UAAU;EACtB,MAAM,UAAU,MAAM,WAAW,MAAM,SAAS,WAAW,IAAI,QAAQ;EAEvE,OAAO,IAAI,MADY,KAAK,IAAI,WAAW,EAAE,QAAQ,CAAC,GAClC,KAAK;CAC3B;AACF"}
1
+ {"version":3,"file":"better-auth.js","names":[],"sources":["../../src/auth/better-auth.ts"],"sourcesContent":["import type { MaybePromise } from '../types/context.js'\nimport type { ContextFactory, ContextFactoryInput } from '../types/collection.js'\nimport type { AnyDb } from '../types/runtime.js'\n\n// Structural on purpose: the engine never imports better-auth, so any auth library exposing the same\n// `api.getSession({ headers })` shape works, and better-auth stays an optional peer.\nexport type SessionProvider = {\n api: { getSession(options: { headers: Headers }): Promise<unknown> }\n}\n\nexport type SessionOf<TAuth extends SessionProvider> = Awaited<\n ReturnType<TAuth['api']['getSession']>\n>\n\n// The library says who signed in; `map` says who that is to the application. It gets the factory's input with\n// `system`, which crosses tenants, so it can look the caller up: their membership, their role (auth.md).\n// `auth` is the provider, or what builds it on the instance's connection: a provider per instance reads a test's\n// sessions from the test's database, and the config never has to reach the instance itself (ADR-092).\nexport function betterAuthContext<TAuth extends SessionProvider, TCtx extends object>(\n auth: TAuth | ((db: AnyDb) => TAuth),\n map: (session: SessionOf<TAuth>, input: ContextFactoryInput) => MaybePromise<TCtx>,\n): ContextFactory<TCtx> {\n return async (input) => {\n const headers = input.headers ?? input.request?.headers ?? new Headers()\n const provider = 'api' in auth ? (auth as TAuth) : auth(input.db)\n const session = (await provider.api.getSession({ headers })) as SessionOf<TAuth>\n return map(session, input)\n }\n}\n"],"mappings":";AAkBA,SAAgB,kBACd,MACA,KACsB;CACtB,OAAO,OAAO,UAAU;EACtB,MAAM,UAAU,MAAM,WAAW,MAAM,SAAS,WAAW,IAAI,QAAQ;EAGvE,OAAO,IAAI,OAFM,SAAS,OAAQ,OAAiB,KAAK,MAAM,EAAE,EAAA,CAChC,IAAI,WAAW,EAAE,QAAQ,CAAC,GACtC,KAAK;CAC3B;AACF"}
package/dist/cli/index.js CHANGED
@@ -281,7 +281,7 @@ async function seed(loaded, io, options) {
281
281
  }
282
282
  const file = findSeedFile(loaded, options.file);
283
283
  if (file === null) throw new CliError("No seed file found (typion/seed.ts). Write one, point at it with --file, or use --random.");
284
- const { getTypion } = await import("../typion-TJWDkHGh.js").then((n) => n.i);
284
+ const { getTypion } = await import("../typion-Dh2BCSRz.js").then((n) => n.i);
285
285
  const typion = await getTypion(loaded.config);
286
286
  const seedModule = await import(pathToFileURL(file).href);
287
287
  const run = seedModule.seed ?? seedModule.default;
@@ -404,6 +404,7 @@ function writeAgentNotes(root, io) {
404
404
  //#endregion
405
405
  //#region src/cli/init.ts
406
406
  const DRIZZLE = "1.0.0-rc.4";
407
+ const TRANSPORTS = ["@typion/rest", "@typion/rpc"];
407
408
  function packageManager(root) {
408
409
  if (existsSync(join(root, "pnpm-lock.yaml"))) return "pnpm";
409
410
  if (existsSync(join(root, "yarn.lock"))) return "yarn";
@@ -547,6 +548,57 @@ function allowTsImports(root, io) {
547
548
  writeFileSync(path, `${JSON.stringify(json, null, 2)}\n`);
548
549
  io.out(`Set ${flag} in tsconfig.json: Typion's imports end in .ts.`);
549
550
  }
551
+ function pnpmMajor(root) {
552
+ const declared = /^pnpm@(\d+)/.exec(String(readJson(join(root, "package.json"))?.packageManager));
553
+ const agent = /^pnpm\/(\d+)/.exec(process.env.npm_config_user_agent ?? "");
554
+ const version = declared?.[1] ?? agent?.[1] ?? /^(\d+)\./.exec(spawnSync("pnpm", ["--version"], {
555
+ cwd: root,
556
+ encoding: "utf8"
557
+ }).stdout ?? "")?.[1];
558
+ return version === void 0 ? null : Number(version);
559
+ }
560
+ function workspaceFile(root) {
561
+ for (let dir = root; dirname(dir) !== dir; dir = dirname(dir)) if (existsSync(join(dir, "pnpm-workspace.yaml"))) return join(dir, "pnpm-workspace.yaml");
562
+ return join(root, "pnpm-workspace.yaml");
563
+ }
564
+ function allowEsbuild(root, io) {
565
+ const major = pnpmMajor(root);
566
+ if (major === null || major < 11) return;
567
+ const path = workspaceFile(root);
568
+ const name = relative(process.cwd(), path);
569
+ const why = `pnpm ${major} fails an install on a build script it was not told to run, and drizzle-kit brings esbuild's`;
570
+ if (!existsSync(path)) {
571
+ writeFileSync(path, "allowBuilds:\n esbuild: true\n");
572
+ io.out(`Created ${name} to allow esbuild's build script: ${why}.`);
573
+ return;
574
+ }
575
+ const text = readFileSync(path, "utf8");
576
+ const eol = text.includes("\r\n") ? "\r\n" : "\n";
577
+ const lines = text.split(/\r?\n/);
578
+ const valueOf = (line) => line.slice(line.indexOf(":") + 1).replace(/(^|\s)#.*$/, "").trim();
579
+ const key = lines.findIndex((line) => /^allowBuilds\s*:/.test(line));
580
+ if (key === -1) {
581
+ if (lines.at(-1) === "") lines.pop();
582
+ lines.push(...lines.length === 0 ? [] : [""], "allowBuilds:", " esbuild: true", "");
583
+ } else if (valueOf(lines[key]) !== "") {
584
+ if (!/\besbuild\b/.test(lines[key])) io.out(`Add esbuild: true to allowBuilds in ${name}: ${why}.`);
585
+ return;
586
+ } else {
587
+ let end = key + 1;
588
+ while (end < lines.length && /^(\s|#|$)/.test(lines[end])) end++;
589
+ const block = lines.slice(key + 1, end);
590
+ const entry = block.findIndex((line) => /^\s+(['"]?)esbuild\1\s*:/.test(line));
591
+ if (entry === -1) {
592
+ const indent = block.map((line) => /^(\s+)[^\s#]/.exec(line)?.[1]).find(Boolean) ?? " ";
593
+ lines.splice(key + 1, 0, `${indent}esbuild: true`);
594
+ } else {
595
+ if (/^(true|false)$/i.test(valueOf(block[entry]))) return;
596
+ lines[key + 1 + entry] = `${/^\s+/.exec(block[entry])[0]}esbuild: true`;
597
+ }
598
+ }
599
+ writeFileSync(path, lines.join(eol));
600
+ io.out(`Set allowBuilds: esbuild: true in ${name}: ${why}.`);
601
+ }
550
602
  const ROUTE = `import { rest } from '@typion/rest'
551
603
  import { rpc } from '@typion/rpc'
552
604
  import { routeHandlers } from 'typion/next'
@@ -565,30 +617,34 @@ async function init(cwd, io, options) {
565
617
  allowTsImports(project.root, io);
566
618
  if (project.framework === "next" && project.appDir !== null) write(join(project.appDir, "api", "[...path]", "route.ts"), ROUTE, io);
567
619
  writeAgentNotes(project.root, io);
568
- await installDependencies(project, driver, io, options);
620
+ const manager = packageManager(project.root);
621
+ if (manager === "pnpm") allowEsbuild(project.root, io);
622
+ await installDependencies(project, manager, driver, io, options);
569
623
  io.out("");
570
624
  io.out("Next:");
571
625
  io.out(" 1. turn on what you need: `softDelete` or `versions` on a collection, `localization`, `multiTenant` or `plugins` in `defineSetup`");
572
626
  io.out(existsSync(join(project.root, "typion", "migrations")) ? " 2. `typion db migrate` to apply the migrations, then `typion db seed`" : " 2. `typion db push` to create the tables, then `typion db seed`");
573
627
  if (project.framework === "next") io.out(" 3. read from a server component with `const app = await getApp(config)` (typion/next)");
574
628
  if (project.framework === "hono") {
575
- io.out(" 3. mount the transports in your Hono app: `.all('/api/*', typionRoutes(config, { transports: [rest(), rpc()] }))` (typion/hono)");
576
- io.out(" 4. bind the caller in your own routes with `typionMiddleware(config)`: `c.var.typion`");
629
+ io.out(" 3. bind the caller in your own routes with `typionMiddleware(config)`: `c.var.typion`");
630
+ const transports = TRANSPORTS.filter((name) => !project.dependencies.has(name));
631
+ const add = installCommand(manager, transports, false);
632
+ const install = transports.length === 0 ? "" : `\`${add.command} ${add.args.join(" ")}\`, then `;
633
+ io.out(` 4. to serve the collections over HTTP: ${install}\`.all('/api/*', typionRoutes(config, { transports: [rest(), rpc()] }))\` (typion/hono)`);
577
634
  }
578
635
  }
579
- async function installDependencies(project, driver, io, options) {
636
+ async function installDependencies(project, manager, driver, io, options) {
580
637
  const deps = [
581
638
  "typion",
582
639
  "drizzle-orm",
583
640
  driver === "pglite" ? "@electric-sql/pglite" : "pg",
584
- ...project.framework === "none" ? [] : ["@typion/rest", "@typion/rpc"]
641
+ ...project.framework === "next" ? TRANSPORTS : []
585
642
  ];
586
643
  const dev = ["drizzle-kit"];
587
644
  const spec = (name) => name.startsWith("drizzle-") ? `${name}@${DRIZZLE}` : name;
588
645
  const missing = deps.filter((name) => !project.dependencies.has(name)).map(spec);
589
646
  const missingDev = dev.filter((name) => !project.dependencies.has(name)).map(spec);
590
647
  if (missing.length === 0 && missingDev.length === 0) return;
591
- const manager = packageManager(project.root);
592
648
  const lines = [...missing.length === 0 ? [] : [installCommand(manager, missing, false)], ...missingDev.length === 0 ? [] : [installCommand(manager, missingDev, true)]];
593
649
  io.out("");
594
650
  io.out("Missing packages:");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["run","db.push","db.generate","db.migrate","db.seed","db.status","db.studio"],"sources":["../../src/cli/output.ts","../../src/cli/config.ts","../../src/cli/db.ts","../../src/cli/agents.ts","../../src/cli/init.ts","../../src/cli/make.ts","../../src/cli/index.ts"],"sourcesContent":["// A failure the user can act on: the CLI prints its message without a stack.\nexport class CliError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'CliError'\n }\n}\n\nexport type Io = {\n out(line: string): void\n err(line: string): void\n}\n\nexport const consoleIo: Io = {\n out: (line) => console.log(line),\n err: (line) => console.error(line),\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport type { TypionConfig } from '../types/collection.js'\nimport { CliError } from './output.js'\n\nconst NAMES = ['typion.config.ts', 'typion.config.js', 'typion.config.mts', 'typion.config.mjs']\nconst DIRS = ['', 'src', 'app', 'config']\n\nexport type LoadedConfig = {\n readonly config: TypionConfig<any>\n readonly path: string\n readonly dir: string\n}\n\nexport function findConfig(cwd: string, given?: string): string {\n if (given !== undefined) {\n const path = isAbsolute(given) ? given : resolve(cwd, given)\n if (!existsSync(path)) throw new CliError(`No config at ${path}`)\n return path\n }\n let dir = resolve(cwd)\n for (;;) {\n for (const sub of DIRS) {\n for (const name of NAMES) {\n const candidate = join(dir, sub, name)\n if (existsSync(candidate)) return candidate\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n throw new CliError(\n `No typion.config.ts found from ${cwd}. Pass --config <path>, or run \\`typion init\\`.`,\n )\n}\n\n// Node runs TypeScript directly (type stripping), which covers a config written with relative imports. A\n// project whose config uses path aliases (`@/…`) needs jiti, so it is used when the project has it.\nasync function importConfig(path: string): Promise<Record<string, unknown>> {\n try {\n return await withoutTypelessWarning(\n async () => (await import(pathToFileURL(path).href)) as Record<string, unknown>,\n )\n } catch (error) {\n const jiti = await loadJiti(path)\n if (jiti === null) throw error\n return (await jiti.import(path, {})) as Record<string, unknown>\n }\n}\n\n// A project without `\"type\": \"module\"` (a Next.js app) makes Node warn, once per command, that it parsed the config\n// twice to find it is a module: true, and nothing the user can act on without changing how their app is built.\nasync function withoutTypelessWarning<T>(load: () => Promise<T>): Promise<T> {\n const emit = process.emitWarning\n process.emitWarning = ((warning: string | Error, ...rest: unknown[]) => {\n const code = (rest[0] as { code?: string } | undefined)?.code ?? rest[1]\n if (code === 'MODULE_TYPELESS_PACKAGE_JSON') return\n ;(emit as (...args: unknown[]) => void).call(process, warning, ...rest)\n }) as typeof process.emitWarning\n try {\n return await load()\n } finally {\n process.emitWarning = emit\n }\n}\n\ntype Jiti = { import(id: string, opts: object): unknown }\n\nasync function loadJiti(path: string): Promise<Jiti | null> {\n try {\n // Optional, and resolved through a variable so it is not a dependency of the build: a project whose\n // config needs path aliases usually has jiti already (drizzle-kit ships it).\n const id = 'jiti'\n const mod = (await import(id)) as { createJiti: (from: string, options?: object) => Jiti }\n return mod.createJiti(pathToFileURL(path).href, { interopDefault: true })\n } catch {\n return null\n }\n}\n\nfunction pickConfig(exports: Record<string, unknown>, path: string): TypionConfig<any> {\n const candidates = [exports.config, exports.default, ...Object.values(exports)]\n for (const value of candidates) {\n if (\n typeof value === 'object' &&\n value !== null &&\n 'definition' in value &&\n 'schema' in value &&\n typeof (value as { definition?: unknown }).definition === 'object'\n ) {\n return value as TypionConfig<any>\n }\n }\n throw new CliError(\n `${path} exports no Typion config (expected \\`export const config = defineConfig(…)\\`)`,\n )\n}\n\n// A config reads `process.env.DATABASE_URL`, and Next.js, Vite and drizzle-kit read `.env` files for it: the CLI does\n// too, `.env.local` first so that it wins, and never over what the shell already set.\nfunction loadEnv(dir: string): void {\n for (const name of ['.env.local', '.env']) {\n const path = join(dir, name)\n if (existsSync(path)) process.loadEnvFile(path)\n }\n}\n\nexport async function loadConfig(cwd: string, given?: string): Promise<LoadedConfig> {\n loadEnv(cwd)\n const path = findConfig(cwd, given)\n const exports = await importConfig(path)\n return { config: pickConfig(exports, path), path, dir: dirname(path) }\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { sql } from 'drizzle-orm'\nimport type { PgAsyncDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core'\nimport { getTableConfig, PgTable } from 'drizzle-orm/pg-core'\nimport { is } from 'drizzle-orm'\nimport type { LoadedConfig } from './config.js'\nimport { CliError, type Io } from './output.js'\n\nconst BREAKPOINT = '--> statement-breakpoint'\nconst DEFAULT_DIR = 'typion/migrations'\nconst DEFAULT_TABLE = 'typion_migrations'\n\ntype Journal = { version: 1; entries: { idx: number; tag: string; createdAt: string }[] }\n\ntype Api = typeof import('drizzle-kit/api-postgres')\n\nasync function api(): Promise<Api> {\n try {\n return (await import('drizzle-kit/api-postgres')) as Api\n } catch {\n throw new CliError(\n 'The database commands need drizzle-kit installed (`pnpm add -D drizzle-kit`)',\n )\n }\n}\n\nfunction schemaOf(loaded: LoadedConfig): Record<string, unknown> {\n return loaded.config.schema as Record<string, unknown>\n}\n\n// Migrations belong to the project, not to the folder the config happens to sit in, so they are resolved\n// from the nearest package.json above it.\nfunction projectRoot(loaded: LoadedConfig): string {\n let dir = loaded.dir\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return loaded.dir\n dir = parent\n }\n}\n\nfunction migrationsDir(loaded: LoadedConfig): string {\n const dir = loaded.config.migrations?.dir ?? DEFAULT_DIR\n return isAbsolute(dir) ? dir : resolve(projectRoot(loaded), dir)\n}\n\nfunction migrationsTable(loaded: LoadedConfig): { schema: string; table: string } {\n return {\n schema: loaded.config.migrations?.schema ?? 'public',\n table: loaded.config.migrations?.table ?? DEFAULT_TABLE,\n }\n}\n\nfunction readJournal(dir: string): Journal {\n try {\n return JSON.parse(readFileSync(join(dir, 'meta', 'journal.json'), 'utf8')) as Journal\n } catch {\n return { version: 1, entries: [] }\n }\n}\n\nfunction writeJournal(dir: string, journal: Journal): void {\n mkdirSync(join(dir, 'meta'), { recursive: true })\n writeFileSync(join(dir, 'meta', 'journal.json'), `${JSON.stringify(journal, null, 2)}\\n`)\n}\n\nfunction connect(loaded: LoadedConfig): PgAsyncDatabase<PgQueryResultHKT, any> {\n const adapter = loaded.config.db\n if (adapter === undefined) {\n throw new CliError('The config has no database adapter (`db` in defineConfig)')\n }\n adapter.check?.()\n return adapter.connect(loaded.config.definition.relations)\n}\n\nexport async function push(loaded: LoadedConfig, io: Io, options: { force?: boolean }) {\n const { pushSchema } = await api()\n const db = connect(loaded)\n const { sqlStatements, hints, apply } = await pushSchema(schemaOf(loaded), db as never)\n if (sqlStatements.length === 0) {\n io.out('The database already matches the config.')\n return\n }\n for (const statement of sqlStatements) io.out(statement)\n if (hints.length > 0) {\n for (const hint of hints) io.err(`! ${hint.hint}`)\n if (options.force !== true) {\n throw new CliError('These changes can lose data: run again with --force to apply them.')\n }\n }\n await apply()\n io.out(`Applied ${sqlStatements.length} statement(s).`)\n await loaded.config.db?.close?.()\n}\n\nexport async function generate(loaded: LoadedConfig, io: Io, options: { name?: string }) {\n const { generateDrizzleJson, generateMigration } = await api()\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n const last = journal.entries.at(-1)\n const previous =\n last === undefined\n ? await generateDrizzleJson({})\n : (JSON.parse(\n readFileSync(\n join(dir, 'meta', `${String(last.idx).padStart(4, '0')}_snapshot.json`),\n 'utf8',\n ),\n ) as Awaited<ReturnType<typeof generateDrizzleJson>>)\n const current = await generateDrizzleJson(schemaOf(loaded), previous.id)\n const statements = await generateMigration(previous, current)\n if (statements.length === 0) {\n io.out('No changes: the migrations already describe the config.')\n return\n }\n const idx = (last?.idx ?? -1) + 1\n const tag = `${String(idx).padStart(4, '0')}_${(options.name ?? 'change').replace(/[^a-z0-9_-]+/gi, '_')}`\n mkdirSync(join(dir, 'meta'), { recursive: true })\n writeFileSync(join(dir, `${tag}.sql`), `${statements.join(`\\n${BREAKPOINT}\\n`)}\\n`)\n writeFileSync(\n join(dir, 'meta', `${String(idx).padStart(4, '0')}_snapshot.json`),\n `${JSON.stringify(current, null, 2)}\\n`,\n )\n journal.entries.push({ idx, tag, createdAt: new Date().toISOString() })\n writeJournal(dir, journal)\n io.out(`Wrote ${tag}.sql with ${statements.length} statement(s).`)\n}\n\nasync function applied(\n db: PgAsyncDatabase<PgQueryResultHKT, any>,\n where: { schema: string; table: string },\n): Promise<Set<string>> {\n if (where.schema !== 'public') {\n await db.execute(sql.raw(`create schema if not exists \"${where.schema}\"`))\n }\n await db.execute(\n sql.raw(\n `create table if not exists \"${where.schema}\".\"${where.table}\" (` +\n 'tag text primary key, applied_at timestamptz not null default now())',\n ),\n )\n const rows = await db.execute(sql.raw(`select tag from \"${where.schema}\".\"${where.table}\"`))\n const list =\n (rows as unknown as { rows?: { tag: string }[] }).rows ?? (rows as unknown as { tag: string }[])\n return new Set(list.map((row) => row.tag))\n}\n\nexport async function migrate(loaded: LoadedConfig, io: Io) {\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n if (journal.entries.length === 0) {\n io.out('No migrations to apply: run `typion db generate` first.')\n return\n }\n const db = connect(loaded)\n const where = migrationsTable(loaded)\n const done = await applied(db, where)\n const pending = journal.entries.filter((entry) => !done.has(entry.tag))\n if (pending.length === 0) {\n io.out('The database is up to date.')\n await loaded.config.db?.close?.()\n return\n }\n for (const entry of pending) {\n const statements = readFileSync(join(dir, `${entry.tag}.sql`), 'utf8')\n .split(BREAKPOINT)\n .map((statement) => statement.trim())\n .filter((statement) => statement !== '')\n await db.transaction(async (tx) => {\n for (const statement of statements) await tx.execute(sql.raw(statement))\n await tx.execute(\n sql.raw(`insert into \"${where.schema}\".\"${where.table}\" (tag) values ('${entry.tag}')`),\n )\n })\n io.out(`Applied ${entry.tag} (${statements.length} statement(s)).`)\n }\n await loaded.config.db?.close?.()\n}\n\nconst SEED_FILES = ['typion/seed.ts', 'typion/seed.js', 'seed.ts', 'seed.js']\n\nfunction findSeedFile(loaded: LoadedConfig, given?: string): string | null {\n if (given !== undefined) {\n const path = isAbsolute(given) ? given : resolve(process.cwd(), given)\n if (!existsSync(path)) throw new CliError(`No seed file at ${path}`)\n return path\n }\n for (const dir of [projectRoot(loaded), loaded.dir]) {\n for (const name of SEED_FILES) {\n const candidate = join(dir, name)\n if (existsSync(candidate)) return candidate\n }\n }\n return null\n}\n\n// Two ways to fill a database, and they answer different needs: the project's own seed writes meaningful rows\n// through the engine (hooks, versions and validation included), `--random` asks drizzle-seed for plausible\n// ones straight into the tables.\nasync function anyRows(loaded: LoadedConfig): Promise<boolean> {\n const db = connect(loaded)\n for (const entity of Object.values(loaded.config.definition.entities)) {\n if (entity.owner !== 'user') continue\n const where = `\"${entity.pgSchema ?? 'public'}\".\"${entity.tableName}\"`\n const rows = await db.execute(sql.raw(`select 1 from ${where} limit 1`))\n const list = (rows as unknown as { rows?: unknown[] }).rows ?? (rows as unknown as unknown[])\n if (list.length > 0) return true\n }\n return false\n}\n\nexport async function seed(\n loaded: LoadedConfig,\n io: Io,\n options: {\n file?: string\n random?: boolean\n count?: number\n seed?: number\n reset?: boolean\n ifEmpty?: boolean\n },\n) {\n if (options.ifEmpty === true && (await anyRows(loaded))) {\n io.out('The collections already hold rows: nothing seeded.')\n await loaded.config.db?.close?.()\n return\n }\n const { resetTables, seedCollections } = await import('../seed/index.js')\n if (options.reset === true) {\n await resetTables(loaded.config)\n io.out('Emptied every table of the config.')\n }\n if (options.random === true) {\n await seedCollections(loaded.config, { count: options.count, seed: options.seed })\n io.out(`Seeded every collection with ${options.count ?? 10} rows.`)\n await loaded.config.db?.close?.()\n return\n }\n const file = findSeedFile(loaded, options.file)\n if (file === null) {\n throw new CliError(\n 'No seed file found (typion/seed.ts). Write one, point at it with --file, or use --random.',\n )\n }\n const { getTypion } = await import('../runtime/typion.js')\n const typion = await getTypion(loaded.config)\n const seedModule = (await import(pathToFileURL(file).href)) as Record<string, unknown>\n const run = (seedModule.seed ?? seedModule.default) as\n ((args: { typion: unknown; config: unknown }) => unknown) | undefined\n if (typeof run !== 'function') {\n throw new CliError(\n `${file} exports no seed function (\\`export async function seed({ typion })\\`)`,\n )\n }\n await run({ typion, config: loaded.config })\n io.out(`Ran ${file}.`)\n await loaded.config.db?.close?.()\n}\n\nexport async function status(loaded: LoadedConfig, io: Io) {\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n const db = connect(loaded)\n const done = await applied(db, migrationsTable(loaded))\n if (journal.entries.length === 0) io.out('No migrations yet.')\n for (const entry of journal.entries) {\n io.out(`${done.has(entry.tag) ? 'applied' : 'pending'} ${entry.tag}`)\n }\n const tables = Object.values(schemaOf(loaded)).filter((value) => is(value, PgTable)) as PgTable[]\n io.out(\n `${tables.length} table(s) in the config: ${tables.map((t) => getTableConfig(t).name).join(', ')}`,\n )\n await loaded.config.db?.close?.()\n}\n\nexport async function studio(loaded: LoadedConfig, io: Io, options: { port?: number }) {\n const { startStudioServer } = await api()\n const credentials = loaded.config.db?.credentials?.()\n if (credentials === undefined) {\n throw new CliError(\n 'This database adapter cannot open Studio: pass `url` to dbAdapter(), or use typion/db/pglite.',\n )\n }\n io.out(`Studio on https://local.drizzle.studio (port ${options.port ?? 4983})`)\n await startStudioServer(schemaOf(loaded), credentials as never, { port: options.port })\n}\n\nexport function listMigrations(dir: string): string[] {\n try {\n return readdirSync(dir).filter((name) => name.endsWith('.sql'))\n } catch {\n return []\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, relative } from 'node:path'\nimport type { Io } from './output.js'\n\n// Agents do not know Typion from training, so the application's agent notes carry the rules that must always hold\n// and point at the guide shipped with the installed version. The block is delimited so that it can be rewritten\n// without touching the rest of the file, the way Next.js maintains its own (`next dev`).\nexport const START_MARKER = '<!-- BEGIN:typion-agent-rules -->'\nexport const END_MARKER = '<!-- END:typion-agent-rules -->'\n\nexport const AGENT_RULES = `${START_MARKER}\n\n# Typion\n\nThis application's data layer is Typion, which is newer than your training data. Before you add or change a\ncollection, an access rule, a hook, a query or an API route, read \\`node_modules/typion/docs/README.md\\` (resolved\nfrom this file's directory) and the page it points to for the task.\n\n- Read and write the application's data through Typion, bound to the caller: \\`getApp(config)\\` on Next.js,\n \\`c.var.typion\\` on Hono, \\`typion.$fromRequest(request)\\` elsewhere, \\`typion.$as(ctx)\\`. Never through\n \\`typion.$db\\`, Drizzle or SQL: they skip the access rules, tenants, soft delete, drafts, hooks and the history.\n- \\`typion.$system({ reason })\\` skips the access rules: for seeds, jobs and webhooks, never to answer a user's\n request.\n- Authorization lives in each collection's \\`access\\` rules, deny by default, not in pages, routes or server\n actions.\n- Every schema change ships a migration: \\`typion db generate --name <change>\\`.\n\nThis block is written by \\`typion init\\`; run it again after upgrading Typion.\n\n${END_MARKER}`\n\nconst SKILL_MARKER =\n '<!-- Written by `typion init`, which rewrites it: keep project notes in AGENTS.md. -->'\n\nexport const SKILL = `---\nname: typion\ndescription: Use for any change to this application's data layer with Typion — collections, access rules, hooks, queries and descriptors, API routes, seeds, migrations, or tests that touch typion.config.ts or the typion/ folder next to it.\n---\n\n${SKILL_MARKER}\n\nTypion is newer than your training data. Its guide ships with the installed version, in \\`node_modules/typion/docs/\\`.\n\n1. Read \\`node_modules/typion/docs/README.md\\`: the model, the rules, where things go.\n2. Read the page for the task:\n - \\`collections.md\\`: a collection, its columns and relations, a many-to-many\n - \\`access.md\\`: who reads and writes what, hidden columns, what a caller sees\n - \\`auth.md\\`: signing in, who the caller is\n - \\`hooks.md\\`: reacting to writes\n - \\`queries.md\\`: reads, writes, descriptors, transactions, errors\n - \\`http.md\\`: Next.js pages and server actions, Hono, the routes, the browser client, business operations\n - \\`database.md\\`: drivers, migrations, seed\n - \\`testing.md\\`: tests\n - \\`features/\\`: localization, multi-tenancy, soft delete, versions and drafts\n3. Before you call the change done: \\`tsc\\` passes, every new collection has its rules, a test covers a caller the\n rules allow and one they refuse, and a schema change has its migration.\n`\n\ntype Outcome = 'created' | 'updated' | 'unchanged' | 'kept'\n\nfunction upsert(existing: string): string {\n const eol = existing.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const block = AGENT_RULES.replace(/\\n/g, eol)\n const start = existing.indexOf(START_MARKER)\n const end = existing.indexOf(END_MARKER, start)\n if (start !== -1 && end !== -1) {\n return existing.slice(0, start) + block + existing.slice(end + END_MARKER.length)\n }\n if (existing.length === 0) return `${block}${eol}`\n const body = existing.endsWith(eol) ? existing : `${existing}${eol}`\n return `${body}${eol}${block}${eol}`\n}\n\nfunction writeFile(path: string, next: string, previous: string | null): Outcome {\n if (previous === next) return 'unchanged'\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, next)\n return previous === null ? 'created' : 'updated'\n}\n\nfunction read(path: string): string | null {\n return existsSync(path) ? readFileSync(path, 'utf8') : null\n}\n\n// The block goes where the project keeps its notes: AGENTS.md, or CLAUDE.md when only that one exists; a project\n// with neither gets both, CLAUDE.md importing AGENTS.md. The skill is rewritten only while it is still Typion's.\nexport function writeAgentNotes(root: string, io: Io): void {\n const agentsPath = join(root, 'AGENTS.md')\n const claudePath = join(root, 'CLAUDE.md')\n const agents = read(agentsPath)\n const claude = read(claudePath)\n const report = (path: string, outcome: Outcome) => {\n const verb = { created: 'Created', updated: 'Updated', kept: 'Kept', unchanged: null }[outcome]\n if (verb !== null) io.out(`${verb} ${relative(process.cwd(), path)}.`)\n }\n\n const claudeHostsBlock = claude?.includes(START_MARKER) ?? false\n if (agents !== null && (agents.includes(START_MARKER) || !claudeHostsBlock)) {\n report(agentsPath, writeFile(agentsPath, upsert(agents), agents))\n } else if (claude !== null) {\n report(claudePath, writeFile(claudePath, upsert(claude), claude))\n } else {\n report(agentsPath, writeFile(agentsPath, upsert(''), null))\n report(claudePath, writeFile(claudePath, '@AGENTS.md\\n', null))\n }\n\n const skillPath = join(root, '.claude', 'skills', 'typion', 'SKILL.md')\n const skill = read(skillPath)\n if (skill !== null && !skill.includes(SKILL_MARKER)) {\n io.out(`Kept ${relative(process.cwd(), skillPath)} (it is not Typion's any more).`)\n } else {\n report(skillPath, writeFile(skillPath, SKILL, skill))\n }\n}\n","import { spawnSync } from 'node:child_process'\nimport { createInterface } from 'node:readline/promises'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, relative } from 'node:path'\nimport { writeAgentNotes } from './agents.js'\nimport { CliError, type Io } from './output.js'\n\ntype PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\n// npm's `latest` Drizzle is 0.x, and a later release candidate can break the engine (rc.5 does): the version the\n// engine is built on, which its `package.json` names as a peer.\nconst DRIZZLE = '1.0.0-rc.4'\n\nfunction packageManager(root: string): PackageManager {\n if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm'\n if (existsSync(join(root, 'yarn.lock'))) return 'yarn'\n if (existsSync(join(root, 'bun.lock')) || existsSync(join(root, 'bun.lockb'))) return 'bun'\n if (existsSync(join(root, 'package-lock.json'))) return 'npm'\n const agent = process.env.npm_config_user_agent ?? ''\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('bun')) return 'bun'\n if (agent.startsWith('pnpm')) return 'pnpm'\n return 'npm'\n}\n\nfunction installCommand(\n manager: PackageManager,\n packages: readonly string[],\n dev: boolean,\n): { command: string; args: string[] } {\n const flag = dev ? (manager === 'npm' ? '--save-dev' : '-D') : ''\n const verb = manager === 'npm' ? 'install' : 'add'\n return {\n command: manager,\n args: [verb, ...(flag === '' ? [] : [flag]), ...packages],\n }\n}\n\nasync function confirm(question: string, io: Io): Promise<boolean> {\n if (!process.stdin.isTTY) {\n io.out(`${question} — not a terminal, so nothing was installed. Re-run with --yes.`)\n return false\n }\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n try {\n const answer = (await rl.question(`${question} [Y/n] `)).trim().toLowerCase()\n return answer === '' || answer === 'y' || answer === 'yes'\n } finally {\n rl.close()\n }\n}\n\nfunction run(command: string, args: readonly string[], cwd: string, io: Io): void {\n io.out(`> ${command} ${args.join(' ')}`)\n const result = spawnSync(command, [...args], { cwd, stdio: 'inherit' })\n if (result.error !== undefined || (result.status !== null && result.status !== 0)) {\n throw new CliError(`\\`${command} ${args.join(' ')}\\` failed; install them yourself and re-run.`)\n }\n}\n\ntype Project = {\n readonly root: string\n readonly src: string\n readonly framework: 'next' | 'hono' | 'none'\n readonly dependencies: ReadonlySet<string>\n readonly appDir: string | null\n}\n\nfunction readJson(path: string): Record<string, any> | null {\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as Record<string, any>\n } catch {\n return null\n }\n}\n\nfunction inspect(cwd: string): Project {\n const pkg = readJson(join(cwd, 'package.json'))\n if (pkg === null) throw new CliError(`No package.json in ${cwd}: run this inside your project.`)\n const deps = { ...pkg.dependencies, ...pkg.devDependencies } as Record<string, string>\n const src = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd\n const appDir = [join(src, 'app'), join(cwd, 'app')].find((dir) => existsSync(dir)) ?? null\n return {\n root: cwd,\n src,\n framework: deps.next !== undefined ? 'next' : deps.hono !== undefined ? 'hono' : 'none',\n dependencies: new Set(Object.keys(deps)),\n appDir,\n }\n}\n\nfunction write(path: string, contents: string, io: Io): boolean {\n if (existsSync(path)) {\n io.out(`Kept ${relative(process.cwd(), path)} (it exists already).`)\n return false\n }\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, contents)\n io.out(`Created ${relative(process.cwd(), path)}.`)\n return true\n}\n\nconst COLLECTION = `import { text } from 'drizzle-orm/pg-core'\nimport { collection } from 'typion'\n\nexport const pages = collection('pages', {\n columns: {\n title: text().notNull(),\n slug: text().notNull().unique(),\n },\n public: true,\n})\n`\n\nfunction configFile(driver: 'pglite' | 'postgres'): string {\n const db =\n driver === 'pglite'\n ? ` db: pglite({ dataDir: '.pglite' }),`\n : ` db: dbAdapter((relations) => drizzle(process.env.DATABASE_URL!, { relations }), {\\n url: process.env.DATABASE_URL,\\n }),`\n const imports =\n driver === 'pglite'\n ? `import { defineConfig, defineSetup } from 'typion'\\nimport { pglite } from 'typion/db/pglite'`\n : `import { drizzle } from 'drizzle-orm/node-postgres'\\nimport { dbAdapter, defineConfig, defineSetup } from 'typion'`\n return `${imports}\nimport { pages } from './typion/collections/pages.ts'\n\n// What the application knows about a caller: rules, hooks and field rules read it. Registered below as well, since\n// field rules are typed before this config exists.\nexport type AppContext = {\n actorId: string | null\n}\n\n// A constant of its own: the collections read it to type their options and their columns, which happens before\n// this config exists. It takes the features (\\`localization\\`, \\`multiTenant\\`) and the plugins (\\`plugins: […]\\`).\nexport const setup = defineSetup({})\n\nexport const config = defineConfig({\n setup,\n collections: [pages],\n${db}\n // Who is calling. Return your own shape; declare the return type, the body may query \\`system\\`.\n context: async ({ headers }): Promise<AppContext> => {\n void headers\n return { actorId: null }\n },\n})\n\ndeclare module 'typion' {\n interface Register {\n setup: typeof setup\n config: typeof config\n context: AppContext\n }\n}\n`\n}\n\n// Every import Typion writes ends in `.ts`, as Node needs to load the config the way the CLI does. TypeScript takes\n// them with `allowImportingTsExtensions` where nothing is emitted (Next.js), and with\n// `rewriteRelativeImportExtensions` where `tsc` builds the project.\nfunction allowTsImports(root: string, io: Io): void {\n const path = join(root, 'tsconfig.json')\n if (!existsSync(path)) return\n const json = readJson(path)\n const options = (json?.compilerOptions ?? {}) as Record<string, unknown>\n if (\n options.allowImportingTsExtensions === true ||\n options.rewriteRelativeImportExtensions === true\n ) {\n return\n }\n const flag =\n options.noEmit === true ? 'allowImportingTsExtensions' : 'rewriteRelativeImportExtensions'\n if (json === null) {\n io.out(\n `Add \"${flag}\": true to the compilerOptions of tsconfig.json: Typion's imports end in .ts.`,\n )\n return\n }\n json.compilerOptions = { ...options, [flag]: true }\n writeFileSync(path, `${JSON.stringify(json, null, 2)}\\n`)\n io.out(`Set ${flag} in tsconfig.json: Typion's imports end in .ts.`)\n}\n\nconst ROUTE = `import { rest } from '@typion/rest'\nimport { rpc } from '@typion/rpc'\nimport { routeHandlers } from 'typion/next'\nimport { config } from '@/typion.config.ts'\n\n// What the app serves over HTTP: a resource per collection, and the endpoint the browser client posts to. Leave\n// out what you do not use.\nexport const { GET, POST, PATCH, PUT, DELETE, OPTIONS } = await routeHandlers(config, {\n transports: [rest(), rpc()],\n})\n`\n\nexport async function init(\n cwd: string,\n io: Io,\n options: { driver?: string; yes?: boolean; skipInstall?: boolean },\n): Promise<void> {\n const project = inspect(cwd)\n const driver = options.driver === 'postgres' ? 'postgres' : 'pglite'\n\n // The sample collection comes with a new config only: a run after an upgrade refreshes the notes and leaves the\n // project's collections as they are.\n if (write(join(project.src, 'typion.config.ts'), configFile(driver), io)) {\n write(join(project.src, 'typion', 'collections', 'pages.ts'), COLLECTION, io)\n }\n allowTsImports(project.root, io)\n\n if (project.framework === 'next' && project.appDir !== null) {\n write(join(project.appDir, 'api', '[...path]', 'route.ts'), ROUTE, io)\n }\n writeAgentNotes(project.root, io)\n\n await installDependencies(project, driver, io, options)\n\n io.out('')\n io.out('Next:')\n io.out(\n ' 1. turn on what you need: `softDelete` or `versions` on a collection, `localization`, `multiTenant` or `plugins` in `defineSetup`',\n )\n io.out(\n existsSync(join(project.root, 'typion', 'migrations'))\n ? ' 2. `typion db migrate` to apply the migrations, then `typion db seed`'\n : ' 2. `typion db push` to create the tables, then `typion db seed`',\n )\n if (project.framework === 'next') {\n io.out(\n ' 3. read from a server component with `const app = await getApp(config)` (typion/next)',\n )\n }\n // The app's entry is the developer's own file: what to add to it is said, not written.\n if (project.framework === 'hono') {\n io.out(\n \" 3. mount the transports in your Hono app: `.all('/api/*', typionRoutes(config, { transports: [rest(), rpc()] }))` (typion/hono)\",\n )\n io.out(\n ' 4. bind the caller in your own routes with `typionMiddleware(config)`: `c.var.typion`',\n )\n }\n}\n\nasync function installDependencies(\n project: Project,\n driver: 'pglite' | 'postgres',\n io: Io,\n options: { yes?: boolean; skipInstall?: boolean },\n): Promise<void> {\n const deps = [\n 'typion',\n 'drizzle-orm',\n driver === 'pglite' ? '@electric-sql/pglite' : 'pg',\n ...(project.framework === 'none' ? [] : ['@typion/rest', '@typion/rpc']),\n ]\n const dev = ['drizzle-kit']\n const spec = (name: string) => (name.startsWith('drizzle-') ? `${name}@${DRIZZLE}` : name)\n const missing = deps.filter((name) => !project.dependencies.has(name)).map(spec)\n const missingDev = dev.filter((name) => !project.dependencies.has(name)).map(spec)\n if (missing.length === 0 && missingDev.length === 0) return\n\n const manager = packageManager(project.root)\n const lines = [\n ...(missing.length === 0 ? [] : [installCommand(manager, missing, false)]),\n ...(missingDev.length === 0 ? [] : [installCommand(manager, missingDev, true)]),\n ]\n io.out('')\n io.out('Missing packages:')\n for (const line of lines) io.out(` ${line.command} ${line.args.join(' ')}`)\n\n if (options.skipInstall === true) return\n const ok = options.yes === true || (await confirm(`Install them with ${manager}?`, io))\n if (!ok) return\n for (const line of lines) run(line.command, line.args, project.root, io)\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport type { LoadedConfig } from './config.js'\nimport { CliError, type Io } from './output.js'\n\nfunction pascal(name: string): string {\n return name.replace(/(^|[-_ ])(\\w)/g, (_, __, char: string) => char.toUpperCase())\n}\n\nfunction camel(name: string): string {\n const upper = pascal(name)\n return upper.charAt(0).toLowerCase() + upper.slice(1)\n}\n\n// Where the collections of this project live: next to the ones already there, else beside the config.\nfunction collectionsDir(loaded: LoadedConfig, given?: string): string {\n if (given !== undefined) return isAbsolute(given) ? given : resolve(process.cwd(), given)\n const candidates = [join(loaded.dir, 'typion', 'collections'), join(loaded.dir, 'collections')]\n return candidates.find((dir) => existsSync(dir)) ?? candidates[0]!\n}\n\n// No rule is written for the developer: a generated `read: true` would serve every row to anyone, anonymous callers\n// included, until someone noticed. In a multi-tenant application the rows belong to the caller's tenant.\nfunction template(name: string, tenant: boolean): string {\n return `import { text } from 'drizzle-orm/pg-core'\nimport { collection } from 'typion'\n\nexport const ${camel(name)} = collection('${camel(name)}', {\n columns: {\n // Plain Drizzle columns; the features and plugins add their own options next to \\`columns\\`.\n title: text().notNull(),\n },${tenant ? '\\n tenant: true,' : ''}\n}).define({\n // Deny by default: an operation without a rule is refused. Give each one the rule it needs, for example\n // \\`read: ({ ctx }) => ctx.actorId !== null\\`.\n access: {},\n})\n`\n}\n\nfunction importPath(from: string, to: string): string {\n const path = relative(from, to).replaceAll('\\\\', '/')\n return path.startsWith('.') ? path : `./${path}`\n}\n\n// Best effort: adds the import and the entry to `collections: [...]`. When the config does not match the\n// shape the CLI understands, it prints the two lines instead of guessing.\nfunction register(loaded: LoadedConfig, name: string, file: string, io: Io): void {\n const source = readFileSync(loaded.path, 'utf8')\n const specifier = importPath(loaded.dir, file).replace(/\\.ts$/, '.ts')\n const line = `import { ${camel(name)} } from '${specifier}'`\n const list = /collections:\\s*\\[([^\\]]*)\\]/.exec(source)\n if (source.includes(line) || list === null) {\n io.out('Add it to the config:')\n io.out(` ${line}`)\n io.out(` collections: [ …, ${camel(name)} ]`)\n return\n }\n const entries = list[1]!.trim()\n const updated = source\n .replace(/(^import .*\\n)(?![\\s\\S]*^import )/m, `$1${line}\\n`)\n .replace(\n /collections:\\s*\\[([^\\]]*)\\]/,\n `collections: [${entries === '' ? '' : `${entries.replace(/,\\s*$/, '')}, `}${camel(name)}]`,\n )\n writeFileSync(loaded.path, updated)\n io.out(`Registered it in ${relative(process.cwd(), loaded.path)}.`)\n}\n\nfunction pluginTemplate(name: string): string {\n const id = camel(name)\n const Kinds = `${pascal(name)}Kinds`\n const Options = `${pascal(name)}Options`\n return `import { definePlugin } from 'typion'\nimport type { CollectionKinds } from 'typion'\n\n// What this plugin adds to every collection. A collection that does not set the option gets nothing.\nexport type ${Options} = { ${id}?: boolean }\n\n// How the option turns into columns and into engine options, read from \\`this['options']\\`.\ninterface ${Kinds} extends CollectionKinds {\n readonly columns: this['options'] extends { ${id}: true } ? {} : {}\n readonly entity: this['options'] extends { ${id}: true } ? {} : {}\n}\n\nexport function ${id}() {\n return definePlugin({\n id: '${id}',\n collection: {\n $options: {} as ${Options},\n $kinds: {} as ${Kinds},\n // Option keys this plugin reads, so they never reach the engine as entity options.\n consumes: ['${id}'],\n columns: (options) => (options.${id} === true ? {} : {}),\n entity: (options) => (options.${id} === true ? {} : {}),\n },\n // Tables, relations, entities, hooks, api, routes, errors and context go here too; see @typion/audit.\n })\n}\n`\n}\n\nexport function makePlugin(\n loaded: LoadedConfig,\n io: Io,\n name: string,\n options: { dir?: string },\n): void {\n if (!/^[a-z][a-z0-9_-]*$/i.test(name)) {\n throw new CliError(`'${name}' is not a plugin name (letters, digits, dash, underscore)`)\n }\n const dir =\n options.dir === undefined\n ? join(loaded.dir, 'typion', 'plugins')\n : isAbsolute(options.dir)\n ? options.dir\n : resolve(process.cwd(), options.dir)\n const file = join(dir, `${camel(name)}.ts`)\n if (existsSync(file)) throw new CliError(`${relative(process.cwd(), file)} already exists`)\n mkdirSync(dir, { recursive: true })\n writeFileSync(file, pluginTemplate(name))\n io.out(`Created ${relative(process.cwd(), file)}.`)\n io.out('Install it in the config:')\n io.out(` import { ${camel(name)} } from './${relative(loaded.dir, file).replaceAll('\\\\', '/')}'`)\n io.out(` export const setup = defineSetup({ plugins: [ …, ${camel(name)}() ] })`)\n}\n\nexport function makeCollection(\n loaded: LoadedConfig,\n io: Io,\n name: string,\n options: { dir?: string },\n): void {\n if (!/^[a-z][a-z0-9_-]*$/i.test(name)) {\n throw new CliError(`'${name}' is not a collection name (letters, digits, dash, underscore)`)\n }\n const dir = collectionsDir(loaded, options.dir)\n const file = join(dir, `${camel(name)}.ts`)\n if (existsSync(file)) throw new CliError(`${relative(process.cwd(), file)} already exists`)\n mkdirSync(dirname(file), { recursive: true })\n const tenant = loaded.config.definition.plugins.some((plugin) => plugin.id === 'multiTenant')\n writeFileSync(file, template(name, tenant))\n io.out(`Created ${relative(process.cwd(), file)}.`)\n register(loaded, name, file, io)\n io.out('Then `typion db push` (or `typion db generate` + `typion db migrate`).')\n}\n","import { parseArgs } from 'node:util'\nimport { ConfigError } from '../errors.js'\nimport { loadConfig } from './config.js'\nimport * as db from './db.js'\nimport { init } from './init.js'\nimport { makeCollection, makePlugin } from './make.js'\nimport { CliError, consoleIo, type Io } from './output.js'\n\nconst HELP = `typion — the CLI of a Typion project\n\nUsage\n typion <group> <command> [options]\n\nDatabase (everything that touches the schema, through drizzle-kit)\n typion db push [--force] make the database match the config (development)\n typion db generate [--name x] write the SQL of what changed, with its snapshot\n typion db migrate apply the migrations the database has not applied\n typion db seed [--file path] run the project's seed through the engine\n [--random] ask drizzle-seed for rows instead (--count, --seed)\n [--reset] empty every table of the config first\n [--if-empty] do nothing when a collection already holds rows\n typion db status what is applied, what is pending\n typion db studio [--port n] open Drizzle Studio on this config\n\nProject\n typion make collection <name> [--dir path] a new collection, registered in the config\n typion make plugin <name> [--dir path] a plugin skeleton for this project\n typion init [--driver pglite|postgres] [--yes] [--skip-install]\n set Typion up in a project that exists, with the\n notes its agents read (run it again after upgrading)\n\nOptions\n --config <path> the config to read; by default the nearest typion.config.ts\n --help this text (also: typion db --help)\n`\n\nconst DB_HELP = `typion db — the database of a Typion config\n\n push [--force] make the database match the config (development)\n generate [--name x] write the SQL of what changed, with its snapshot\n migrate apply the migrations the database has not applied\n seed [--file|--random] fill the database: the project's seed, or drizzle-seed rows\n status what is applied, what is pending\n studio [--port n] open Drizzle Studio on this config\n`\n\nconst OPTIONS = {\n config: { type: 'string' },\n name: { type: 'string' },\n dir: { type: 'string' },\n driver: { type: 'string' },\n port: { type: 'string' },\n file: { type: 'string' },\n count: { type: 'string' },\n seed: { type: 'string' },\n force: { type: 'boolean' },\n random: { type: 'boolean' },\n reset: { type: 'boolean' },\n 'if-empty': { type: 'boolean' },\n 'skip-install': { type: 'boolean' },\n yes: { type: 'boolean' },\n help: { type: 'boolean' },\n} as const\n\nfunction port(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined\n if (!/^\\d+$/.test(raw)) throw new CliError('--port must be a number')\n return Number(raw)\n}\n\nexport async function run(argv: readonly string[], io: Io = consoleIo, cwd = process.cwd()) {\n const { values, positionals } = parseArgs({\n args: [...argv],\n options: OPTIONS,\n allowPositionals: true,\n strict: true,\n })\n const [group, command, argument] = positionals\n\n if (group === undefined || values.help === true) {\n io.out(group === 'db' ? DB_HELP : HELP)\n return\n }\n\n const config = async () => loadConfig(cwd, values.config)\n\n switch (`${group} ${command ?? ''}`.trim()) {\n case 'db push':\n return db.push(await config(), io, { force: values.force })\n case 'db generate':\n return db.generate(await config(), io, { name: values.name })\n case 'db migrate':\n return db.migrate(await config(), io)\n case 'db seed':\n return db.seed(await config(), io, {\n file: values.file,\n random: values.random,\n count: values.count === undefined ? undefined : Number(values.count),\n seed: values.seed === undefined ? undefined : Number(values.seed),\n reset: values.reset,\n ifEmpty: values['if-empty'],\n })\n case 'db status':\n return db.status(await config(), io)\n case 'db studio':\n return db.studio(await config(), io, { port: port(values.port) })\n case 'db':\n io.out(DB_HELP)\n return\n case 'make collection': {\n if (argument === undefined) throw new CliError('Usage: typion make collection <name>')\n return makeCollection(await config(), io, argument, { dir: values.dir })\n }\n case 'make plugin': {\n if (argument === undefined) throw new CliError('Usage: typion make plugin <name>')\n return makePlugin(await config(), io, argument, { dir: values.dir })\n }\n case 'make':\n throw new CliError('Usage: typion make collection|plugin <name>')\n case 'init':\n return init(cwd, io, {\n driver: values.driver,\n yes: values.yes,\n skipInstall: values['skip-install'],\n })\n default:\n throw new CliError(\n `Unknown command '${[group, command].filter(Boolean).join(' ')}'. Try \\`typion --help\\`.`,\n )\n }\n}\n\nexport async function main(argv: readonly string[]): Promise<number> {\n try {\n await run(argv)\n return 0\n } catch (error) {\n // What the user has to change, in a sentence: a stack trace would bury it.\n if (error instanceof CliError || error instanceof ConfigError) {\n console.error(error.message)\n return 1\n }\n console.error(error)\n return 1\n }\n}\n\nexport { CliError }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["run","db.push","db.generate","db.migrate","db.seed","db.status","db.studio"],"sources":["../../src/cli/output.ts","../../src/cli/config.ts","../../src/cli/db.ts","../../src/cli/agents.ts","../../src/cli/init.ts","../../src/cli/make.ts","../../src/cli/index.ts"],"sourcesContent":["// A failure the user can act on: the CLI prints its message without a stack.\nexport class CliError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'CliError'\n }\n}\n\nexport type Io = {\n out(line: string): void\n err(line: string): void\n}\n\nexport const consoleIo: Io = {\n out: (line) => console.log(line),\n err: (line) => console.error(line),\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport type { TypionConfig } from '../types/collection.js'\nimport { CliError } from './output.js'\n\nconst NAMES = ['typion.config.ts', 'typion.config.js', 'typion.config.mts', 'typion.config.mjs']\nconst DIRS = ['', 'src', 'app', 'config']\n\nexport type LoadedConfig = {\n readonly config: TypionConfig<any>\n readonly path: string\n readonly dir: string\n}\n\nexport function findConfig(cwd: string, given?: string): string {\n if (given !== undefined) {\n const path = isAbsolute(given) ? given : resolve(cwd, given)\n if (!existsSync(path)) throw new CliError(`No config at ${path}`)\n return path\n }\n let dir = resolve(cwd)\n for (;;) {\n for (const sub of DIRS) {\n for (const name of NAMES) {\n const candidate = join(dir, sub, name)\n if (existsSync(candidate)) return candidate\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n throw new CliError(\n `No typion.config.ts found from ${cwd}. Pass --config <path>, or run \\`typion init\\`.`,\n )\n}\n\n// Node runs TypeScript directly (type stripping), which covers a config written with relative imports. A\n// project whose config uses path aliases (`@/…`) needs jiti, so it is used when the project has it.\nasync function importConfig(path: string): Promise<Record<string, unknown>> {\n try {\n return await withoutTypelessWarning(\n async () => (await import(pathToFileURL(path).href)) as Record<string, unknown>,\n )\n } catch (error) {\n const jiti = await loadJiti(path)\n if (jiti === null) throw error\n return (await jiti.import(path, {})) as Record<string, unknown>\n }\n}\n\n// A project without `\"type\": \"module\"` (a Next.js app) makes Node warn, once per command, that it parsed the config\n// twice to find it is a module: true, and nothing the user can act on without changing how their app is built.\nasync function withoutTypelessWarning<T>(load: () => Promise<T>): Promise<T> {\n const emit = process.emitWarning\n process.emitWarning = ((warning: string | Error, ...rest: unknown[]) => {\n const code = (rest[0] as { code?: string } | undefined)?.code ?? rest[1]\n if (code === 'MODULE_TYPELESS_PACKAGE_JSON') return\n ;(emit as (...args: unknown[]) => void).call(process, warning, ...rest)\n }) as typeof process.emitWarning\n try {\n return await load()\n } finally {\n process.emitWarning = emit\n }\n}\n\ntype Jiti = { import(id: string, opts: object): unknown }\n\nasync function loadJiti(path: string): Promise<Jiti | null> {\n try {\n // Optional, and resolved through a variable so it is not a dependency of the build: a project whose\n // config needs path aliases usually has jiti already (drizzle-kit ships it).\n const id = 'jiti'\n const mod = (await import(id)) as { createJiti: (from: string, options?: object) => Jiti }\n return mod.createJiti(pathToFileURL(path).href, { interopDefault: true })\n } catch {\n return null\n }\n}\n\nfunction pickConfig(exports: Record<string, unknown>, path: string): TypionConfig<any> {\n const candidates = [exports.config, exports.default, ...Object.values(exports)]\n for (const value of candidates) {\n if (\n typeof value === 'object' &&\n value !== null &&\n 'definition' in value &&\n 'schema' in value &&\n typeof (value as { definition?: unknown }).definition === 'object'\n ) {\n return value as TypionConfig<any>\n }\n }\n throw new CliError(\n `${path} exports no Typion config (expected \\`export const config = defineConfig(…)\\`)`,\n )\n}\n\n// A config reads `process.env.DATABASE_URL`, and Next.js, Vite and drizzle-kit read `.env` files for it: the CLI does\n// too, `.env.local` first so that it wins, and never over what the shell already set.\nfunction loadEnv(dir: string): void {\n for (const name of ['.env.local', '.env']) {\n const path = join(dir, name)\n if (existsSync(path)) process.loadEnvFile(path)\n }\n}\n\nexport async function loadConfig(cwd: string, given?: string): Promise<LoadedConfig> {\n loadEnv(cwd)\n const path = findConfig(cwd, given)\n const exports = await importConfig(path)\n return { config: pickConfig(exports, path), path, dir: dirname(path) }\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { sql } from 'drizzle-orm'\nimport type { PgAsyncDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core'\nimport { getTableConfig, PgTable } from 'drizzle-orm/pg-core'\nimport { is } from 'drizzle-orm'\nimport type { LoadedConfig } from './config.js'\nimport { CliError, type Io } from './output.js'\n\nconst BREAKPOINT = '--> statement-breakpoint'\nconst DEFAULT_DIR = 'typion/migrations'\nconst DEFAULT_TABLE = 'typion_migrations'\n\ntype Journal = { version: 1; entries: { idx: number; tag: string; createdAt: string }[] }\n\ntype Api = typeof import('drizzle-kit/api-postgres')\n\nasync function api(): Promise<Api> {\n try {\n return (await import('drizzle-kit/api-postgres')) as Api\n } catch {\n throw new CliError(\n 'The database commands need drizzle-kit installed (`pnpm add -D drizzle-kit`)',\n )\n }\n}\n\nfunction schemaOf(loaded: LoadedConfig): Record<string, unknown> {\n return loaded.config.schema as Record<string, unknown>\n}\n\n// Migrations belong to the project, not to the folder the config happens to sit in, so they are resolved\n// from the nearest package.json above it.\nfunction projectRoot(loaded: LoadedConfig): string {\n let dir = loaded.dir\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return loaded.dir\n dir = parent\n }\n}\n\nfunction migrationsDir(loaded: LoadedConfig): string {\n const dir = loaded.config.migrations?.dir ?? DEFAULT_DIR\n return isAbsolute(dir) ? dir : resolve(projectRoot(loaded), dir)\n}\n\nfunction migrationsTable(loaded: LoadedConfig): { schema: string; table: string } {\n return {\n schema: loaded.config.migrations?.schema ?? 'public',\n table: loaded.config.migrations?.table ?? DEFAULT_TABLE,\n }\n}\n\nfunction readJournal(dir: string): Journal {\n try {\n return JSON.parse(readFileSync(join(dir, 'meta', 'journal.json'), 'utf8')) as Journal\n } catch {\n return { version: 1, entries: [] }\n }\n}\n\nfunction writeJournal(dir: string, journal: Journal): void {\n mkdirSync(join(dir, 'meta'), { recursive: true })\n writeFileSync(join(dir, 'meta', 'journal.json'), `${JSON.stringify(journal, null, 2)}\\n`)\n}\n\nfunction connect(loaded: LoadedConfig): PgAsyncDatabase<PgQueryResultHKT, any> {\n const adapter = loaded.config.db\n if (adapter === undefined) {\n throw new CliError('The config has no database adapter (`db` in defineConfig)')\n }\n adapter.check?.()\n return adapter.connect(loaded.config.definition.relations)\n}\n\nexport async function push(loaded: LoadedConfig, io: Io, options: { force?: boolean }) {\n const { pushSchema } = await api()\n const db = connect(loaded)\n const { sqlStatements, hints, apply } = await pushSchema(schemaOf(loaded), db as never)\n if (sqlStatements.length === 0) {\n io.out('The database already matches the config.')\n return\n }\n for (const statement of sqlStatements) io.out(statement)\n if (hints.length > 0) {\n for (const hint of hints) io.err(`! ${hint.hint}`)\n if (options.force !== true) {\n throw new CliError('These changes can lose data: run again with --force to apply them.')\n }\n }\n await apply()\n io.out(`Applied ${sqlStatements.length} statement(s).`)\n await loaded.config.db?.close?.()\n}\n\nexport async function generate(loaded: LoadedConfig, io: Io, options: { name?: string }) {\n const { generateDrizzleJson, generateMigration } = await api()\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n const last = journal.entries.at(-1)\n const previous =\n last === undefined\n ? await generateDrizzleJson({})\n : (JSON.parse(\n readFileSync(\n join(dir, 'meta', `${String(last.idx).padStart(4, '0')}_snapshot.json`),\n 'utf8',\n ),\n ) as Awaited<ReturnType<typeof generateDrizzleJson>>)\n const current = await generateDrizzleJson(schemaOf(loaded), previous.id)\n const statements = await generateMigration(previous, current)\n if (statements.length === 0) {\n io.out('No changes: the migrations already describe the config.')\n return\n }\n const idx = (last?.idx ?? -1) + 1\n const tag = `${String(idx).padStart(4, '0')}_${(options.name ?? 'change').replace(/[^a-z0-9_-]+/gi, '_')}`\n mkdirSync(join(dir, 'meta'), { recursive: true })\n writeFileSync(join(dir, `${tag}.sql`), `${statements.join(`\\n${BREAKPOINT}\\n`)}\\n`)\n writeFileSync(\n join(dir, 'meta', `${String(idx).padStart(4, '0')}_snapshot.json`),\n `${JSON.stringify(current, null, 2)}\\n`,\n )\n journal.entries.push({ idx, tag, createdAt: new Date().toISOString() })\n writeJournal(dir, journal)\n io.out(`Wrote ${tag}.sql with ${statements.length} statement(s).`)\n}\n\nasync function applied(\n db: PgAsyncDatabase<PgQueryResultHKT, any>,\n where: { schema: string; table: string },\n): Promise<Set<string>> {\n if (where.schema !== 'public') {\n await db.execute(sql.raw(`create schema if not exists \"${where.schema}\"`))\n }\n await db.execute(\n sql.raw(\n `create table if not exists \"${where.schema}\".\"${where.table}\" (` +\n 'tag text primary key, applied_at timestamptz not null default now())',\n ),\n )\n const rows = await db.execute(sql.raw(`select tag from \"${where.schema}\".\"${where.table}\"`))\n const list =\n (rows as unknown as { rows?: { tag: string }[] }).rows ?? (rows as unknown as { tag: string }[])\n return new Set(list.map((row) => row.tag))\n}\n\nexport async function migrate(loaded: LoadedConfig, io: Io) {\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n if (journal.entries.length === 0) {\n io.out('No migrations to apply: run `typion db generate` first.')\n return\n }\n const db = connect(loaded)\n const where = migrationsTable(loaded)\n const done = await applied(db, where)\n const pending = journal.entries.filter((entry) => !done.has(entry.tag))\n if (pending.length === 0) {\n io.out('The database is up to date.')\n await loaded.config.db?.close?.()\n return\n }\n for (const entry of pending) {\n const statements = readFileSync(join(dir, `${entry.tag}.sql`), 'utf8')\n .split(BREAKPOINT)\n .map((statement) => statement.trim())\n .filter((statement) => statement !== '')\n await db.transaction(async (tx) => {\n for (const statement of statements) await tx.execute(sql.raw(statement))\n await tx.execute(\n sql.raw(`insert into \"${where.schema}\".\"${where.table}\" (tag) values ('${entry.tag}')`),\n )\n })\n io.out(`Applied ${entry.tag} (${statements.length} statement(s)).`)\n }\n await loaded.config.db?.close?.()\n}\n\nconst SEED_FILES = ['typion/seed.ts', 'typion/seed.js', 'seed.ts', 'seed.js']\n\nfunction findSeedFile(loaded: LoadedConfig, given?: string): string | null {\n if (given !== undefined) {\n const path = isAbsolute(given) ? given : resolve(process.cwd(), given)\n if (!existsSync(path)) throw new CliError(`No seed file at ${path}`)\n return path\n }\n for (const dir of [projectRoot(loaded), loaded.dir]) {\n for (const name of SEED_FILES) {\n const candidate = join(dir, name)\n if (existsSync(candidate)) return candidate\n }\n }\n return null\n}\n\n// Two ways to fill a database, and they answer different needs: the project's own seed writes meaningful rows\n// through the engine (hooks, versions and validation included), `--random` asks drizzle-seed for plausible\n// ones straight into the tables.\nasync function anyRows(loaded: LoadedConfig): Promise<boolean> {\n const db = connect(loaded)\n for (const entity of Object.values(loaded.config.definition.entities)) {\n if (entity.owner !== 'user') continue\n const where = `\"${entity.pgSchema ?? 'public'}\".\"${entity.tableName}\"`\n const rows = await db.execute(sql.raw(`select 1 from ${where} limit 1`))\n const list = (rows as unknown as { rows?: unknown[] }).rows ?? (rows as unknown as unknown[])\n if (list.length > 0) return true\n }\n return false\n}\n\nexport async function seed(\n loaded: LoadedConfig,\n io: Io,\n options: {\n file?: string\n random?: boolean\n count?: number\n seed?: number\n reset?: boolean\n ifEmpty?: boolean\n },\n) {\n if (options.ifEmpty === true && (await anyRows(loaded))) {\n io.out('The collections already hold rows: nothing seeded.')\n await loaded.config.db?.close?.()\n return\n }\n const { resetTables, seedCollections } = await import('../seed/index.js')\n if (options.reset === true) {\n await resetTables(loaded.config)\n io.out('Emptied every table of the config.')\n }\n if (options.random === true) {\n await seedCollections(loaded.config, { count: options.count, seed: options.seed })\n io.out(`Seeded every collection with ${options.count ?? 10} rows.`)\n await loaded.config.db?.close?.()\n return\n }\n const file = findSeedFile(loaded, options.file)\n if (file === null) {\n throw new CliError(\n 'No seed file found (typion/seed.ts). Write one, point at it with --file, or use --random.',\n )\n }\n const { getTypion } = await import('../runtime/typion.js')\n const typion = await getTypion(loaded.config)\n const seedModule = (await import(pathToFileURL(file).href)) as Record<string, unknown>\n const run = (seedModule.seed ?? seedModule.default) as\n ((args: { typion: unknown; config: unknown }) => unknown) | undefined\n if (typeof run !== 'function') {\n throw new CliError(\n `${file} exports no seed function (\\`export async function seed({ typion })\\`)`,\n )\n }\n await run({ typion, config: loaded.config })\n io.out(`Ran ${file}.`)\n await loaded.config.db?.close?.()\n}\n\nexport async function status(loaded: LoadedConfig, io: Io) {\n const dir = migrationsDir(loaded)\n const journal = readJournal(dir)\n const db = connect(loaded)\n const done = await applied(db, migrationsTable(loaded))\n if (journal.entries.length === 0) io.out('No migrations yet.')\n for (const entry of journal.entries) {\n io.out(`${done.has(entry.tag) ? 'applied' : 'pending'} ${entry.tag}`)\n }\n const tables = Object.values(schemaOf(loaded)).filter((value) => is(value, PgTable)) as PgTable[]\n io.out(\n `${tables.length} table(s) in the config: ${tables.map((t) => getTableConfig(t).name).join(', ')}`,\n )\n await loaded.config.db?.close?.()\n}\n\nexport async function studio(loaded: LoadedConfig, io: Io, options: { port?: number }) {\n const { startStudioServer } = await api()\n const credentials = loaded.config.db?.credentials?.()\n if (credentials === undefined) {\n throw new CliError(\n 'This database adapter cannot open Studio: pass `url` to dbAdapter(), or use typion/db/pglite.',\n )\n }\n io.out(`Studio on https://local.drizzle.studio (port ${options.port ?? 4983})`)\n await startStudioServer(schemaOf(loaded), credentials as never, { port: options.port })\n}\n\nexport function listMigrations(dir: string): string[] {\n try {\n return readdirSync(dir).filter((name) => name.endsWith('.sql'))\n } catch {\n return []\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, relative } from 'node:path'\nimport type { Io } from './output.js'\n\n// Agents do not know Typion from training, so the application's agent notes carry the rules that must always hold\n// and point at the guide shipped with the installed version. The block is delimited so that it can be rewritten\n// without touching the rest of the file, the way Next.js maintains its own (`next dev`).\nexport const START_MARKER = '<!-- BEGIN:typion-agent-rules -->'\nexport const END_MARKER = '<!-- END:typion-agent-rules -->'\n\nexport const AGENT_RULES = `${START_MARKER}\n\n# Typion\n\nThis application's data layer is Typion, which is newer than your training data. Before you add or change a\ncollection, an access rule, a hook, a query or an API route, read \\`node_modules/typion/docs/README.md\\` (resolved\nfrom this file's directory) and the page it points to for the task.\n\n- Read and write the application's data through Typion, bound to the caller: \\`getApp(config)\\` on Next.js,\n \\`c.var.typion\\` on Hono, \\`typion.$fromRequest(request)\\` elsewhere, \\`typion.$as(ctx)\\`. Never through\n \\`typion.$db\\`, Drizzle or SQL: they skip the access rules, tenants, soft delete, drafts, hooks and the history.\n- \\`typion.$system({ reason })\\` skips the access rules: for seeds, jobs and webhooks, never to answer a user's\n request.\n- Authorization lives in each collection's \\`access\\` rules, deny by default, not in pages, routes or server\n actions.\n- Every schema change ships a migration: \\`typion db generate --name <change>\\`.\n\nThis block is written by \\`typion init\\`; run it again after upgrading Typion.\n\n${END_MARKER}`\n\nconst SKILL_MARKER =\n '<!-- Written by `typion init`, which rewrites it: keep project notes in AGENTS.md. -->'\n\nexport const SKILL = `---\nname: typion\ndescription: Use for any change to this application's data layer with Typion — collections, access rules, hooks, queries and descriptors, API routes, seeds, migrations, or tests that touch typion.config.ts or the typion/ folder next to it.\n---\n\n${SKILL_MARKER}\n\nTypion is newer than your training data. Its guide ships with the installed version, in \\`node_modules/typion/docs/\\`.\n\n1. Read \\`node_modules/typion/docs/README.md\\`: the model, the rules, where things go.\n2. Read the page for the task:\n - \\`collections.md\\`: a collection, its columns and relations, a many-to-many\n - \\`access.md\\`: who reads and writes what, hidden columns, what a caller sees\n - \\`auth.md\\`: signing in, who the caller is\n - \\`hooks.md\\`: reacting to writes\n - \\`queries.md\\`: reads, writes, descriptors, transactions, errors\n - \\`http.md\\`: Next.js pages and server actions, Hono, the routes, the browser client, business operations\n - \\`database.md\\`: drivers, migrations, seed\n - \\`testing.md\\`: tests\n - \\`features/\\`: localization, multi-tenancy, soft delete, versions and drafts\n3. Before you call the change done: \\`tsc\\` passes, every new collection has its rules, a test covers a caller the\n rules allow and one they refuse, and a schema change has its migration.\n`\n\ntype Outcome = 'created' | 'updated' | 'unchanged' | 'kept'\n\nfunction upsert(existing: string): string {\n const eol = existing.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const block = AGENT_RULES.replace(/\\n/g, eol)\n const start = existing.indexOf(START_MARKER)\n const end = existing.indexOf(END_MARKER, start)\n if (start !== -1 && end !== -1) {\n return existing.slice(0, start) + block + existing.slice(end + END_MARKER.length)\n }\n if (existing.length === 0) return `${block}${eol}`\n const body = existing.endsWith(eol) ? existing : `${existing}${eol}`\n return `${body}${eol}${block}${eol}`\n}\n\nfunction writeFile(path: string, next: string, previous: string | null): Outcome {\n if (previous === next) return 'unchanged'\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, next)\n return previous === null ? 'created' : 'updated'\n}\n\nfunction read(path: string): string | null {\n return existsSync(path) ? readFileSync(path, 'utf8') : null\n}\n\n// The block goes where the project keeps its notes: AGENTS.md, or CLAUDE.md when only that one exists; a project\n// with neither gets both, CLAUDE.md importing AGENTS.md. The skill is rewritten only while it is still Typion's.\nexport function writeAgentNotes(root: string, io: Io): void {\n const agentsPath = join(root, 'AGENTS.md')\n const claudePath = join(root, 'CLAUDE.md')\n const agents = read(agentsPath)\n const claude = read(claudePath)\n const report = (path: string, outcome: Outcome) => {\n const verb = { created: 'Created', updated: 'Updated', kept: 'Kept', unchanged: null }[outcome]\n if (verb !== null) io.out(`${verb} ${relative(process.cwd(), path)}.`)\n }\n\n const claudeHostsBlock = claude?.includes(START_MARKER) ?? false\n if (agents !== null && (agents.includes(START_MARKER) || !claudeHostsBlock)) {\n report(agentsPath, writeFile(agentsPath, upsert(agents), agents))\n } else if (claude !== null) {\n report(claudePath, writeFile(claudePath, upsert(claude), claude))\n } else {\n report(agentsPath, writeFile(agentsPath, upsert(''), null))\n report(claudePath, writeFile(claudePath, '@AGENTS.md\\n', null))\n }\n\n const skillPath = join(root, '.claude', 'skills', 'typion', 'SKILL.md')\n const skill = read(skillPath)\n if (skill !== null && !skill.includes(SKILL_MARKER)) {\n io.out(`Kept ${relative(process.cwd(), skillPath)} (it is not Typion's any more).`)\n } else {\n report(skillPath, writeFile(skillPath, SKILL, skill))\n }\n}\n","import { spawnSync } from 'node:child_process'\nimport { createInterface } from 'node:readline/promises'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, relative } from 'node:path'\nimport { writeAgentNotes } from './agents.js'\nimport { CliError, type Io } from './output.js'\n\ntype PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\n// npm's `latest` Drizzle is 0.x, and a later release candidate can break the engine (rc.5 does): the version the\n// engine is built on, which its `package.json` names as a peer.\nconst DRIZZLE = '1.0.0-rc.4'\n\nconst TRANSPORTS = ['@typion/rest', '@typion/rpc']\n\nfunction packageManager(root: string): PackageManager {\n if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm'\n if (existsSync(join(root, 'yarn.lock'))) return 'yarn'\n if (existsSync(join(root, 'bun.lock')) || existsSync(join(root, 'bun.lockb'))) return 'bun'\n if (existsSync(join(root, 'package-lock.json'))) return 'npm'\n const agent = process.env.npm_config_user_agent ?? ''\n if (agent.startsWith('yarn')) return 'yarn'\n if (agent.startsWith('bun')) return 'bun'\n if (agent.startsWith('pnpm')) return 'pnpm'\n return 'npm'\n}\n\nfunction installCommand(\n manager: PackageManager,\n packages: readonly string[],\n dev: boolean,\n): { command: string; args: string[] } {\n const flag = dev ? (manager === 'npm' ? '--save-dev' : '-D') : ''\n const verb = manager === 'npm' ? 'install' : 'add'\n return {\n command: manager,\n args: [verb, ...(flag === '' ? [] : [flag]), ...packages],\n }\n}\n\nasync function confirm(question: string, io: Io): Promise<boolean> {\n if (!process.stdin.isTTY) {\n io.out(`${question} — not a terminal, so nothing was installed. Re-run with --yes.`)\n return false\n }\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n try {\n const answer = (await rl.question(`${question} [Y/n] `)).trim().toLowerCase()\n return answer === '' || answer === 'y' || answer === 'yes'\n } finally {\n rl.close()\n }\n}\n\nfunction run(command: string, args: readonly string[], cwd: string, io: Io): void {\n io.out(`> ${command} ${args.join(' ')}`)\n const result = spawnSync(command, [...args], { cwd, stdio: 'inherit' })\n if (result.error !== undefined || (result.status !== null && result.status !== 0)) {\n throw new CliError(`\\`${command} ${args.join(' ')}\\` failed; install them yourself and re-run.`)\n }\n}\n\ntype Project = {\n readonly root: string\n readonly src: string\n readonly framework: 'next' | 'hono' | 'none'\n readonly dependencies: ReadonlySet<string>\n readonly appDir: string | null\n}\n\nfunction readJson(path: string): Record<string, any> | null {\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as Record<string, any>\n } catch {\n return null\n }\n}\n\nfunction inspect(cwd: string): Project {\n const pkg = readJson(join(cwd, 'package.json'))\n if (pkg === null) throw new CliError(`No package.json in ${cwd}: run this inside your project.`)\n const deps = { ...pkg.dependencies, ...pkg.devDependencies } as Record<string, string>\n const src = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd\n const appDir = [join(src, 'app'), join(cwd, 'app')].find((dir) => existsSync(dir)) ?? null\n return {\n root: cwd,\n src,\n framework: deps.next !== undefined ? 'next' : deps.hono !== undefined ? 'hono' : 'none',\n dependencies: new Set(Object.keys(deps)),\n appDir,\n }\n}\n\nfunction write(path: string, contents: string, io: Io): boolean {\n if (existsSync(path)) {\n io.out(`Kept ${relative(process.cwd(), path)} (it exists already).`)\n return false\n }\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, contents)\n io.out(`Created ${relative(process.cwd(), path)}.`)\n return true\n}\n\nconst COLLECTION = `import { text } from 'drizzle-orm/pg-core'\nimport { collection } from 'typion'\n\nexport const pages = collection('pages', {\n columns: {\n title: text().notNull(),\n slug: text().notNull().unique(),\n },\n public: true,\n})\n`\n\nfunction configFile(driver: 'pglite' | 'postgres'): string {\n const db =\n driver === 'pglite'\n ? ` db: pglite({ dataDir: '.pglite' }),`\n : ` db: dbAdapter((relations) => drizzle(process.env.DATABASE_URL!, { relations }), {\\n url: process.env.DATABASE_URL,\\n }),`\n const imports =\n driver === 'pglite'\n ? `import { defineConfig, defineSetup } from 'typion'\\nimport { pglite } from 'typion/db/pglite'`\n : `import { drizzle } from 'drizzle-orm/node-postgres'\\nimport { dbAdapter, defineConfig, defineSetup } from 'typion'`\n return `${imports}\nimport { pages } from './typion/collections/pages.ts'\n\n// What the application knows about a caller: rules, hooks and field rules read it. Registered below as well, since\n// field rules are typed before this config exists.\nexport type AppContext = {\n actorId: string | null\n}\n\n// A constant of its own: the collections read it to type their options and their columns, which happens before\n// this config exists. It takes the features (\\`localization\\`, \\`multiTenant\\`) and the plugins (\\`plugins: […]\\`).\nexport const setup = defineSetup({})\n\nexport const config = defineConfig({\n setup,\n collections: [pages],\n${db}\n // Who is calling. Return your own shape; declare the return type, the body may query \\`system\\`.\n context: async ({ headers }): Promise<AppContext> => {\n void headers\n return { actorId: null }\n },\n})\n\ndeclare module 'typion' {\n interface Register {\n setup: typeof setup\n config: typeof config\n context: AppContext\n }\n}\n`\n}\n\n// Every import Typion writes ends in `.ts`, as Node needs to load the config the way the CLI does. TypeScript takes\n// them with `allowImportingTsExtensions` where nothing is emitted (Next.js), and with\n// `rewriteRelativeImportExtensions` where `tsc` builds the project.\nfunction allowTsImports(root: string, io: Io): void {\n const path = join(root, 'tsconfig.json')\n if (!existsSync(path)) return\n const json = readJson(path)\n const options = (json?.compilerOptions ?? {}) as Record<string, unknown>\n if (\n options.allowImportingTsExtensions === true ||\n options.rewriteRelativeImportExtensions === true\n ) {\n return\n }\n const flag =\n options.noEmit === true ? 'allowImportingTsExtensions' : 'rewriteRelativeImportExtensions'\n if (json === null) {\n io.out(\n `Add \"${flag}\": true to the compilerOptions of tsconfig.json: Typion's imports end in .ts.`,\n )\n return\n }\n json.compilerOptions = { ...options, [flag]: true }\n writeFileSync(path, `${JSON.stringify(json, null, 2)}\\n`)\n io.out(`Set ${flag} in tsconfig.json: Typion's imports end in .ts.`)\n}\n\n// The pnpm that will install: the version the project declares, which pnpm switches to; else the one running\n// `init`; else the one on the PATH.\nfunction pnpmMajor(root: string): number | null {\n const declared = /^pnpm@(\\d+)/.exec(String(readJson(join(root, 'package.json'))?.packageManager))\n const agent = /^pnpm\\/(\\d+)/.exec(process.env.npm_config_user_agent ?? '')\n const version =\n declared?.[1] ??\n agent?.[1] ??\n /^(\\d+)\\./.exec(\n spawnSync('pnpm', ['--version'], { cwd: root, encoding: 'utf8' }).stdout ?? '',\n )?.[1]\n return version === undefined ? null : Number(version)\n}\n\n// pnpm reads its settings from the workspace's root, the nearest pnpm-workspace.yaml up the tree.\nfunction workspaceFile(root: string): string {\n for (let dir = root; dirname(dir) !== dir; dir = dirname(dir)) {\n if (existsSync(join(dir, 'pnpm-workspace.yaml'))) return join(dir, 'pnpm-workspace.yaml')\n }\n return join(root, 'pnpm-workspace.yaml')\n}\n\n// From pnpm 11 a build script that is neither allowed nor denied fails the install, and drizzle-kit brings\n// esbuild's: `init` would stop at its own install. pnpm then leaves a placeholder under `allowBuilds`, which fails\n// every install after it, and a second `allowBuilds` added by hand is a duplicated key.\nfunction allowEsbuild(root: string, io: Io): void {\n const major = pnpmMajor(root)\n if (major === null || major < 11) return\n const path = workspaceFile(root)\n const name = relative(process.cwd(), path)\n const why = `pnpm ${major} fails an install on a build script it was not told to run, and drizzle-kit brings esbuild's`\n if (!existsSync(path)) {\n writeFileSync(path, 'allowBuilds:\\n esbuild: true\\n')\n io.out(`Created ${name} to allow esbuild's build script: ${why}.`)\n return\n }\n const text = readFileSync(path, 'utf8')\n const eol = text.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const lines = text.split(/\\r?\\n/)\n const valueOf = (line: string) =>\n line\n .slice(line.indexOf(':') + 1)\n .replace(/(^|\\s)#.*$/, '')\n .trim()\n const key = lines.findIndex((line) => /^allowBuilds\\s*:/.test(line))\n if (key === -1) {\n if (lines.at(-1) === '') lines.pop()\n lines.push(...(lines.length === 0 ? [] : ['']), 'allowBuilds:', ' esbuild: true', '')\n } else if (valueOf(lines[key]!) !== '') {\n // A flow mapping, `allowBuilds: { … }`, is the project's to edit.\n if (!/\\besbuild\\b/.test(lines[key]!))\n io.out(`Add esbuild: true to allowBuilds in ${name}: ${why}.`)\n return\n } else {\n let end = key + 1\n while (end < lines.length && /^(\\s|#|$)/.test(lines[end]!)) end++\n const block = lines.slice(key + 1, end)\n const entry = block.findIndex((line) => /^\\s+(['\"]?)esbuild\\1\\s*:/.test(line))\n if (entry === -1) {\n const indent = block.map((line) => /^(\\s+)[^\\s#]/.exec(line)?.[1]).find(Boolean) ?? ' '\n lines.splice(key + 1, 0, `${indent}esbuild: true`)\n } else {\n // A value the project chose stays; anything else is pnpm's placeholder.\n if (/^(true|false)$/i.test(valueOf(block[entry]!))) return\n lines[key + 1 + entry] = `${/^\\s+/.exec(block[entry]!)![0]}esbuild: true`\n }\n }\n writeFileSync(path, lines.join(eol))\n io.out(`Set allowBuilds: esbuild: true in ${name}: ${why}.`)\n}\n\nconst ROUTE = `import { rest } from '@typion/rest'\nimport { rpc } from '@typion/rpc'\nimport { routeHandlers } from 'typion/next'\nimport { config } from '@/typion.config.ts'\n\n// What the app serves over HTTP: a resource per collection, and the endpoint the browser client posts to. Leave\n// out what you do not use.\nexport const { GET, POST, PATCH, PUT, DELETE, OPTIONS } = await routeHandlers(config, {\n transports: [rest(), rpc()],\n})\n`\n\nexport async function init(\n cwd: string,\n io: Io,\n options: { driver?: string; yes?: boolean; skipInstall?: boolean },\n): Promise<void> {\n const project = inspect(cwd)\n const driver = options.driver === 'postgres' ? 'postgres' : 'pglite'\n\n // The sample collection comes with a new config only: a run after an upgrade refreshes the notes and leaves the\n // project's collections as they are.\n if (write(join(project.src, 'typion.config.ts'), configFile(driver), io)) {\n write(join(project.src, 'typion', 'collections', 'pages.ts'), COLLECTION, io)\n }\n allowTsImports(project.root, io)\n\n if (project.framework === 'next' && project.appDir !== null) {\n write(join(project.appDir, 'api', '[...path]', 'route.ts'), ROUTE, io)\n }\n writeAgentNotes(project.root, io)\n\n const manager = packageManager(project.root)\n if (manager === 'pnpm') allowEsbuild(project.root, io)\n await installDependencies(project, manager, driver, io, options)\n\n io.out('')\n io.out('Next:')\n io.out(\n ' 1. turn on what you need: `softDelete` or `versions` on a collection, `localization`, `multiTenant` or `plugins` in `defineSetup`',\n )\n io.out(\n existsSync(join(project.root, 'typion', 'migrations'))\n ? ' 2. `typion db migrate` to apply the migrations, then `typion db seed`'\n : ' 2. `typion db push` to create the tables, then `typion db seed`',\n )\n if (project.framework === 'next') {\n io.out(\n ' 3. read from a server component with `const app = await getApp(config)` (typion/next)',\n )\n }\n // The app's entry is the developer's own file: what to add to it is said, not written. It may serve only routes\n // of its own, so the transports come with the step that mounts them rather than with what every app installs.\n if (project.framework === 'hono') {\n io.out(\n ' 3. bind the caller in your own routes with `typionMiddleware(config)`: `c.var.typion`',\n )\n const transports = TRANSPORTS.filter((name) => !project.dependencies.has(name))\n const add = installCommand(manager, transports, false)\n const install = transports.length === 0 ? '' : `\\`${add.command} ${add.args.join(' ')}\\`, then `\n io.out(\n ` 4. to serve the collections over HTTP: ${install}\\`.all('/api/*', typionRoutes(config, { transports: [rest(), rpc()] }))\\` (typion/hono)`,\n )\n }\n}\n\nasync function installDependencies(\n project: Project,\n manager: PackageManager,\n driver: 'pglite' | 'postgres',\n io: Io,\n options: { yes?: boolean; skipInstall?: boolean },\n): Promise<void> {\n const deps = [\n 'typion',\n 'drizzle-orm',\n driver === 'pglite' ? '@electric-sql/pglite' : 'pg',\n // The route `init` writes on Next.js imports them.\n ...(project.framework === 'next' ? TRANSPORTS : []),\n ]\n const dev = ['drizzle-kit']\n const spec = (name: string) => (name.startsWith('drizzle-') ? `${name}@${DRIZZLE}` : name)\n const missing = deps.filter((name) => !project.dependencies.has(name)).map(spec)\n const missingDev = dev.filter((name) => !project.dependencies.has(name)).map(spec)\n if (missing.length === 0 && missingDev.length === 0) return\n\n const lines = [\n ...(missing.length === 0 ? [] : [installCommand(manager, missing, false)]),\n ...(missingDev.length === 0 ? [] : [installCommand(manager, missingDev, true)]),\n ]\n io.out('')\n io.out('Missing packages:')\n for (const line of lines) io.out(` ${line.command} ${line.args.join(' ')}`)\n\n if (options.skipInstall === true) return\n const ok = options.yes === true || (await confirm(`Install them with ${manager}?`, io))\n if (!ok) return\n for (const line of lines) run(line.command, line.args, project.root, io)\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport type { LoadedConfig } from './config.js'\nimport { CliError, type Io } from './output.js'\n\nfunction pascal(name: string): string {\n return name.replace(/(^|[-_ ])(\\w)/g, (_, __, char: string) => char.toUpperCase())\n}\n\nfunction camel(name: string): string {\n const upper = pascal(name)\n return upper.charAt(0).toLowerCase() + upper.slice(1)\n}\n\n// Where the collections of this project live: next to the ones already there, else beside the config.\nfunction collectionsDir(loaded: LoadedConfig, given?: string): string {\n if (given !== undefined) return isAbsolute(given) ? given : resolve(process.cwd(), given)\n const candidates = [join(loaded.dir, 'typion', 'collections'), join(loaded.dir, 'collections')]\n return candidates.find((dir) => existsSync(dir)) ?? candidates[0]!\n}\n\n// No rule is written for the developer: a generated `read: true` would serve every row to anyone, anonymous callers\n// included, until someone noticed. In a multi-tenant application the rows belong to the caller's tenant.\nfunction template(name: string, tenant: boolean): string {\n return `import { text } from 'drizzle-orm/pg-core'\nimport { collection } from 'typion'\n\nexport const ${camel(name)} = collection('${camel(name)}', {\n columns: {\n // Plain Drizzle columns; the features and plugins add their own options next to \\`columns\\`.\n title: text().notNull(),\n },${tenant ? '\\n tenant: true,' : ''}\n}).define({\n // Deny by default: an operation without a rule is refused. Give each one the rule it needs, for example\n // \\`read: ({ ctx }) => ctx.actorId !== null\\`.\n access: {},\n})\n`\n}\n\nfunction importPath(from: string, to: string): string {\n const path = relative(from, to).replaceAll('\\\\', '/')\n return path.startsWith('.') ? path : `./${path}`\n}\n\n// Best effort: adds the import and the entry to `collections: [...]`. When the config does not match the\n// shape the CLI understands, it prints the two lines instead of guessing.\nfunction register(loaded: LoadedConfig, name: string, file: string, io: Io): void {\n const source = readFileSync(loaded.path, 'utf8')\n const specifier = importPath(loaded.dir, file).replace(/\\.ts$/, '.ts')\n const line = `import { ${camel(name)} } from '${specifier}'`\n const list = /collections:\\s*\\[([^\\]]*)\\]/.exec(source)\n if (source.includes(line) || list === null) {\n io.out('Add it to the config:')\n io.out(` ${line}`)\n io.out(` collections: [ …, ${camel(name)} ]`)\n return\n }\n const entries = list[1]!.trim()\n const updated = source\n .replace(/(^import .*\\n)(?![\\s\\S]*^import )/m, `$1${line}\\n`)\n .replace(\n /collections:\\s*\\[([^\\]]*)\\]/,\n `collections: [${entries === '' ? '' : `${entries.replace(/,\\s*$/, '')}, `}${camel(name)}]`,\n )\n writeFileSync(loaded.path, updated)\n io.out(`Registered it in ${relative(process.cwd(), loaded.path)}.`)\n}\n\nfunction pluginTemplate(name: string): string {\n const id = camel(name)\n const Kinds = `${pascal(name)}Kinds`\n const Options = `${pascal(name)}Options`\n return `import { definePlugin } from 'typion'\nimport type { CollectionKinds } from 'typion'\n\n// What this plugin adds to every collection. A collection that does not set the option gets nothing.\nexport type ${Options} = { ${id}?: boolean }\n\n// How the option turns into columns and into engine options, read from \\`this['options']\\`.\ninterface ${Kinds} extends CollectionKinds {\n readonly columns: this['options'] extends { ${id}: true } ? {} : {}\n readonly entity: this['options'] extends { ${id}: true } ? {} : {}\n}\n\nexport function ${id}() {\n return definePlugin({\n id: '${id}',\n collection: {\n $options: {} as ${Options},\n $kinds: {} as ${Kinds},\n // Option keys this plugin reads, so they never reach the engine as entity options.\n consumes: ['${id}'],\n columns: (options) => (options.${id} === true ? {} : {}),\n entity: (options) => (options.${id} === true ? {} : {}),\n },\n // Tables, relations, entities, hooks, api, routes, errors and context go here too; see @typion/audit.\n })\n}\n`\n}\n\nexport function makePlugin(\n loaded: LoadedConfig,\n io: Io,\n name: string,\n options: { dir?: string },\n): void {\n if (!/^[a-z][a-z0-9_-]*$/i.test(name)) {\n throw new CliError(`'${name}' is not a plugin name (letters, digits, dash, underscore)`)\n }\n const dir =\n options.dir === undefined\n ? join(loaded.dir, 'typion', 'plugins')\n : isAbsolute(options.dir)\n ? options.dir\n : resolve(process.cwd(), options.dir)\n const file = join(dir, `${camel(name)}.ts`)\n if (existsSync(file)) throw new CliError(`${relative(process.cwd(), file)} already exists`)\n mkdirSync(dir, { recursive: true })\n writeFileSync(file, pluginTemplate(name))\n io.out(`Created ${relative(process.cwd(), file)}.`)\n io.out('Install it in the config:')\n io.out(` import { ${camel(name)} } from './${relative(loaded.dir, file).replaceAll('\\\\', '/')}'`)\n io.out(` export const setup = defineSetup({ plugins: [ …, ${camel(name)}() ] })`)\n}\n\nexport function makeCollection(\n loaded: LoadedConfig,\n io: Io,\n name: string,\n options: { dir?: string },\n): void {\n if (!/^[a-z][a-z0-9_-]*$/i.test(name)) {\n throw new CliError(`'${name}' is not a collection name (letters, digits, dash, underscore)`)\n }\n const dir = collectionsDir(loaded, options.dir)\n const file = join(dir, `${camel(name)}.ts`)\n if (existsSync(file)) throw new CliError(`${relative(process.cwd(), file)} already exists`)\n mkdirSync(dirname(file), { recursive: true })\n const tenant = loaded.config.definition.plugins.some((plugin) => plugin.id === 'multiTenant')\n writeFileSync(file, template(name, tenant))\n io.out(`Created ${relative(process.cwd(), file)}.`)\n register(loaded, name, file, io)\n io.out('Then `typion db push` (or `typion db generate` + `typion db migrate`).')\n}\n","import { parseArgs } from 'node:util'\nimport { ConfigError } from '../errors.js'\nimport { loadConfig } from './config.js'\nimport * as db from './db.js'\nimport { init } from './init.js'\nimport { makeCollection, makePlugin } from './make.js'\nimport { CliError, consoleIo, type Io } from './output.js'\n\nconst HELP = `typion — the CLI of a Typion project\n\nUsage\n typion <group> <command> [options]\n\nDatabase (everything that touches the schema, through drizzle-kit)\n typion db push [--force] make the database match the config (development)\n typion db generate [--name x] write the SQL of what changed, with its snapshot\n typion db migrate apply the migrations the database has not applied\n typion db seed [--file path] run the project's seed through the engine\n [--random] ask drizzle-seed for rows instead (--count, --seed)\n [--reset] empty every table of the config first\n [--if-empty] do nothing when a collection already holds rows\n typion db status what is applied, what is pending\n typion db studio [--port n] open Drizzle Studio on this config\n\nProject\n typion make collection <name> [--dir path] a new collection, registered in the config\n typion make plugin <name> [--dir path] a plugin skeleton for this project\n typion init [--driver pglite|postgres] [--yes] [--skip-install]\n set Typion up in a project that exists, with the\n notes its agents read (run it again after upgrading)\n\nOptions\n --config <path> the config to read; by default the nearest typion.config.ts\n --help this text (also: typion db --help)\n`\n\nconst DB_HELP = `typion db — the database of a Typion config\n\n push [--force] make the database match the config (development)\n generate [--name x] write the SQL of what changed, with its snapshot\n migrate apply the migrations the database has not applied\n seed [--file|--random] fill the database: the project's seed, or drizzle-seed rows\n status what is applied, what is pending\n studio [--port n] open Drizzle Studio on this config\n`\n\nconst OPTIONS = {\n config: { type: 'string' },\n name: { type: 'string' },\n dir: { type: 'string' },\n driver: { type: 'string' },\n port: { type: 'string' },\n file: { type: 'string' },\n count: { type: 'string' },\n seed: { type: 'string' },\n force: { type: 'boolean' },\n random: { type: 'boolean' },\n reset: { type: 'boolean' },\n 'if-empty': { type: 'boolean' },\n 'skip-install': { type: 'boolean' },\n yes: { type: 'boolean' },\n help: { type: 'boolean' },\n} as const\n\nfunction port(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined\n if (!/^\\d+$/.test(raw)) throw new CliError('--port must be a number')\n return Number(raw)\n}\n\nexport async function run(argv: readonly string[], io: Io = consoleIo, cwd = process.cwd()) {\n const { values, positionals } = parseArgs({\n args: [...argv],\n options: OPTIONS,\n allowPositionals: true,\n strict: true,\n })\n const [group, command, argument] = positionals\n\n if (group === undefined || values.help === true) {\n io.out(group === 'db' ? DB_HELP : HELP)\n return\n }\n\n const config = async () => loadConfig(cwd, values.config)\n\n switch (`${group} ${command ?? ''}`.trim()) {\n case 'db push':\n return db.push(await config(), io, { force: values.force })\n case 'db generate':\n return db.generate(await config(), io, { name: values.name })\n case 'db migrate':\n return db.migrate(await config(), io)\n case 'db seed':\n return db.seed(await config(), io, {\n file: values.file,\n random: values.random,\n count: values.count === undefined ? undefined : Number(values.count),\n seed: values.seed === undefined ? undefined : Number(values.seed),\n reset: values.reset,\n ifEmpty: values['if-empty'],\n })\n case 'db status':\n return db.status(await config(), io)\n case 'db studio':\n return db.studio(await config(), io, { port: port(values.port) })\n case 'db':\n io.out(DB_HELP)\n return\n case 'make collection': {\n if (argument === undefined) throw new CliError('Usage: typion make collection <name>')\n return makeCollection(await config(), io, argument, { dir: values.dir })\n }\n case 'make plugin': {\n if (argument === undefined) throw new CliError('Usage: typion make plugin <name>')\n return makePlugin(await config(), io, argument, { dir: values.dir })\n }\n case 'make':\n throw new CliError('Usage: typion make collection|plugin <name>')\n case 'init':\n return init(cwd, io, {\n driver: values.driver,\n yes: values.yes,\n skipInstall: values['skip-install'],\n })\n default:\n throw new CliError(\n `Unknown command '${[group, command].filter(Boolean).join(' ')}'. Try \\`typion --help\\`.`,\n )\n }\n}\n\nexport async function main(argv: readonly string[]): Promise<number> {\n try {\n await run(argv)\n return 0\n } catch (error) {\n // What the user has to change, in a sentence: a stack trace would bury it.\n if (error instanceof CliError || error instanceof ConfigError) {\n console.error(error.message)\n return 1\n }\n console.error(error)\n return 1\n }\n}\n\nexport { CliError }\n"],"mappings":";;;;;;;;;;AACA,IAAa,WAAb,cAA8B,MAAM;CAClC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAOA,MAAa,YAAgB;CAC3B,MAAM,SAAS,QAAQ,IAAI,IAAI;CAC/B,MAAM,SAAS,QAAQ,MAAM,IAAI;AACnC;;;ACVA,MAAM,QAAQ;CAAC;CAAoB;CAAoB;CAAqB;AAAmB;AAC/F,MAAM,OAAO;CAAC;CAAI;CAAO;CAAO;AAAQ;AAQxC,SAAgB,WAAW,KAAa,OAAwB;CAC9D,IAAI,UAAU,KAAA,GAAW;EACvB,MAAM,OAAO,WAAW,KAAK,IAAI,QAAQ,QAAQ,KAAK,KAAK;EAC3D,IAAI,CAAC,WAAW,IAAI,GAAG,MAAM,IAAI,SAAS,gBAAgB,MAAM;EAChE,OAAO;CACT;CACA,IAAI,MAAM,QAAQ,GAAG;CACrB,SAAS;EACP,KAAK,MAAM,OAAO,MAChB,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI;GACrC,IAAI,WAAW,SAAS,GAAG,OAAO;EACpC;EAEF,MAAM,SAAS,QAAQ,GAAG;EAC1B,IAAI,WAAW,KAAK;EACpB,MAAM;CACR;CACA,MAAM,IAAI,SACR,kCAAkC,IAAI,gDACxC;AACF;AAIA,eAAe,aAAa,MAAgD;CAC1E,IAAI;EACF,OAAO,MAAM,uBACX,YAAa,MAAM,OAAO,cAAc,IAAI,CAAC,CAAC,KAChD;CACF,SAAS,OAAO;EACd,MAAM,OAAO,MAAM,SAAS,IAAI;EAChC,IAAI,SAAS,MAAM,MAAM;EACzB,OAAQ,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC;CACpC;AACF;AAIA,eAAe,uBAA0B,MAAoC;CAC3E,MAAM,OAAO,QAAQ;CACrB,QAAQ,gBAAgB,SAAyB,GAAG,SAAoB;EAEtE,KADc,KAAK,EAAE,EAAoC,QAAQ,KAAK,QACzD,gCAAgC;EAC5C,KAAuC,KAAK,SAAS,SAAS,GAAG,IAAI;CACxE;CACA,IAAI;EACF,OAAO,MAAM,KAAK;CACpB,UAAU;EACR,QAAQ,cAAc;CACxB;AACF;AAIA,eAAe,SAAS,MAAoC;CAC1D,IAAI;EAKF,QAAO,MADY,OAAO,QAAA,CACf,WAAW,cAAc,IAAI,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,CAAC;CAC1E,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,WAAW,SAAkC,MAAiC;CACrF,MAAM,aAAa;EAAC,QAAQ;EAAQ,QAAQ;EAAS,GAAG,OAAO,OAAO,OAAO;CAAC;CAC9E,KAAK,MAAM,SAAS,YAClB,IACE,OAAO,UAAU,YACjB,UAAU,QACV,gBAAgB,SAChB,YAAY,SACZ,OAAQ,MAAmC,eAAe,UAE1D,OAAO;CAGX,MAAM,IAAI,SACR,GAAG,KAAK,+EACV;AACF;AAIA,SAAS,QAAQ,KAAmB;CAClC,KAAK,MAAM,QAAQ,CAAC,cAAc,MAAM,GAAG;EACzC,MAAM,OAAO,KAAK,KAAK,IAAI;EAC3B,IAAI,WAAW,IAAI,GAAG,QAAQ,YAAY,IAAI;CAChD;AACF;AAEA,eAAsB,WAAW,KAAa,OAAuC;CACnF,QAAQ,GAAG;CACX,MAAM,OAAO,WAAW,KAAK,KAAK;CAElC,OAAO;EAAE,QAAQ,WAAW,MADN,aAAa,IAAI,GACF,IAAI;EAAG;EAAM,KAAK,QAAQ,IAAI;CAAE;AACvE;;;ACxGA,MAAM,aAAa;AACnB,MAAM,cAAc;AACpB,MAAM,gBAAgB;AAMtB,eAAe,MAAoB;CACjC,IAAI;EACF,OAAQ,MAAM,OAAO;CACvB,QAAQ;EACN,MAAM,IAAI,SACR,8EACF;CACF;AACF;AAEA,SAAS,SAAS,QAA+C;CAC/D,OAAO,OAAO,OAAO;AACvB;AAIA,SAAS,YAAY,QAA8B;CACjD,IAAI,MAAM,OAAO;CACjB,SAAS;EACP,IAAI,WAAW,KAAK,KAAK,cAAc,CAAC,GAAG,OAAO;EAClD,MAAM,SAAS,QAAQ,GAAG;EAC1B,IAAI,WAAW,KAAK,OAAO,OAAO;EAClC,MAAM;CACR;AACF;AAEA,SAAS,cAAc,QAA8B;CACnD,MAAM,MAAM,OAAO,OAAO,YAAY,OAAO;CAC7C,OAAO,WAAW,GAAG,IAAI,MAAM,QAAQ,YAAY,MAAM,GAAG,GAAG;AACjE;AAEA,SAAS,gBAAgB,QAAyD;CAChF,OAAO;EACL,QAAQ,OAAO,OAAO,YAAY,UAAU;EAC5C,OAAO,OAAO,OAAO,YAAY,SAAS;CAC5C;AACF;AAEA,SAAS,YAAY,KAAsB;CACzC,IAAI;EACF,OAAO,KAAK,MAAM,aAAa,KAAK,KAAK,QAAQ,cAAc,GAAG,MAAM,CAAC;CAC3E,QAAQ;EACN,OAAO;GAAE,SAAS;GAAG,SAAS,CAAC;EAAE;CACnC;AACF;AAEA,SAAS,aAAa,KAAa,SAAwB;CACzD,UAAU,KAAK,KAAK,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;CAChD,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,GAAG;AAC1F;AAEA,SAAS,QAAQ,QAA8D;CAC7E,MAAM,UAAU,OAAO,OAAO;CAC9B,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,SAAS,2DAA2D;CAEhF,QAAQ,QAAQ;CAChB,OAAO,QAAQ,QAAQ,OAAO,OAAO,WAAW,SAAS;AAC3D;AAEA,eAAsB,KAAK,QAAsB,IAAQ,SAA8B;CACrF,MAAM,EAAE,eAAe,MAAM,IAAI;CACjC,MAAM,KAAK,QAAQ,MAAM;CACzB,MAAM,EAAE,eAAe,OAAO,UAAU,MAAM,WAAW,SAAS,MAAM,GAAG,EAAW;CACtF,IAAI,cAAc,WAAW,GAAG;EAC9B,GAAG,IAAI,0CAA0C;EACjD;CACF;CACA,KAAK,MAAM,aAAa,eAAe,GAAG,IAAI,SAAS;CACvD,IAAI,MAAM,SAAS,GAAG;EACpB,KAAK,MAAM,QAAQ,OAAO,GAAG,IAAI,KAAK,KAAK,MAAM;EACjD,IAAI,QAAQ,UAAU,MACpB,MAAM,IAAI,SAAS,oEAAoE;CAE3F;CACA,MAAM,MAAM;CACZ,GAAG,IAAI,WAAW,cAAc,OAAO,eAAe;CACtD,MAAM,OAAO,OAAO,IAAI,QAAQ;AAClC;AAEA,eAAsB,SAAS,QAAsB,IAAQ,SAA4B;CACvF,MAAM,EAAE,qBAAqB,sBAAsB,MAAM,IAAI;CAC7D,MAAM,MAAM,cAAc,MAAM;CAChC,MAAM,UAAU,YAAY,GAAG;CAC/B,MAAM,OAAO,QAAQ,QAAQ,GAAG,EAAE;CAClC,MAAM,WACJ,SAAS,KAAA,IACL,MAAM,oBAAoB,CAAC,CAAC,IAC3B,KAAK,MACJ,aACE,KAAK,KAAK,QAAQ,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,eAAe,GACtE,MACF,CACF;CACN,MAAM,UAAU,MAAM,oBAAoB,SAAS,MAAM,GAAG,SAAS,EAAE;CACvE,MAAM,aAAa,MAAM,kBAAkB,UAAU,OAAO;CAC5D,IAAI,WAAW,WAAW,GAAG;EAC3B,GAAG,IAAI,yDAAyD;EAChE;CACF;CACA,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,IAAI,QAAQ,QAAQ,SAAA,CAAU,QAAQ,kBAAkB,GAAG;CACvG,UAAU,KAAK,KAAK,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;CAChD,cAAc,KAAK,KAAK,GAAG,IAAI,KAAK,GAAG,GAAG,WAAW,KAAK,KAAK,WAAW,GAAG,EAAE,GAAG;CAClF,cACE,KAAK,KAAK,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,eAAe,GACjE,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,GACtC;CACA,QAAQ,QAAQ,KAAK;EAAE;EAAK;EAAK,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;CAAE,CAAC;CACtE,aAAa,KAAK,OAAO;CACzB,GAAG,IAAI,SAAS,IAAI,YAAY,WAAW,OAAO,eAAe;AACnE;AAEA,eAAe,QACb,IACA,OACsB;CACtB,IAAI,MAAM,WAAW,UACnB,MAAM,GAAG,QAAQ,IAAI,IAAI,gCAAgC,MAAM,OAAO,EAAE,CAAC;CAE3E,MAAM,GAAG,QACP,IAAI,IACF,+BAA+B,MAAM,OAAO,KAAK,MAAM,MAAM,wEAE/D,CACF;CACA,MAAM,OAAO,MAAM,GAAG,QAAQ,IAAI,IAAI,oBAAoB,MAAM,OAAO,KAAK,MAAM,MAAM,EAAE,CAAC;CAC3F,MAAM,OACH,KAAiD,QAAS;CAC7D,OAAO,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC;AAC3C;AAEA,eAAsB,QAAQ,QAAsB,IAAQ;CAC1D,MAAM,MAAM,cAAc,MAAM;CAChC,MAAM,UAAU,YAAY,GAAG;CAC/B,IAAI,QAAQ,QAAQ,WAAW,GAAG;EAChC,GAAG,IAAI,yDAAyD;EAChE;CACF;CACA,MAAM,KAAK,QAAQ,MAAM;CACzB,MAAM,QAAQ,gBAAgB,MAAM;CACpC,MAAM,OAAO,MAAM,QAAQ,IAAI,KAAK;CACpC,MAAM,UAAU,QAAQ,QAAQ,QAAQ,UAAU,CAAC,KAAK,IAAI,MAAM,GAAG,CAAC;CACtE,IAAI,QAAQ,WAAW,GAAG;EACxB,GAAG,IAAI,6BAA6B;EACpC,MAAM,OAAO,OAAO,IAAI,QAAQ;EAChC;CACF;CACA,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,aAAa,aAAa,KAAK,KAAK,GAAG,MAAM,IAAI,KAAK,GAAG,MAAM,CAAC,CACnE,MAAM,UAAU,CAAC,CACjB,KAAK,cAAc,UAAU,KAAK,CAAC,CAAC,CACpC,QAAQ,cAAc,cAAc,EAAE;EACzC,MAAM,GAAG,YAAY,OAAO,OAAO;GACjC,KAAK,MAAM,aAAa,YAAY,MAAM,GAAG,QAAQ,IAAI,IAAI,SAAS,CAAC;GACvE,MAAM,GAAG,QACP,IAAI,IAAI,gBAAgB,MAAM,OAAO,KAAK,MAAM,MAAM,mBAAmB,MAAM,IAAI,GAAG,CACxF;EACF,CAAC;EACD,GAAG,IAAI,WAAW,MAAM,IAAI,IAAI,WAAW,OAAO,gBAAgB;CACpE;CACA,MAAM,OAAO,OAAO,IAAI,QAAQ;AAClC;AAEA,MAAM,aAAa;CAAC;CAAkB;CAAkB;CAAW;AAAS;AAE5E,SAAS,aAAa,QAAsB,OAA+B;CACzE,IAAI,UAAU,KAAA,GAAW;EACvB,MAAM,OAAO,WAAW,KAAK,IAAI,QAAQ,QAAQ,QAAQ,IAAI,GAAG,KAAK;EACrE,IAAI,CAAC,WAAW,IAAI,GAAG,MAAM,IAAI,SAAS,mBAAmB,MAAM;EACnE,OAAO;CACT;CACA,KAAK,MAAM,OAAO,CAAC,YAAY,MAAM,GAAG,OAAO,GAAG,GAChD,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,YAAY,KAAK,KAAK,IAAI;EAChC,IAAI,WAAW,SAAS,GAAG,OAAO;CACpC;CAEF,OAAO;AACT;AAKA,eAAe,QAAQ,QAAwC;CAC7D,MAAM,KAAK,QAAQ,MAAM;CACzB,KAAK,MAAM,UAAU,OAAO,OAAO,OAAO,OAAO,WAAW,QAAQ,GAAG;EACrE,IAAI,OAAO,UAAU,QAAQ;EAC7B,MAAM,QAAQ,IAAI,OAAO,YAAY,SAAS,KAAK,OAAO,UAAU;EACpE,MAAM,OAAO,MAAM,GAAG,QAAQ,IAAI,IAAI,iBAAiB,MAAM,SAAS,CAAC;EAEvE,KADc,KAAyC,QAAS,KAAA,CACvD,SAAS,GAAG,OAAO;CAC9B;CACA,OAAO;AACT;AAEA,eAAsB,KACpB,QACA,IACA,SAQA;CACA,IAAI,QAAQ,YAAY,QAAS,MAAM,QAAQ,MAAM,GAAI;EACvD,GAAG,IAAI,oDAAoD;EAC3D,MAAM,OAAO,OAAO,IAAI,QAAQ;EAChC;CACF;CACA,MAAM,EAAE,aAAa,oBAAoB,MAAM,OAAO;CACtD,IAAI,QAAQ,UAAU,MAAM;EAC1B,MAAM,YAAY,OAAO,MAAM;EAC/B,GAAG,IAAI,oCAAoC;CAC7C;CACA,IAAI,QAAQ,WAAW,MAAM;EAC3B,MAAM,gBAAgB,OAAO,QAAQ;GAAE,OAAO,QAAQ;GAAO,MAAM,QAAQ;EAAK,CAAC;EACjF,GAAG,IAAI,gCAAgC,QAAQ,SAAS,GAAG,OAAO;EAClE,MAAM,OAAO,OAAO,IAAI,QAAQ;EAChC;CACF;CACA,MAAM,OAAO,aAAa,QAAQ,QAAQ,IAAI;CAC9C,IAAI,SAAS,MACX,MAAM,IAAI,SACR,2FACF;CAEF,MAAM,EAAE,cAAc,MAAM,OAAO,wBAAuB,CAAA,MAAA,MAAA,EAAA,CAAA;CAC1D,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM;CAC5C,MAAM,aAAc,MAAM,OAAO,cAAc,IAAI,CAAC,CAAC;CACrD,MAAM,MAAO,WAAW,QAAQ,WAAW;CAE3C,IAAI,OAAO,QAAQ,YACjB,MAAM,IAAI,SACR,GAAG,KAAK,uEACV;CAEF,MAAM,IAAI;EAAE;EAAQ,QAAQ,OAAO;CAAO,CAAC;CAC3C,GAAG,IAAI,OAAO,KAAK,EAAE;CACrB,MAAM,OAAO,OAAO,IAAI,QAAQ;AAClC;AAEA,eAAsB,OAAO,QAAsB,IAAQ;CAEzD,MAAM,UAAU,YADJ,cAAc,MACI,CAAC;CAE/B,MAAM,OAAO,MAAM,QADR,QAAQ,MACS,GAAG,gBAAgB,MAAM,CAAC;CACtD,IAAI,QAAQ,QAAQ,WAAW,GAAG,GAAG,IAAI,oBAAoB;CAC7D,KAAK,MAAM,SAAS,QAAQ,SAC1B,GAAG,IAAI,GAAG,KAAK,IAAI,MAAM,GAAG,IAAI,YAAY,UAAU,IAAI,MAAM,KAAK;CAEvE,MAAM,SAAS,OAAO,OAAO,SAAS,MAAM,CAAC,CAAC,CAAC,QAAQ,UAAU,GAAG,OAAO,OAAO,CAAC;CACnF,GAAG,IACD,GAAG,OAAO,OAAO,2BAA2B,OAAO,KAAK,MAAM,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,GACjG;CACA,MAAM,OAAO,OAAO,IAAI,QAAQ;AAClC;AAEA,eAAsB,OAAO,QAAsB,IAAQ,SAA4B;CACrF,MAAM,EAAE,sBAAsB,MAAM,IAAI;CACxC,MAAM,cAAc,OAAO,OAAO,IAAI,cAAc;CACpD,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,SACR,+FACF;CAEF,GAAG,IAAI,gDAAgD,QAAQ,QAAQ,KAAK,EAAE;CAC9E,MAAM,kBAAkB,SAAS,MAAM,GAAG,aAAsB,EAAE,MAAM,QAAQ,KAAK,CAAC;AACxF;;;AC1RA,MAAa,eAAe;AAC5B,MAAa,aAAa;AAE1B,MAAa,cAAc,GAAG,aAAa;;;;;;;;;;;;;;;;;;;EAmBzC;AAEF,MAAM,eACJ;AAEF,MAAa,QAAQ;;;;;EAKnB,aAAa;;;;;;;;;;;;;;;;;;AAqBf,SAAS,OAAO,UAA0B;CACxC,MAAM,MAAM,SAAS,SAAS,MAAM,IAAI,SAAS;CACjD,MAAM,QAAQ,YAAY,QAAQ,OAAO,GAAG;CAC5C,MAAM,QAAQ,SAAS,QAAQ,YAAY;CAC3C,MAAM,MAAM,SAAS,QAAQ,YAAY,KAAK;CAC9C,IAAI,UAAU,MAAM,QAAQ,IAC1B,OAAO,SAAS,MAAM,GAAG,KAAK,IAAI,QAAQ,SAAS,MAAM,MAAM,EAAiB;CAElF,IAAI,SAAS,WAAW,GAAG,OAAO,GAAG,QAAQ;CAE7C,OAAO,GADM,SAAS,SAAS,GAAG,IAAI,WAAW,GAAG,WAAW,QAC9C,MAAM,QAAQ;AACjC;AAEA,SAAS,UAAU,MAAc,MAAc,UAAkC;CAC/E,IAAI,aAAa,MAAM,OAAO;CAC9B,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAC5C,cAAc,MAAM,IAAI;CACxB,OAAO,aAAa,OAAO,YAAY;AACzC;AAEA,SAAS,KAAK,MAA6B;CACzC,OAAO,WAAW,IAAI,IAAI,aAAa,MAAM,MAAM,IAAI;AACzD;AAIA,SAAgB,gBAAgB,MAAc,IAAc;CAC1D,MAAM,aAAa,KAAK,MAAM,WAAW;CACzC,MAAM,aAAa,KAAK,MAAM,WAAW;CACzC,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,UAAU,MAAc,YAAqB;EACjD,MAAM,OAAO;GAAE,SAAS;GAAW,SAAS;GAAW,MAAM;GAAQ,WAAW;EAAK,EAAE;EACvF,IAAI,SAAS,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,EAAE;CACvE;CAEA,MAAM,mBAAmB,QAAQ,SAAA,mCAAqB,KAAK;CAC3D,IAAI,WAAW,SAAS,OAAO,SAAA,mCAAqB,KAAK,CAAC,mBACxD,OAAO,YAAY,UAAU,YAAY,OAAO,MAAM,GAAG,MAAM,CAAC;MAC3D,IAAI,WAAW,MACpB,OAAO,YAAY,UAAU,YAAY,OAAO,MAAM,GAAG,MAAM,CAAC;MAC3D;EACL,OAAO,YAAY,UAAU,YAAY,OAAO,EAAE,GAAG,IAAI,CAAC;EAC1D,OAAO,YAAY,UAAU,YAAY,gBAAgB,IAAI,CAAC;CAChE;CAEA,MAAM,YAAY,KAAK,MAAM,WAAW,UAAU,UAAU,UAAU;CACtE,MAAM,QAAQ,KAAK,SAAS;CAC5B,IAAI,UAAU,QAAQ,CAAC,MAAM,SAAS,YAAY,GAChD,GAAG,IAAI,QAAQ,SAAS,QAAQ,IAAI,GAAG,SAAS,EAAE,gCAAgC;MAElF,OAAO,WAAW,UAAU,WAAW,OAAO,KAAK,CAAC;AAExD;;;ACtGA,MAAM,UAAU;AAEhB,MAAM,aAAa,CAAC,gBAAgB,aAAa;AAEjD,SAAS,eAAe,MAA8B;CACpD,IAAI,WAAW,KAAK,MAAM,gBAAgB,CAAC,GAAG,OAAO;CACrD,IAAI,WAAW,KAAK,MAAM,WAAW,CAAC,GAAG,OAAO;CAChD,IAAI,WAAW,KAAK,MAAM,UAAU,CAAC,KAAK,WAAW,KAAK,MAAM,WAAW,CAAC,GAAG,OAAO;CACtF,IAAI,WAAW,KAAK,MAAM,mBAAmB,CAAC,GAAG,OAAO;CACxD,MAAM,QAAQ,QAAQ,IAAI,yBAAyB;CACnD,IAAI,MAAM,WAAW,MAAM,GAAG,OAAO;CACrC,IAAI,MAAM,WAAW,KAAK,GAAG,OAAO;CACpC,IAAI,MAAM,WAAW,MAAM,GAAG,OAAO;CACrC,OAAO;AACT;AAEA,SAAS,eACP,SACA,UACA,KACqC;CACrC,MAAM,OAAO,MAAO,YAAY,QAAQ,eAAe,OAAQ;CAE/D,OAAO;EACL,SAAS;EACT,MAAM;GAHK,YAAY,QAAQ,YAAY;GAG9B,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI;GAAI,GAAG;EAAQ;CAC1D;AACF;AAEA,eAAe,QAAQ,UAAkB,IAA0B;CACjE,IAAI,CAAC,QAAQ,MAAM,OAAO;EACxB,GAAG,IAAI,GAAG,SAAS,gEAAgE;EACnF,OAAO;CACT;CACA,MAAM,KAAK,gBAAgB;EAAE,OAAO,QAAQ;EAAO,QAAQ,QAAQ;CAAO,CAAC;CAC3E,IAAI;EACF,MAAM,UAAU,MAAM,GAAG,SAAS,GAAG,SAAS,QAAQ,EAAA,CAAG,KAAK,CAAC,CAAC,YAAY;EAC5E,OAAO,WAAW,MAAM,WAAW,OAAO,WAAW;CACvD,UAAU;EACR,GAAG,MAAM;CACX;AACF;AAEA,SAASA,MAAI,SAAiB,MAAyB,KAAa,IAAc;CAChF,GAAG,IAAI,KAAK,QAAQ,GAAG,KAAK,KAAK,GAAG,GAAG;CACvC,MAAM,SAAS,UAAU,SAAS,CAAC,GAAG,IAAI,GAAG;EAAE;EAAK,OAAO;CAAU,CAAC;CACtE,IAAI,OAAO,UAAU,KAAA,KAAc,OAAO,WAAW,QAAQ,OAAO,WAAW,GAC7E,MAAM,IAAI,SAAS,KAAK,QAAQ,GAAG,KAAK,KAAK,GAAG,EAAE,6CAA6C;AAEnG;AAUA,SAAS,SAAS,MAA0C;CAC1D,IAAI;EACF,OAAO,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;CAC9C,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,QAAQ,KAAsB;CACrC,MAAM,MAAM,SAAS,KAAK,KAAK,cAAc,CAAC;CAC9C,IAAI,QAAQ,MAAM,MAAM,IAAI,SAAS,sBAAsB,IAAI,gCAAgC;CAC/F,MAAM,OAAO;EAAE,GAAG,IAAI;EAAc,GAAG,IAAI;CAAgB;CAC3D,MAAM,MAAM,WAAW,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,IAAI;CAC9D,MAAM,SAAS,CAAC,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,QAAQ,WAAW,GAAG,CAAC,KAAK;CACtF,OAAO;EACL,MAAM;EACN;EACA,WAAW,KAAK,SAAS,KAAA,IAAY,SAAS,KAAK,SAAS,KAAA,IAAY,SAAS;EACjF,cAAc,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC;EACvC;CACF;AACF;AAEA,SAAS,MAAM,MAAc,UAAkB,IAAiB;CAC9D,IAAI,WAAW,IAAI,GAAG;EACpB,GAAG,IAAI,QAAQ,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,sBAAsB;EACnE,OAAO;CACT;CACA,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAC5C,cAAc,MAAM,QAAQ;CAC5B,GAAG,IAAI,WAAW,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,EAAE;CAClD,OAAO;AACT;AAEA,MAAM,aAAa;;;;;;;;;;;AAYnB,SAAS,WAAW,QAAuC;CASzD,OAAO,GAHL,WAAW,WACP,kGACA,qHACY;;;;;;;;;;;;;;;;EAPhB,WAAW,WACP,0CACA,iIAqBH;;;;;;;;;;;;;;;;AAgBL;AAKA,SAAS,eAAe,MAAc,IAAc;CAClD,MAAM,OAAO,KAAK,MAAM,eAAe;CACvC,IAAI,CAAC,WAAW,IAAI,GAAG;CACvB,MAAM,OAAO,SAAS,IAAI;CAC1B,MAAM,UAAW,MAAM,mBAAmB,CAAC;CAC3C,IACE,QAAQ,+BAA+B,QACvC,QAAQ,oCAAoC,MAE5C;CAEF,MAAM,OACJ,QAAQ,WAAW,OAAO,+BAA+B;CAC3D,IAAI,SAAS,MAAM;EACjB,GAAG,IACD,QAAQ,KAAK,8EACf;EACA;CACF;CACA,KAAK,kBAAkB;EAAE,GAAG;GAAU,OAAO;CAAK;CAClD,cAAc,MAAM,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,GAAG;CACxD,GAAG,IAAI,OAAO,KAAK,gDAAgD;AACrE;AAIA,SAAS,UAAU,MAA6B;CAC9C,MAAM,WAAW,cAAc,KAAK,OAAO,SAAS,KAAK,MAAM,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC;CAChG,MAAM,QAAQ,eAAe,KAAK,QAAQ,IAAI,yBAAyB,EAAE;CACzE,MAAM,UACJ,WAAW,MACX,QAAQ,MACR,WAAW,KACT,UAAU,QAAQ,CAAC,WAAW,GAAG;EAAE,KAAK;EAAM,UAAU;CAAO,CAAC,CAAC,CAAC,UAAU,EAC9E,CAAC,GAAG;CACN,OAAO,YAAY,KAAA,IAAY,OAAO,OAAO,OAAO;AACtD;AAGA,SAAS,cAAc,MAAsB;CAC3C,KAAK,IAAI,MAAM,MAAM,QAAQ,GAAG,MAAM,KAAK,MAAM,QAAQ,GAAG,GAC1D,IAAI,WAAW,KAAK,KAAK,qBAAqB,CAAC,GAAG,OAAO,KAAK,KAAK,qBAAqB;CAE1F,OAAO,KAAK,MAAM,qBAAqB;AACzC;AAKA,SAAS,aAAa,MAAc,IAAc;CAChD,MAAM,QAAQ,UAAU,IAAI;CAC5B,IAAI,UAAU,QAAQ,QAAQ,IAAI;CAClC,MAAM,OAAO,cAAc,IAAI;CAC/B,MAAM,OAAO,SAAS,QAAQ,IAAI,GAAG,IAAI;CACzC,MAAM,MAAM,QAAQ,MAAM;CAC1B,IAAI,CAAC,WAAW,IAAI,GAAG;EACrB,cAAc,MAAM,iCAAiC;EACrD,GAAG,IAAI,WAAW,KAAK,oCAAoC,IAAI,EAAE;EACjE;CACF;CACA,MAAM,OAAO,aAAa,MAAM,MAAM;CACtC,MAAM,MAAM,KAAK,SAAS,MAAM,IAAI,SAAS;CAC7C,MAAM,QAAQ,KAAK,MAAM,OAAO;CAChC,MAAM,WAAW,SACf,KACG,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC,CAAC,CAC5B,QAAQ,cAAc,EAAE,CAAC,CACzB,KAAK;CACV,MAAM,MAAM,MAAM,WAAW,SAAS,mBAAmB,KAAK,IAAI,CAAC;CACnE,IAAI,QAAQ,IAAI;EACd,IAAI,MAAM,GAAG,EAAE,MAAM,IAAI,MAAM,IAAI;EACnC,MAAM,KAAK,GAAI,MAAM,WAAW,IAAI,CAAC,IAAI,CAAC,EAAE,GAAI,gBAAgB,mBAAmB,EAAE;CACvF,OAAO,IAAI,QAAQ,MAAM,IAAK,MAAM,IAAI;EAEtC,IAAI,CAAC,cAAc,KAAK,MAAM,IAAK,GACjC,GAAG,IAAI,uCAAuC,KAAK,IAAI,IAAI,EAAE;EAC/D;CACF,OAAO;EACL,IAAI,MAAM,MAAM;EAChB,OAAO,MAAM,MAAM,UAAU,YAAY,KAAK,MAAM,IAAK,GAAG;EAC5D,MAAM,QAAQ,MAAM,MAAM,MAAM,GAAG,GAAG;EACtC,MAAM,QAAQ,MAAM,WAAW,SAAS,2BAA2B,KAAK,IAAI,CAAC;EAC7E,IAAI,UAAU,IAAI;GAChB,MAAM,SAAS,MAAM,KAAK,SAAS,eAAe,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,OAAO,KAAK;GACpF,MAAM,OAAO,MAAM,GAAG,GAAG,GAAG,OAAO,cAAc;EACnD,OAAO;GAEL,IAAI,kBAAkB,KAAK,QAAQ,MAAM,MAAO,CAAC,GAAG;GACpD,MAAM,MAAM,IAAI,SAAS,GAAG,OAAO,KAAK,MAAM,MAAO,CAAC,CAAE,GAAG;EAC7D;CACF;CACA,cAAc,MAAM,MAAM,KAAK,GAAG,CAAC;CACnC,GAAG,IAAI,qCAAqC,KAAK,IAAI,IAAI,EAAE;AAC7D;AAEA,MAAM,QAAQ;;;;;;;;;;;AAYd,eAAsB,KACpB,KACA,IACA,SACe;CACf,MAAM,UAAU,QAAQ,GAAG;CAC3B,MAAM,SAAS,QAAQ,WAAW,aAAa,aAAa;CAI5D,IAAI,MAAM,KAAK,QAAQ,KAAK,kBAAkB,GAAG,WAAW,MAAM,GAAG,EAAE,GACrE,MAAM,KAAK,QAAQ,KAAK,UAAU,eAAe,UAAU,GAAG,YAAY,EAAE;CAE9E,eAAe,QAAQ,MAAM,EAAE;CAE/B,IAAI,QAAQ,cAAc,UAAU,QAAQ,WAAW,MACrD,MAAM,KAAK,QAAQ,QAAQ,OAAO,aAAa,UAAU,GAAG,OAAO,EAAE;CAEvE,gBAAgB,QAAQ,MAAM,EAAE;CAEhC,MAAM,UAAU,eAAe,QAAQ,IAAI;CAC3C,IAAI,YAAY,QAAQ,aAAa,QAAQ,MAAM,EAAE;CACrD,MAAM,oBAAoB,SAAS,SAAS,QAAQ,IAAI,OAAO;CAE/D,GAAG,IAAI,EAAE;CACT,GAAG,IAAI,OAAO;CACd,GAAG,IACD,qIACF;CACA,GAAG,IACD,WAAW,KAAK,QAAQ,MAAM,UAAU,YAAY,CAAC,IACjD,4EACA,mEACN;CACA,IAAI,QAAQ,cAAc,QACxB,GAAG,IACD,yFACF;CAIF,IAAI,QAAQ,cAAc,QAAQ;EAChC,GAAG,IACD,yFACF;EACA,MAAM,aAAa,WAAW,QAAQ,SAAS,CAAC,QAAQ,aAAa,IAAI,IAAI,CAAC;EAC9E,MAAM,MAAM,eAAe,SAAS,YAAY,KAAK;EACrD,MAAM,UAAU,WAAW,WAAW,IAAI,KAAK,KAAK,IAAI,QAAQ,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;EACtF,GAAG,IACD,4CAA4C,QAAQ,wFACtD;CACF;AACF;AAEA,eAAe,oBACb,SACA,SACA,QACA,IACA,SACe;CACf,MAAM,OAAO;EACX;EACA;EACA,WAAW,WAAW,yBAAyB;EAE/C,GAAI,QAAQ,cAAc,SAAS,aAAa,CAAC;CACnD;CACA,MAAM,MAAM,CAAC,aAAa;CAC1B,MAAM,QAAQ,SAAkB,KAAK,WAAW,UAAU,IAAI,GAAG,KAAK,GAAG,YAAY;CACrF,MAAM,UAAU,KAAK,QAAQ,SAAS,CAAC,QAAQ,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI;CAC/E,MAAM,aAAa,IAAI,QAAQ,SAAS,CAAC,QAAQ,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI;CACjF,IAAI,QAAQ,WAAW,KAAK,WAAW,WAAW,GAAG;CAErD,MAAM,QAAQ,CACZ,GAAI,QAAQ,WAAW,IAAI,CAAC,IAAI,CAAC,eAAe,SAAS,SAAS,KAAK,CAAC,GACxE,GAAI,WAAW,WAAW,IAAI,CAAC,IAAI,CAAC,eAAe,SAAS,YAAY,IAAI,CAAC,CAC/E;CACA,GAAG,IAAI,EAAE;CACT,GAAG,IAAI,mBAAmB;CAC1B,KAAK,MAAM,QAAQ,OAAO,GAAG,IAAI,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK,KAAK,GAAG,GAAG;CAE3E,IAAI,QAAQ,gBAAgB,MAAM;CAElC,IAAI,EADO,QAAQ,QAAQ,QAAS,MAAM,QAAQ,qBAAqB,QAAQ,IAAI,EAAE,IAC5E;CACT,KAAK,MAAM,QAAQ,OAAO,MAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,MAAM,EAAE;AACzE;;;AC9VA,SAAS,OAAO,MAAsB;CACpC,OAAO,KAAK,QAAQ,mBAAmB,GAAG,IAAI,SAAiB,KAAK,YAAY,CAAC;AACnF;AAEA,SAAS,MAAM,MAAsB;CACnC,MAAM,QAAQ,OAAO,IAAI;CACzB,OAAO,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC;AACtD;AAGA,SAAS,eAAe,QAAsB,OAAwB;CACpE,IAAI,UAAU,KAAA,GAAW,OAAO,WAAW,KAAK,IAAI,QAAQ,QAAQ,QAAQ,IAAI,GAAG,KAAK;CACxF,MAAM,aAAa,CAAC,KAAK,OAAO,KAAK,UAAU,aAAa,GAAG,KAAK,OAAO,KAAK,aAAa,CAAC;CAC9F,OAAO,WAAW,MAAM,QAAQ,WAAW,GAAG,CAAC,KAAK,WAAW;AACjE;AAIA,SAAS,SAAS,MAAc,QAAyB;CACvD,OAAO;;;eAGM,MAAM,IAAI,EAAE,iBAAiB,MAAM,IAAI,EAAE;;;;MAIlD,SAAS,sBAAsB,GAAG;;;;;;;AAOxC;AAEA,SAAS,WAAW,MAAc,IAAoB;CACpD,MAAM,OAAO,SAAS,MAAM,EAAE,CAAC,CAAC,WAAW,MAAM,GAAG;CACpD,OAAO,KAAK,WAAW,GAAG,IAAI,OAAO,KAAK;AAC5C;AAIA,SAAS,SAAS,QAAsB,MAAc,MAAc,IAAc;CAChF,MAAM,SAAS,aAAa,OAAO,MAAM,MAAM;CAC/C,MAAM,YAAY,WAAW,OAAO,KAAK,IAAI,CAAC,CAAC,QAAQ,SAAS,KAAK;CACrE,MAAM,OAAO,YAAY,MAAM,IAAI,EAAE,WAAW,UAAU;CAC1D,MAAM,OAAO,8BAA8B,KAAK,MAAM;CACtD,IAAI,OAAO,SAAS,IAAI,KAAK,SAAS,MAAM;EAC1C,GAAG,IAAI,uBAAuB;EAC9B,GAAG,IAAI,KAAK,MAAM;EAClB,GAAG,IAAI,uBAAuB,MAAM,IAAI,EAAE,GAAG;EAC7C;CACF;CACA,MAAM,UAAU,KAAK,EAAE,CAAE,KAAK;CAC9B,MAAM,UAAU,OACb,QAAQ,sCAAsC,KAAK,KAAK,GAAG,CAAC,CAC5D,QACC,+BACA,iBAAiB,YAAY,KAAK,KAAK,GAAG,QAAQ,QAAQ,SAAS,EAAE,EAAE,MAAM,MAAM,IAAI,EAAE,EAC3F;CACF,cAAc,OAAO,MAAM,OAAO;CAClC,GAAG,IAAI,oBAAoB,SAAS,QAAQ,IAAI,GAAG,OAAO,IAAI,EAAE,EAAE;AACpE;AAEA,SAAS,eAAe,MAAsB;CAC5C,MAAM,KAAK,MAAM,IAAI;CACrB,MAAM,QAAQ,GAAG,OAAO,IAAI,EAAE;CAC9B,MAAM,UAAU,GAAG,OAAO,IAAI,EAAE;CAChC,OAAO;;;;cAIK,QAAQ,OAAO,GAAG;;;YAGpB,MAAM;gDAC8B,GAAG;+CACJ,GAAG;;;kBAGhC,GAAG;;WAEV,GAAG;;wBAEU,QAAQ;sBACV,MAAM;;oBAER,GAAG;uCACgB,GAAG;sCACJ,GAAG;;;;;;AAMzC;AAEA,SAAgB,WACd,QACA,IACA,MACA,SACM;CACN,IAAI,CAAC,sBAAsB,KAAK,IAAI,GAClC,MAAM,IAAI,SAAS,IAAI,KAAK,2DAA2D;CAEzF,MAAM,MACJ,QAAQ,QAAQ,KAAA,IACZ,KAAK,OAAO,KAAK,UAAU,SAAS,IACpC,WAAW,QAAQ,GAAG,IACpB,QAAQ,MACR,QAAQ,QAAQ,IAAI,GAAG,QAAQ,GAAG;CAC1C,MAAM,OAAO,KAAK,KAAK,GAAG,MAAM,IAAI,EAAE,IAAI;CAC1C,IAAI,WAAW,IAAI,GAAG,MAAM,IAAI,SAAS,GAAG,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,gBAAgB;CAC1F,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;CAClC,cAAc,MAAM,eAAe,IAAI,CAAC;CACxC,GAAG,IAAI,WAAW,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,EAAE;CAClD,GAAG,IAAI,2BAA2B;CAClC,GAAG,IAAI,cAAc,MAAM,IAAI,EAAE,aAAa,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG,EAAE,EAAE;CACjG,GAAG,IAAI,sDAAsD,MAAM,IAAI,EAAE,QAAQ;AACnF;AAEA,SAAgB,eACd,QACA,IACA,MACA,SACM;CACN,IAAI,CAAC,sBAAsB,KAAK,IAAI,GAClC,MAAM,IAAI,SAAS,IAAI,KAAK,+DAA+D;CAE7F,MAAM,MAAM,eAAe,QAAQ,QAAQ,GAAG;CAC9C,MAAM,OAAO,KAAK,KAAK,GAAG,MAAM,IAAI,EAAE,IAAI;CAC1C,IAAI,WAAW,IAAI,GAAG,MAAM,IAAI,SAAS,GAAG,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,gBAAgB;CAC1F,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAC5C,MAAM,SAAS,OAAO,OAAO,WAAW,QAAQ,MAAM,WAAW,OAAO,OAAO,aAAa;CAC5F,cAAc,MAAM,SAAS,MAAM,MAAM,CAAC;CAC1C,GAAG,IAAI,WAAW,SAAS,QAAQ,IAAI,GAAG,IAAI,EAAE,EAAE;CAClD,SAAS,QAAQ,MAAM,MAAM,EAAE;CAC/B,GAAG,IAAI,wEAAwE;AACjF;;;ACzIA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4Bb,MAAM,UAAU;;;;;;;;;AAUhB,MAAM,UAAU;CACd,QAAQ,EAAE,MAAM,SAAS;CACzB,MAAM,EAAE,MAAM,SAAS;CACvB,KAAK,EAAE,MAAM,SAAS;CACtB,QAAQ,EAAE,MAAM,SAAS;CACzB,MAAM,EAAE,MAAM,SAAS;CACvB,MAAM,EAAE,MAAM,SAAS;CACvB,OAAO,EAAE,MAAM,SAAS;CACxB,MAAM,EAAE,MAAM,SAAS;CACvB,OAAO,EAAE,MAAM,UAAU;CACzB,QAAQ,EAAE,MAAM,UAAU;CAC1B,OAAO,EAAE,MAAM,UAAU;CACzB,YAAY,EAAE,MAAM,UAAU;CAC9B,gBAAgB,EAAE,MAAM,UAAU;CAClC,KAAK,EAAE,MAAM,UAAU;CACvB,MAAM,EAAE,MAAM,UAAU;AAC1B;AAEA,SAAS,KAAK,KAA6C;CACzD,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAA;CAC9B,IAAI,CAAC,QAAQ,KAAK,GAAG,GAAG,MAAM,IAAI,SAAS,yBAAyB;CACpE,OAAO,OAAO,GAAG;AACnB;AAEA,eAAsB,IAAI,MAAyB,KAAS,WAAW,MAAM,QAAQ,IAAI,GAAG;CAC1F,MAAM,EAAE,QAAQ,gBAAgB,UAAU;EACxC,MAAM,CAAC,GAAG,IAAI;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;CACV,CAAC;CACD,MAAM,CAAC,OAAO,SAAS,YAAY;CAEnC,IAAI,UAAU,KAAA,KAAa,OAAO,SAAS,MAAM;EAC/C,GAAG,IAAI,UAAU,OAAO,UAAU,IAAI;EACtC;CACF;CAEA,MAAM,SAAS,YAAY,WAAW,KAAK,OAAO,MAAM;CAExD,QAAQ,GAAG,MAAM,GAAG,WAAW,KAAK,KAAK,GAAzC;EACE,KAAK,WACH,OAAOC,KAAQ,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,OAAO,MAAM,CAAC;EAC5D,KAAK,eACH,OAAOC,SAAY,MAAM,OAAO,GAAG,IAAI,EAAE,MAAM,OAAO,KAAK,CAAC;EAC9D,KAAK,cACH,OAAOC,QAAW,MAAM,OAAO,GAAG,EAAE;EACtC,KAAK,WACH,OAAOC,KAAQ,MAAM,OAAO,GAAG,IAAI;GACjC,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,OAAO,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO,OAAO,KAAK;GACnE,MAAM,OAAO,SAAS,KAAA,IAAY,KAAA,IAAY,OAAO,OAAO,IAAI;GAChE,OAAO,OAAO;GACd,SAAS,OAAO;EAClB,CAAC;EACH,KAAK,aACH,OAAOC,OAAU,MAAM,OAAO,GAAG,EAAE;EACrC,KAAK,aACH,OAAOC,OAAU,MAAM,OAAO,GAAG,IAAI,EAAE,MAAM,KAAK,OAAO,IAAI,EAAE,CAAC;EAClE,KAAK;GACH,GAAG,IAAI,OAAO;GACd;EACF,KAAK;GACH,IAAI,aAAa,KAAA,GAAW,MAAM,IAAI,SAAS,sCAAsC;GACrF,OAAO,eAAe,MAAM,OAAO,GAAG,IAAI,UAAU,EAAE,KAAK,OAAO,IAAI,CAAC;EAEzE,KAAK;GACH,IAAI,aAAa,KAAA,GAAW,MAAM,IAAI,SAAS,kCAAkC;GACjF,OAAO,WAAW,MAAM,OAAO,GAAG,IAAI,UAAU,EAAE,KAAK,OAAO,IAAI,CAAC;EAErE,KAAK,QACH,MAAM,IAAI,SAAS,6CAA6C;EAClE,KAAK,QACH,OAAO,KAAK,KAAK,IAAI;GACnB,QAAQ,OAAO;GACf,KAAK,OAAO;GACZ,aAAa,OAAO;EACtB,CAAC;EACH,SACE,MAAM,IAAI,SACR,oBAAoB,CAAC,OAAO,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,EAAE,0BACjE;CACJ;AACF;AAEA,eAAsB,KAAK,MAA0C;CACnE,IAAI;EACF,MAAM,IAAI,IAAI;EACd,OAAO;CACT,SAAS,OAAO;EAEd,IAAI,iBAAiB,YAAY,iBAAiB,aAAa;GAC7D,QAAQ,MAAM,MAAM,OAAO;GAC3B,OAAO;EACT;EACA,QAAQ,MAAM,KAAK;EACnB,OAAO;CACT;AACF"}
@@ -1436,9 +1436,11 @@ interface HookTypion extends RegisteredHook {}
1436
1436
  type RegisteredHook = [Registered] extends [never] ? {} : Omit<TypionApp<RegisteredTypes, 'user'>, '$mode'> & {
1437
1437
  readonly $mode: TypionMode;
1438
1438
  };
1439
- type ContextFactory<TCtx> = (input: ContextInput & {
1439
+ type ContextFactoryInput = ContextInput & {
1440
1440
  system: SystemTypion;
1441
- }) => MaybePromise<TCtx>;
1441
+ db: AnyDb;
1442
+ };
1443
+ type ContextFactory<TCtx> = (input: ContextFactoryInput) => MaybePromise<TCtx>;
1442
1444
  type TypionConfig<TE extends TypionTypes> = {
1443
1445
  readonly '~types'?: TE;
1444
1446
  readonly definition: TypionDefinition<TE>;
@@ -2094,5 +2096,5 @@ type ContextInput = {
2094
2096
  type Ctx<TE extends TypionTypes> = BaseContext & TE['ctx'] & PluginContext<TE['plugins']>;
2095
2097
  type FullCtx<TCtx extends object, P extends readonly AnyPlugin[]> = BaseContext & TCtx & PluginContext<P>;
2096
2098
  //#endregion
2097
- export { AfterChangeArgs as $, InferResult as $a, RequirementsError as $i, MultiTenantPlugin as $n, NullableTimestampKeys as $r, RegisteredContext as $t, Dialect as A, ConfigError as Aa, CollectionSpec as Ai, defineSetup as An, CreateInput as Ar, VersionsTraits as At, EntityMeta as B, PluginError as Ba, PluginContext as Bi, SoftDeleteKinds as Bn, FieldRefinements as Br, ConfigOptions as Bt, WireBatchEnvelope as C, ReadModeOf as Ca, VirtualColumn as Ci, AnySetup as Cn, Jsonified as Cr, VersionsEntityOptions as Ct, WireErrorCode as D, WriteModeOf as Da, AnyPlugin as Di, SetupOptions as Dn, TraitQueries as Dr, VersionsOption as Dt, WireError as E, WriteModeFn as Ea, AnyFeatureTables as Ei, SetupLocalization as En, TraitOptions as Er, VersionsListOptions as Et, AnyTx as F, ForbiddenError as Fa, MergeAll as Fi, versionsTable as Fn, EntityDef as Fr, ByName as Ft, AllowAll as G, UnsupportedError as Ga, PluginErrorFactories as Gi, softDeleteColumn as Gn, LinkApi as Gr, DbAdapter as Gt, RelationMeta as H, TypionError as Ha, PluginEntityDefiner as Hi, SoftDeleteQueries as Hn, HiddenWriteKeys as Hr, ConfigTables as Ht, AnyTypion as I, ForbiddenErrorOptions as Ia, MergeConfigs as Ii, SoftDeleteApi as In, EntityOptions as Ir, Collection as It, OperationMeta as J, attempt as Ja, PluginNeedsContext as Ji, MultiTenantCollectionOptions as Jn, LinkQueries as Jr, HookTypion as Jt, AnyAccessRules as K, ValidationError as Ka, PluginErrorInput as Ki, softUnique as Kn, LinkInput as Kr, FoldKinds as Kt, AnyTypionApp as L, InternalError as La, Plugin as Li, SoftDeleteCollectionOptions as Ln, EntitySchemas as Lr, CollectionDraft as Lt, AfterCommitQueue as M, ConflictError as Ma, DependenciesError as Mi, FeaturePlugins as Mn, DeleteOptions as Mr, AfterCommitErrorHandler as Mt, AnyDb as N, ConflictErrorOptions as Na, FeatureId as Ni, FeaturesOptions as Nn, EntitiesOf$1 as Nr, AnyCollection as Nt, WireErrorEnvelope as O, Attempt as Oa, AnyPluginSpec as Oi, SetupPlugins as On, AnyEntities as Or, VersionsReadOptions as Ot, AnyRow as P, ConflictKind as Pa, FeatureTables as Pi, VersionsPlugin as Pn, EntityApi as Pr, Behaviour as Pt, RuleSchema as Q, InferItem as Qa, PluginTables as Qi, MultiTenantOptions as Qn, NoneIfEmpty as Qr, OneSpec as Qt, ValidationAdapter as R, InvalidStateError as Ra, PluginApis as Ri, SoftDeleteDeleteOptions as Rn, EntityValidation as Rr, CollectionRuntime as Rt, ErrorStatus as S, ReadModeFn as Sa, VS as Si, defineConfig as Sn, collection as Sr, VersionsCreateOptions as St, WireEnvelope as T, ValidationMode as Ta, VirtualTable as Ti, Setup as Tn, timestamps as Tr, VersionsKinds as Tt, TypionDefinition as U, TypionErrorCode as Ua, PluginEntityOptions as Ui, SoftDeleteReadOptions as Un, Id$1 as Ur, ConfigTypes as Ut, GeneratedTables as V, PluginErrorOptions as Va, PluginEntities as Vi, SoftDeletePlugin as Vn, FieldRuleArgs as Vr, ConfigSeedOptions as Vt, AccessRules as W, TypionErrorOptions as Wa, PluginErrorDef as Wi, SoftDeleteTraits as Wn, Insert as Wr, ContextFactory as Wt, RuleArgs as X, AnyDescriptor as Xa, PluginRuntime as Xi, MultiTenantEntityOptions as Xn, ManagedKeys as Xr, MigrationsOptions as Xt, RawWhere as Y, isTypionError as Ya, PluginRoute as Yi, MultiTenantContext as Yn, LinkQueryMethods as Yr, ManySpec as Yt, RuleData as Z, Descriptor as Za, PluginSpec as Zi, MultiTenantKinds as Zn, NoExtraKeys as Zr, NoUnknownKeys as Zt, TransportCall as _, KindedData as _a, Result as _i, GetTypionOptions as _n, localizedUnique as _r, Version as _t, MaybePromise as a, ColumnKindRuntime as aa, UpdateManyOptions as ai, StructureInput as an, TextTenantColumn as ar, HookBase as at, TransportSchema as b, PluginReadOptions as ba, Governed as bi, allowAll as bn, PluginSpecInput as br, VersionState as bt, CorsOptions as c, ColumnKindsSpec as ca, ByIdConfig as ci, ThroughSpec as cn, LocaleReadMode as cr, TypionHookApp as ct, HandlerOptions as d, KeyedShape as da, FindConfig as di, TypionAppOf as dn, LocalizationPlugin as dr, DraftsApi as dt, SeedColumnsInput as ea, ReadRow as ei, RegisteredPlugins as en, Op as eo, MultiTenantSystemOptions as er, ChangeArgs as et, TypionApp as f, KindOf as fa, FirstConfig as fi, TypionConfig as fn, LocalizationReadMode as fr, DraftsQueries as ft, Transport as g, Kinded as ga, ReadOptions as gi, structuralValidation as gn, localizedIndex as gr, PendingDraftPolicy as gt, CheckedDescriptor as h, KindWriteOptions as ha, Page as hi, StructuralValidationAdapter as hn, localized as hr, HistoryQueries as ht, FullCtx as i, COLUMN_KIND as ia, UpdateInput as ii, RelationSpec as in, descriptor as io, TenantIdOf as ir, GlobalHooks as it, SchemaDrift as j, ConfigErrorKind as ja, ColumnKind as ji, DefaultFeaturePlugins as jn, CreateOptions as jr, VersionsUpdateOptions as jt, WireIssue as k, BadRequestError as ka, CollectionKinds as ki, TypionSetup as kn, ColumnKeys as kr, VersionsRestoreOptions as kt, DescriptorApi as l, ColumnKindsTypes as la, CountConfig as li, TypesOf as ln, LocalizationColumnKinds as lr, TypionHookEntityApi as lt, TypionTypes as m, KindWrite as ma, OrderBy as mi, StructuralSchema as mn, Localized as mr, HistoryApi as mt, ContextInput as n, SeedSpec as na, Row as ni, RegisteredTypes as nn, ReadOp as no, TenantColumnOf as nr, CreateInput_ as nt, TypionMode as o, ColumnKindSpec as oa, UpdateOptions as oi, SystemTypion as on, UuidTenantColumn as or, Insert_ as ot, TypionEngine as p, KindRead as pa, InputSchema as pi, Register as pn, LocalizationWriteMode as pr, FieldDiff as pt, Operation as q, ValidationIssue as qa, PluginKinds as qi, IntegerTenantColumn as qn, LinkMethods as qr, HandlerOptionsOf as qt, Ctx as r, TableShape as ra, Select as ri, RelationHelpers as rn, WriteOp as ro, TenantContext as rr, EntityHooks as rt, BindOptions as s, ColumnKindTypes as sa, WriteOptions as si, TableOf as sn, tenantColumn as sr, Select_ as st, BaseContext as t, SeedGenerators as ta, ReferenceOptions as ti, RegisteredSetup as tn, RESULT as to, MultiTenantTraits as tr, ChangeOp as tt, EntityName as u, InputModeOf as ua, Extend as ui, Typion as un, LocalizationOptions as ur, UpdateInput_ as ut, TransportEntity as v, OptionType as va, Where as vi, getTypion as vn, localizedValue as vr, VersionOperation as vt, WireDataEnvelope as w, TableMode as wa, VirtualRelation as wi, DefaultSetup as wn, defaultIdColumn as wr, VersionsHookArgs as wt, ERROR_STATUS as x, PluginSystemOptions as xa, HiddenReadKeys as xi, dbAdapter as xn, definePlugin as xr, VersionsCollectionOptions as xt, TransportOperation as y, PluginContextOptions as ya, DynamicReadKeys as yi, AfterCommitErrorInfo as yn, DefinedPlugin as yr, VersionRef as yt, ColumnMeta as z, NotFoundError as za, PluginCollectionOptions as zi, SoftDeleteEntityOptions as zn, FieldOptions as zr, ColumnsOf as zt };
2098
- //# sourceMappingURL=context-CpLQy7OI.d.ts.map
2099
+ export { AfterChangeArgs as $, InferItem as $a, PluginTables as $i, MultiTenantOptions as $n, NoneIfEmpty as $r, OneSpec as $t, Dialect as A, BadRequestError as Aa, CollectionKinds as Ai, TypionSetup as An, ColumnKeys as Ar, VersionsTraits as At, EntityMeta as B, NotFoundError as Ba, PluginCollectionOptions as Bi, SoftDeleteEntityOptions as Bn, FieldOptions as Br, ConfigOptions as Bt, WireBatchEnvelope as C, ReadModeFn as Ca, VS as Ci, defineConfig as Cn, collection as Cr, VersionsEntityOptions as Ct, WireErrorCode as D, WriteModeFn as Da, AnyFeatureTables as Di, SetupLocalization as Dn, TraitOptions as Dr, VersionsOption as Dt, WireError as E, ValidationMode as Ea, VirtualTable as Ei, Setup as En, timestamps as Er, VersionsListOptions as Et, AnyTx as F, ConflictKind as Fa, FeatureTables as Fi, VersionsPlugin as Fn, EntityApi as Fr, ByName as Ft, AllowAll as G, TypionErrorOptions as Ga, PluginErrorDef as Gi, SoftDeleteTraits as Gn, Insert as Gr, ContextFactoryInput as Gt, RelationMeta as H, PluginErrorOptions as Ha, PluginEntities as Hi, SoftDeletePlugin as Hn, FieldRuleArgs as Hr, ConfigTables as Ht, AnyTypion as I, ForbiddenError as Ia, MergeAll as Ii, versionsTable as In, EntityDef as Ir, Collection as It, OperationMeta as J, ValidationIssue as Ja, PluginKinds as Ji, IntegerTenantColumn as Jn, LinkMethods as Jr, HandlerOptionsOf as Jt, AnyAccessRules as K, UnsupportedError as Ka, PluginErrorFactories as Ki, softDeleteColumn as Kn, LinkApi as Kr, DbAdapter as Kt, AnyTypionApp as L, ForbiddenErrorOptions as La, MergeConfigs as Li, SoftDeleteApi as Ln, EntityOptions as Lr, CollectionDraft as Lt, AfterCommitQueue as M, ConfigErrorKind as Ma, ColumnKind as Mi, DefaultFeaturePlugins as Mn, CreateOptions as Mr, AfterCommitErrorHandler as Mt, AnyDb as N, ConflictError as Na, DependenciesError as Ni, FeaturePlugins as Nn, DeleteOptions as Nr, AnyCollection as Nt, WireErrorEnvelope as O, WriteModeOf as Oa, AnyPlugin as Oi, SetupOptions as On, TraitQueries as Or, VersionsReadOptions as Ot, AnyRow as P, ConflictErrorOptions as Pa, FeatureId as Pi, FeaturesOptions as Pn, EntitiesOf$1 as Pr, Behaviour as Pt, RuleSchema as Q, Descriptor as Qa, PluginSpec as Qi, MultiTenantKinds as Qn, NoExtraKeys as Qr, NoUnknownKeys as Qt, ValidationAdapter as R, InternalError as Ra, Plugin as Ri, SoftDeleteCollectionOptions as Rn, EntitySchemas as Rr, CollectionRuntime as Rt, ErrorStatus as S, PluginSystemOptions as Sa, HiddenReadKeys as Si, dbAdapter as Sn, definePlugin as Sr, VersionsCreateOptions as St, WireEnvelope as T, TableMode as Ta, VirtualRelation as Ti, DefaultSetup as Tn, defaultIdColumn as Tr, VersionsKinds as Tt, TypionDefinition as U, TypionError as Ua, PluginEntityDefiner as Ui, SoftDeleteQueries as Un, HiddenWriteKeys as Ur, ConfigTypes as Ut, GeneratedTables as V, PluginError as Va, PluginContext as Vi, SoftDeleteKinds as Vn, FieldRefinements as Vr, ConfigSeedOptions as Vt, AccessRules as W, TypionErrorCode as Wa, PluginEntityOptions as Wi, SoftDeleteReadOptions as Wn, Id$1 as Wr, ContextFactory as Wt, RuleArgs as X, isTypionError as Xa, PluginRoute as Xi, MultiTenantContext as Xn, LinkQueryMethods as Xr, ManySpec as Xt, RawWhere as Y, attempt as Ya, PluginNeedsContext as Yi, MultiTenantCollectionOptions as Yn, LinkQueries as Yr, HookTypion as Yt, RuleData as Z, AnyDescriptor as Za, PluginRuntime as Zi, MultiTenantEntityOptions as Zn, ManagedKeys as Zr, MigrationsOptions as Zt, TransportCall as _, Kinded as _a, ReadOptions as _i, structuralValidation as _n, localizedIndex as _r, Version as _t, MaybePromise as a, COLUMN_KIND as aa, UpdateInput as ai, RelationSpec as an, descriptor as ao, TenantIdOf as ar, HookBase as at, TransportSchema as b, PluginContextOptions as ba, DynamicReadKeys as bi, AfterCommitErrorInfo as bn, DefinedPlugin as br, VersionState as bt, CorsOptions as c, ColumnKindTypes as ca, WriteOptions as ci, TableOf as cn, tenantColumn as cr, TypionHookApp as ct, HandlerOptions as d, InputModeOf as da, Extend as di, Typion as dn, LocalizationOptions as dr, DraftsApi as dt, RequirementsError as ea, NullableTimestampKeys as ei, RegisteredContext as en, InferResult as eo, MultiTenantPlugin as er, ChangeArgs as et, TypionApp as f, KeyedShape as fa, FindConfig as fi, TypionAppOf as fn, LocalizationPlugin as fr, DraftsQueries as ft, Transport as g, KindWriteOptions as ga, Page as gi, StructuralValidationAdapter as gn, localized as gr, PendingDraftPolicy as gt, CheckedDescriptor as h, KindWrite as ha, OrderBy as hi, StructuralSchema as hn, Localized as hr, HistoryQueries as ht, FullCtx as i, TableShape as ia, Select as ii, RelationHelpers as in, WriteOp as io, TenantContext as ir, GlobalHooks as it, SchemaDrift as j, ConfigError as ja, CollectionSpec as ji, defineSetup as jn, CreateInput as jr, VersionsUpdateOptions as jt, WireIssue as k, Attempt as ka, AnyPluginSpec as ki, SetupPlugins as kn, AnyEntities as kr, VersionsRestoreOptions as kt, DescriptorApi as l, ColumnKindsSpec as la, ByIdConfig as li, ThroughSpec as ln, LocaleReadMode as lr, TypionHookEntityApi as lt, TypionTypes as m, KindRead as ma, InputSchema as mi, Register as mn, LocalizationWriteMode as mr, HistoryApi as mt, ContextInput as n, SeedGenerators as na, ReferenceOptions as ni, RegisteredSetup as nn, RESULT as no, MultiTenantTraits as nr, CreateInput_ as nt, TypionMode as o, ColumnKindRuntime as oa, UpdateManyOptions as oi, StructureInput as on, TextTenantColumn as or, Insert_ as ot, TypionEngine as p, KindOf as pa, FirstConfig as pi, TypionConfig as pn, LocalizationReadMode as pr, FieldDiff as pt, Operation as q, ValidationError as qa, PluginErrorInput as qi, softUnique as qn, LinkInput as qr, FoldKinds as qt, Ctx as r, SeedSpec as ra, Row as ri, RegisteredTypes as rn, ReadOp as ro, TenantColumnOf as rr, EntityHooks as rt, BindOptions as s, ColumnKindSpec as sa, UpdateOptions as si, SystemTypion as sn, UuidTenantColumn as sr, Select_ as st, BaseContext as t, SeedColumnsInput as ta, ReadRow as ti, RegisteredPlugins as tn, Op as to, MultiTenantSystemOptions as tr, ChangeOp as tt, EntityName as u, ColumnKindsTypes as ua, CountConfig as ui, TypesOf as un, LocalizationColumnKinds as ur, UpdateInput_ as ut, TransportEntity as v, KindedData as va, Result as vi, GetTypionOptions as vn, localizedUnique as vr, VersionOperation as vt, WireDataEnvelope as w, ReadModeOf as wa, VirtualColumn as wi, AnySetup as wn, Jsonified as wr, VersionsHookArgs as wt, ERROR_STATUS as x, PluginReadOptions as xa, Governed as xi, allowAll as xn, PluginSpecInput as xr, VersionsCollectionOptions as xt, TransportOperation as y, OptionType as ya, Where as yi, getTypion as yn, localizedValue as yr, VersionRef as yt, ColumnMeta as z, InvalidStateError as za, PluginApis as zi, SoftDeleteDeleteOptions as zn, EntityValidation as zr, ColumnsOf as zt };
2100
+ //# sourceMappingURL=context-B4e2eREP.d.ts.map
@@ -1,4 +1,4 @@
1
- import { $a as InferResult, Ar as CreateInput, C as WireBatchEnvelope, Cr as Jsonified, D as WireErrorCode, Dr as TraitQueries, E as WireError, Er as TraitOptions, Jr as LinkQueries, Mr as DeleteOptions, O as WireErrorEnvelope, Qa as InferItem, Qr as NoneIfEmpty, S as ErrorStatus, T as WireEnvelope, U as TypionDefinition, Ua as TypionErrorCode, Ur as Id, Xa as AnyDescriptor, Za as Descriptor, Zr as NoExtraKeys, _i as Result, ai as UpdateManyOptions, ba as PluginReadOptions, ei as ReadRow, eo as Op, hi as Page, ii as UpdateInput, io as descriptor, jr as CreateOptions, k as WireIssue, m as TypionTypes, ni as Row, no as ReadOp, oi as UpdateOptions, pi as InputSchema, ro as WriteOp, to as RESULT, u as EntityName, w as WireDataEnvelope, x as ERROR_STATUS } from "../context-CpLQy7OI.js";
1
+ import { $a as InferItem, $r as NoneIfEmpty, C as WireBatchEnvelope, D as WireErrorCode, Dr as TraitOptions, E as WireError, Mr as CreateOptions, Nr as DeleteOptions, O as WireErrorEnvelope, Or as TraitQueries, Qa as Descriptor, Qr as NoExtraKeys, S as ErrorStatus, T as WireEnvelope, U as TypionDefinition, Wa as TypionErrorCode, Wr as Id, Yr as LinkQueries, Za as AnyDescriptor, ai as UpdateInput, ao as descriptor, eo as InferResult, gi as Page, io as WriteOp, jr as CreateInput, k as WireIssue, m as TypionTypes, mi as InputSchema, no as RESULT, oi as UpdateManyOptions, ri as Row, ro as ReadOp, si as UpdateOptions, ti as ReadRow, to as Op, u as EntityName, vi as Result, w as WireDataEnvelope, wr as Jsonified, x as ERROR_STATUS, xa as PluginReadOptions } from "../context-B4e2eREP.js";
2
2
  import { AnyRelations, GetTableViewFieldSelection, KnownKeysOnly } from "drizzle-orm";
3
3
  //#region src/contract/wire.d.ts
4
4
  type ColData<C> = C extends {
@@ -1,4 +1,4 @@
1
- import { Gt as DbAdapter } from "../context-CpLQy7OI.js";
1
+ import { Kt as DbAdapter } from "../context-B4e2eREP.js";
2
2
  import { PGlite } from "@electric-sql/pglite";
3
3
  //#region src/db/pglite.d.ts
4
4
  export type PgliteAdapter = DbAdapter & {
@@ -1,4 +1,4 @@
1
- import { d as HandlerOptions, m as TypionTypes, p as TypionEngine } from "./context-CpLQy7OI.js";
1
+ import { d as HandlerOptions, m as TypionTypes, p as TypionEngine } from "./context-B4e2eREP.js";
2
2
  //#region src/http/handler.d.ts
3
3
  declare function typionErrorResponse(error: unknown, options?: {
4
4
  debug?: boolean;
@@ -20,4 +20,4 @@ type RouteHandlers = {
20
20
  declare function toRouteHandlers(handler: (request: Request) => Promise<Response>): RouteHandlers;
21
21
  //#endregion
22
22
  export { typionErrorResponse as i, createHandler as n, toRouteHandlers as r, RouteHandlers as t };
23
- //# sourceMappingURL=handler-D03-rJ-t.d.ts.map
23
+ //# sourceMappingURL=handler-BWVU8TCR.d.ts.map
@@ -1,4 +1,4 @@
1
- import { dn as TypionAppOf, fn as TypionConfig, ln as TypesOf, qt as HandlerOptionsOf, ya as PluginContextOptions } from "../context-CpLQy7OI.js";
1
+ import { Jt as HandlerOptionsOf, ba as PluginContextOptions, fn as TypionAppOf, pn as TypionConfig, un as TypesOf } from "../context-B4e2eREP.js";
2
2
  import { Context, MiddlewareHandler } from "hono";
3
3
  //#region src/hono/index.d.ts
4
4
  type ContextOptionsOf<C> = PluginContextOptions<TypesOf<C>['plugins']>;
@@ -1,4 +1,4 @@
1
- import { n as getTypion } from "../typion-TJWDkHGh.js";
1
+ import { n as getTypion } from "../typion-Dh2BCSRz.js";
2
2
  import { t as createHandler } from "../handler-_87bFkbP.js";
3
3
  //#region src/hono/index.ts
4
4
  function typionRoutes(config, options) {