{"version":3,"file":"index.mjs","names":["Kysely","TailordbDialect"],"sources":["../../src/kysely/index.ts"],"sourcesContent":["/**\n * Kysely integration module for generated TailorDB code.\n *\n * Re-exports kysely and function-kysely-tailordb types through a single import path\n * to avoid phantom dependency issues with pnpm, and provides the namespace-aware\n * utility types and factory functions the code generator emits against.\n *\n * It also holds the `TailorDB*` input types, which hand-written code uses to derive\n * create/read/update shapes straight from a table or field collection. They live here\n * rather than in the main entry point because they are built out of kysely's column\n * types, which the main entry point does not otherwise depend on.\n */\n\nimport { TailordbDialect } from \"@tailor-platform/function-kysely-tailordb\";\nimport {\n  type ColumnType,\n  Kysely,\n  type Insertable,\n  type KyselyConfig,\n  type Selectable,\n  type Transaction as KyselyTransaction,\n  type Updateable,\n} from \"kysely\";\nimport type {\n  IsAutoFilledDBField,\n  IsReadOnlyDBField,\n  TailorAnyDBField,\n  TailorAnyDBType,\n} from \"#/configure/services/tailordb/types\";\nimport type { output, TypeLevelError } from \"#/types/helpers\";\n\nexport {\n  type ColumnType,\n  Kysely,\n  type KyselyConfig,\n  type Transaction,\n  type Insertable,\n  type Selectable,\n  sql,\n  type Updateable,\n} from \"kysely\";\n\nexport { TailordbDialect } from \"@tailor-platform/function-kysely-tailordb\";\n\nexport type Timestamp = ColumnType<Date, Date | string, Date | string>;\ntype ResolveSelect<T> = T extends ColumnType<infer S, unknown, unknown> ? S : T;\ntype ResolveInsert<T> = T extends ColumnType<unknown, infer I, unknown> ? I : T;\ntype ResolveUpdate<T> = T extends ColumnType<unknown, unknown, infer U> ? U : T;\nexport type ObjectColumnType<T> = ColumnType<\n  { [K in keyof T]-?: Exclude<ResolveSelect<T[K]>, undefined> },\n  { [K in keyof T]: ResolveInsert<T[K]> },\n  { [K in keyof T]: ResolveUpdate<T[K]> }\n>;\nexport type ArrayColumnType<T> = ColumnType<\n  ResolveSelect<T>[],\n  ResolveInsert<T>[],\n  ResolveUpdate<T>[]\n>;\nexport type Generated<T> =\n  T extends ColumnType<infer S, infer I, infer U>\n    ? ColumnType<S, I | undefined, U>\n    : ColumnType<T, T | undefined, T>;\n// The insert/update types carry the reason so that supplying a value fails with it,\n// instead of the bare \"does not exist\" an absent key produces. The named alias is\n// what survives in nested positions (values()/set()), where tsc elides the marker's\n// type argument and only the name reaches the user.\n// `| undefined` is what makes the column omittable; Kysely drops undefined columns\n// from the statement, so passing it explicitly is the same as leaving it out.\ntype SerialColumnMustBeOmitted = TypeLevelError<\"assigned by .serial(); remove it from the input\">;\nexport type Serial<T = string | number> = ColumnType<\n  T,\n  SerialColumnMustBeOmitted | undefined,\n  SerialColumnMustBeOmitted | undefined\n>;\n\n// Kysely composes its input types out of intersections. Flattening them keeps the\n// shape readable in assignability errors and editor tooltips.\ntype FlattenColumns<T> = { [K in keyof T]: T[K] } & {};\n\nexport type TailordbKysely<DB> = Kysely<DB>;\nexport type NamespaceDB<NS, N extends keyof NS = keyof NS> = TailordbKysely<NS[N]>;\n\n/**\n * Create a namespace-aware getDB function for generated code.\n * @returns A getDB function that creates Kysely instances for specific namespaces\n */\nexport function createGetDB<NS>() {\n  return function getDB<const N extends keyof NS & string>(\n    namespace: N,\n    config?: Omit<KyselyConfig, \"dialect\">,\n  ): TailordbKysely<NS[N]> {\n    const client = new tailordb.Client({ namespace });\n    return new Kysely<NS[N]>({\n      dialect: new TailordbDialect(client),\n      ...config,\n    });\n  };\n}\n\nexport type NamespaceTransaction<NS, K extends keyof NS | TailordbKysely<NS[keyof NS]> = keyof NS> =\n  K extends TailordbKysely<infer DB>\n    ? KyselyTransaction<DB>\n    : K extends keyof NS\n      ? KyselyTransaction<NS[K]>\n      : never;\n\nexport type NamespaceTableName<NS> = {\n  [N in keyof NS]: keyof NS[N];\n}[keyof NS];\n\nexport type NamespaceTable<NS, T extends NamespaceTableName<NS>> = {\n  [N in keyof NS]: T extends keyof NS[N] ? NS[N][T] : never;\n}[keyof NS];\n\nexport type NamespaceInsertable<NS, T extends NamespaceTableName<NS>> = FlattenColumns<\n  Insertable<NamespaceTable<NS, T>>\n>;\nexport type NamespaceSelectable<NS, T extends NamespaceTableName<NS>> = FlattenColumns<\n  Selectable<NamespaceTable<NS, T>>\n>;\nexport type NamespaceUpdateable<NS, T extends NamespaceTableName<NS>> = FlattenColumns<\n  Updateable<NamespaceTable<NS, T>>\n>;\n\n/** What the derived input types accept: a table (`typeof myTable`) or a field collection. */\ntype TailorDBColumnsSource = TailorAnyDBType | Record<string, TailorAnyDBField>;\n\ntype DBFieldsOf<T> = T extends TailorAnyDBType ? T[\"fields\"] : T;\n\n// The column mapping below mirrors the one `kyselyTypePlugin` applies when it writes a\n// table interface (`plugin/builtin/kysely-type/type-processor.ts`), so both surfaces\n// resolve a field to the same column type — including inside nested objects, where the\n// function runtime also hands back a Date for a date/datetime.\n// `example/tests/kysely-parity.ts` pins the two against each other on real generator output.\ntype DBFieldType<F> = F extends TailorAnyDBField ? F[\"_defined\"][\"type\"] : never;\ntype IsArrayDBField<F> = F extends TailorAnyDBField\n  ? F[\"_defined\"][\"array\"] extends true\n    ? true\n    : false\n  : false;\n\ntype Unwrapped<F> = Exclude<output<F>, null>;\ntype ElementOutput<F> =\n  IsArrayDBField<F> extends true\n    ? Unwrapped<F> extends readonly (infer E)[]\n      ? E\n      : Unwrapped<F>\n    : Unwrapped<F>;\n\ntype NestedFieldsOf<F> = F extends TailorAnyDBField ? F[\"fields\"] : never;\n\n// Nested props carry the same column mapping as top-level ones, so a datetime inside an\n// object also resolves to Timestamp. The optional marker matches what the output type\n// gives them, which is what the generator emits too.\n// `-readonly` because a field collection is inferred with `const`, and the generated\n// table interfaces declare their nested props mutable.\ntype NestedProps<Fields> = {\n  -readonly [K in keyof Fields as null extends output<Fields[K]> ? never : K]: DBColumn<Fields[K]>;\n} & {\n  -readonly [K in keyof Fields as null extends output<Fields[K]> ? K : never]?: DBColumn<Fields[K]>;\n};\n\n// The generator reaches for ObjectColumnType only when the object holds something whose\n// select and insert types differ: a timestamp, an optional prop, or a filled-in one.\ntype NestedNeedsColumnType<Fields> = true extends {\n  [K in keyof Fields]: DBFieldType<Fields[K]> extends \"date\" | \"datetime\"\n    ? true\n    : null extends output<Fields[K]>\n      ? true\n      : DBFieldType<Fields[K]> extends \"nested\"\n        ? NestedNeedsColumnType<NestedFieldsOf<Fields[K]>>\n        : Fields[K] extends TailorAnyDBField\n          ? IsAutoFilledDBField<Fields[K]>\n          : false;\n}[keyof Fields]\n  ? true\n  : false;\n\ntype NestedColumn<F> =\n  NestedNeedsColumnType<NestedFieldsOf<F>> extends true\n    ? ObjectColumnType<FlattenColumns<NestedProps<NestedFieldsOf<F>>>>\n    : FlattenColumns<NestedProps<NestedFieldsOf<F>>>;\n\ntype ElementColumn<F> =\n  DBFieldType<F> extends \"date\" | \"datetime\"\n    ? Timestamp\n    : DBFieldType<F> extends \"nested\"\n      ? NestedColumn<F>\n      : ElementOutput<F>;\n\n// A ColumnType cannot sit inside an array — Kysely only unwraps it at the top level of a\n// table property — so an array of them keeps the ColumnType outermost.\ntype ArrayedColumn<F> =\n  IsArrayDBField<F> extends true\n    ? ElementColumn<F> extends ColumnType<unknown, unknown, unknown>\n      ? ArrayColumnType<ElementColumn<F>>\n      : ElementColumn<F>[]\n    : ElementColumn<F>;\n\ntype NullableColumn<F> = null extends output<F> ? ArrayedColumn<F> | null : ArrayedColumn<F>;\n\ntype DBColumn<F> = F extends TailorAnyDBField\n  ? IsReadOnlyDBField<F> extends true\n    ? Serial<NullableColumn<F>>\n    : IsAutoFilledDBField<F> extends true\n      ? Generated<NullableColumn<F>>\n      : NullableColumn<F>\n  : never;\n\n// The column map the three derived types are built from. Not exported: it is how the\n// mapping is expressed, not something callers need to name.\ntype TailorDBColumns<T extends TailorDBColumnsSource> = {\n  [K in keyof DBFieldsOf<T>]: K extends \"id\"\n    ? Generated<output<DBFieldsOf<T>[K]>>\n    : DBColumn<DBFieldsOf<T>[K]>;\n};\n\n/**\n * Create input derived from a TailorDB table (`typeof myTable`) or a field collection.\n *\n * Each field resolves to the column type `kyselyTypePlugin` writes for it, so this and\n * the generated table types agree: `.serial()` fields are never caller-supplied,\n * `.default()` / `.hooks({ create })` fields may be omitted, optional fields stay\n * optional, `id` is platform-generated, and a date or datetime reads back as `Date`.\n *\n * Pass a field collection when the fields are a type parameter — a shared module that\n * lets each project extend a table with its own fields cannot name a generated table\n * type. Declare it as `<const F extends Record<string, TailorAnyDBField>>` so the field\n * types are inferred; a bare `Record<string, TailorAnyDBField>` erases them and nothing\n * is checked.\n *\n * Hand the result to callers rather than consuming it inside the generic that declares\n * it: while `F` is still an unresolved type parameter the mapping stays deferred, so\n * assigning to it inside the function body reports the unevaluated conditional rather\n * than a readable shape.\n * @example\n * function createInput<const F extends Record<string, TailorAnyDBField>>(fields: F) {\n *   return (input: TailorDBInsertable<F>) => { ... };\n * }\n */\nexport type TailorDBInsertable<T extends TailorDBColumnsSource> = FlattenColumns<\n  Insertable<TailorDBColumns<T>>\n>;\n\n/** Read shape of a TailorDB table or field collection. See {@link TailorDBInsertable}. */\nexport type TailorDBSelectable<T extends TailorDBColumnsSource> = FlattenColumns<\n  Selectable<TailorDBColumns<T>>\n>;\n\n/** Update input for a TailorDB table or field collection. See {@link TailorDBInsertable}. */\nexport type TailorDBUpdateable<T extends TailorDBColumnsSource> = FlattenColumns<\n  Updateable<TailorDBColumns<T>>\n>;\n"],"mappings":"sJAsFA,SAAgB,aAAkB,CAChC,OAAO,SACL,EACA,EACuB,CACvB,IAAM,EAAS,IAAI,SAAS,OAAO,CAAE,WAAU,CAAC,EAChD,OAAO,IAAIA,EAAc,CACvB,QAAS,IAAIC,EAAgB,CAAM,EACnC,GAAG,CACL,CAAC,CACH,CACF"}