@yielded/auth-persistence-drizzle 0.1.0-beta.34 → 0.1.0-beta.35

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.
@@ -81,6 +81,8 @@ const makeDrizzleSqlTables = (client, capturedDatabase) => {
81
81
  if (column === void 0) return invalid("Missing Drizzle column");
82
82
  return column;
83
83
  };
84
+ const ordinals = new Map(entries.map(([key], index) => [key, index]));
85
+ const projection = (keys) => keys === void 0 ? entries : keys.map((key) => [key, getColumn(key)]);
84
86
  const bind = (alias) => {
85
87
  const reference = (key) => {
86
88
  const column = getColumn(key);
@@ -115,9 +117,9 @@ const makeDrizzleSqlTables = (client, capturedDatabase) => {
115
117
  name: column.name
116
118
  } : void 0;
117
119
  },
118
- fields: (prefix) => compile(sql.join(entries.map(([key], index) => sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, index))}`), sql`, `)),
119
- decode: (row, prefix) => Object.fromEntries(entries.map(([key, column], index) => {
120
- const alias = nativeSqlAlias(prefix, index);
120
+ fields: (prefix, keys) => compile(sql.join(projection(keys).map(([key]) => sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, ordinals.get(key)))}`), sql`, `)),
121
+ decode: (row, prefix, keys) => Object.fromEntries(projection(keys).map(([key, column]) => {
122
+ const alias = nativeSqlAlias(prefix, ordinals.get(key));
121
123
  if (!Object.hasOwn(row, alias)) return invalid("Missing SQL projection field");
122
124
  const value = row[alias];
123
125
  return [key, value === null ? null : column.mapFromDriverValue(dialect.codecs === void 0 ? value : dialect.codecs.apply(column, "normalize", value))];
@@ -1 +1 @@
1
- {"version":3,"file":"native-sql-table.mjs","names":["Statement","getPgTableConfig","getMysqlTableConfig"],"sources":["../../src/drizzle/native-sql-table.ts"],"sourcesContent":["import {\n PersistenceMappingError,\n makeNativeSqlTables,\n nativeSqlAlias,\n type NativeSqlTables,\n type SqlTable,\n} from \"@yielded/auth-persistence/Adapter\";\nimport {\n getTableColumns,\n getTableName,\n is,\n Param,\n Placeholder,\n SQL,\n Table,\n sql,\n type BuildQueryConfig,\n type SQLWrapper,\n} from \"drizzle-orm\";\nimport { getTableConfig as getMysqlTableConfig, MySqlTable } from \"drizzle-orm/mysql-core\";\nimport { getTableConfig as getPgTableConfig, PgTable } from \"drizzle-orm/pg-core\";\nimport { Predicate } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\nimport * as Statement from \"effect/sql/Statement\";\n\ntype CapturedDialect = Pick<BuildQueryConfig, \"escapeName\" | \"escapeString\" | \"codecs\">;\n\n/** Foreign compiler boundary only: builders are used to materialize SQL, never\n * executed. The select builder exposes the original dialect even through the\n * Durable Object database projection, which retains bound query methods. */\ninterface CapturedDatabase {\n readonly select: () => { readonly dialect: CapturedDialect };\n readonly insert: (table: Table) => {\n readonly values: (values: Record<string, unknown>) => SQLWrapper;\n };\n readonly update: (table: Table) => {\n readonly set: (values: Record<string, unknown>) => SQLWrapper;\n };\n}\n\nconst invalid = (cause: string): never => {\n throw PersistenceMappingError.make({ operation: \"mapping\", cause });\n};\n\nconst capture = (\n database: object,\n): { readonly database: CapturedDatabase; readonly dialect: CapturedDialect } => {\n if (\n !Predicate.hasProperty(database, \"select\") ||\n typeof database.select !== \"function\" ||\n !Predicate.hasProperty(database, \"insert\") ||\n typeof database.insert !== \"function\" ||\n !Predicate.hasProperty(database, \"update\") ||\n typeof database.update !== \"function\"\n )\n return invalid(\"Expected a captured Drizzle database\");\n\n const selection: unknown = database.select();\n\n if (!Predicate.hasProperty(selection, \"dialect\"))\n return invalid(\"Expected a captured Drizzle dialect\");\n const dialect = selection.dialect;\n\n if (\n !Predicate.hasProperty(dialect, \"escapeName\") ||\n typeof dialect.escapeName !== \"function\" ||\n !Predicate.hasProperty(dialect, \"escapeString\") ||\n typeof dialect.escapeString !== \"function\"\n )\n return invalid(\"Expected Drizzle dialect escaping methods\");\n\n if (\n Predicate.hasProperty(dialect, \"codecs\") &&\n dialect.codecs !== undefined &&\n (!Predicate.hasProperty(dialect.codecs, \"apply\") || typeof dialect.codecs.apply !== \"function\")\n )\n return invalid(\"Expected Drizzle dialect codecs\");\n\n // Drizzle's private dialect and generic query builders are erased only here.\n return { database: database as CapturedDatabase, dialect: dialect as CapturedDialect };\n};\n\nconst compileWith =\n (dialect: CapturedDialect) =>\n (expression: SQL): Statement.Fragment => {\n const slots: string[] = [];\n\n const query = expression.toQuery({\n escapeName: (name) => {\n if (name.includes(\"\\0\")) return invalid(\"NUL in SQL identifier\");\n\n return dialect.escapeName(name);\n },\n escapeString: (value) => {\n if (value.includes(\"\\0\")) return invalid(\"NUL in SQL literal\");\n\n return dialect.escapeString(value);\n },\n escapeParam: (index) => {\n if (index !== slots.length) return invalid(\"Invalid Drizzle parameter order\");\n const slot = `yielded_parameter_${index}`;\n\n slots.push(slot);\n\n return `\\0${slot}\\0`;\n },\n ...(dialect.codecs === undefined ? {} : { codecs: dialect.codecs }),\n });\n\n // Only compiler-emitted slots are translated. Native Statement parameters\n // receive their final positions when composed; SQL literals containing $1 or\n // ? are never inspected or rewritten. NUL is reserved for this compilation.\n const parts = query.sql.split(\"\\0\");\n\n if (parts.length !== slots.length * 2 + 1 || query.params.length !== slots.length)\n return invalid(\"NUL or parameter marker collision in Drizzle SQL\");\n\n const segments: Statement.Segment[] = [];\n const consumed = new Set<number>();\n\n for (let offset = 0; offset < parts.length; offset += 2) {\n segments.push(Statement.literal(parts[offset]));\n if (offset + 1 === parts.length) break;\n const index = slots.indexOf(parts[offset + 1]);\n\n if (index < 0 || consumed.has(index))\n return invalid(\"NUL or parameter marker collision in Drizzle SQL\");\n consumed.add(index);\n const value: unknown = query.params[index];\n\n if (is(value, Placeholder) || is(value, Param)) return invalid(\"Unbound Drizzle placeholder\");\n if (Statement.isFragment(value)) segments.push(...value.segments);\n else segments.push(Statement.parameter(value));\n }\n\n return Statement.fragment(segments);\n };\n\n/** Preserve native Statement expressions in writes without applying a column\n * codec to them. Ordinary values still pass through Drizzle's own builders. */\nconst writeValues = (values: Readonly<Record<string, unknown>>) =>\n Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n Statement.isFragment(value) ? sql`${sql.param(value)}` : value,\n ]),\n );\n\n/** Capture the root database's compiler, not a later transaction object's\n * client. Call insert/update inside the operation to materialize hooks once. */\nexport const makeDrizzleSqlTables = (\n client: SqlClient,\n capturedDatabase: object,\n): NativeSqlTables => {\n const { database, dialect } = capture(capturedDatabase);\n const compile = compileWith(dialect);\n\n return makeNativeSqlTables(\n client,\n (_client, physical): SqlTable => {\n if (!is(physical, Table)) return invalid(\"Expected a Drizzle table\");\n const columns = getTableColumns(physical);\n const entries = Object.entries(columns);\n\n const schema = is(physical, PgTable)\n ? getPgTableConfig(physical).schema\n : is(physical, MySqlTable)\n ? getMysqlTableConfig(physical).schema\n : undefined;\n\n const table = { name: getTableName(physical), ...(schema === undefined ? {} : { schema }) };\n\n const getColumn = (key: string) => {\n const column = Object.hasOwn(columns, key) ? columns[key] : undefined;\n\n if (column === undefined) return invalid(\"Missing Drizzle column\");\n\n return column;\n };\n\n const bind = (alias?: string): SqlTable => {\n const reference = (key: string) => {\n const column = getColumn(key);\n\n return alias === undefined\n ? sql`${column}`\n : sql`${sql.identifier(alias)}.${sql.identifier(column.name)}`;\n };\n\n const selection = (key: string) => {\n const column = getColumn(key);\n\n return dialect.codecs === undefined\n ? reference(key)\n : dialect.codecs.apply(column, \"cast\", reference(key));\n };\n\n return {\n keys: entries.map(([key]) => key),\n name: compile(\n alias === undefined ? sql`${physical}` : sql`${physical} AS ${sql.identifier(alias)}`,\n ),\n as: bind,\n column: (key) => compile(reference(key)),\n columnName: (key) => compile(sql`${sql.identifier(getColumn(key).name)}`),\n selectedColumn: (key) => compile(sql`${selection(key)}`),\n unencodedTextColumn: (key) => {\n const column = getColumn(key);\n\n return [\"PgText\", \"PgVarchar\", \"SQLiteText\", \"MySqlText\", \"MySqlVarChar\"].includes(\n column.columnType,\n ) &&\n Predicate.hasProperty(column.mapToDriverValue, \"isNoop\") &&\n column.mapToDriverValue.isNoop === true &&\n Predicate.hasProperty(column.mapFromDriverValue, \"isNoop\") &&\n column.mapFromDriverValue.isNoop === true &&\n (dialect.codecs === undefined ||\n (Predicate.hasProperty(dialect.codecs, \"get\") &&\n typeof dialect.codecs.get === \"function\" &&\n ([\"cast\", \"normalize\", \"castParam\", \"normalizeParam\"] as const).every(\n (kind) => dialect.codecs?.get(column, kind) === undefined,\n )))\n ? { table, name: column.name }\n : undefined;\n },\n fields: (prefix) =>\n compile(\n sql.join(\n entries.map(\n ([key], index) =>\n sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, index))}`,\n ),\n sql`, `,\n ),\n ),\n decode: (row, prefix) =>\n Object.fromEntries(\n entries.map(([key, column], index) => {\n const alias = nativeSqlAlias(prefix, index);\n\n if (!Object.hasOwn(row, alias)) return invalid(\"Missing SQL projection field\");\n const value = row[alias];\n\n return [\n key,\n value === null\n ? null\n : column.mapFromDriverValue(\n dialect.codecs === undefined\n ? value\n : dialect.codecs.apply(column, \"normalize\", value),\n ),\n ];\n }),\n ),\n value: (key, value) => {\n const column = getColumn(key);\n\n return Statement.isFragment(value) ? value : compile(sql`${sql.param(value, column)}`);\n },\n insert: (values) =>\n compile(database.insert(physical).values(writeValues(values)).getSQL()),\n update: (values) => compile(database.update(physical).set(writeValues(values)).getSQL()),\n };\n };\n\n return bind();\n },\n (value) => {\n if (Statement.isFragment(value)) return value;\n if (!is(value, SQL)) return invalid(\"Expected a Drizzle SQL expression\");\n\n return compile(value);\n },\n );\n};\n"],"mappings":";;;;;;;AAwCA,MAAM,WAAW,UAAyB;CACxC,MAAM,wBAAwB,KAAK;EAAE,WAAW;EAAW;CAAM,CAAC;AACpE;AAEA,MAAM,WACJ,aAC+E;CAC/E,IACE,CAAC,UAAU,YAAY,UAAU,QAAQ,KACzC,OAAO,SAAS,WAAW,cAC3B,CAAC,UAAU,YAAY,UAAU,QAAQ,KACzC,OAAO,SAAS,WAAW,cAC3B,CAAC,UAAU,YAAY,UAAU,QAAQ,KACzC,OAAO,SAAS,WAAW,YAE3B,OAAO,QAAQ,sCAAsC;CAEvD,MAAM,YAAqB,SAAS,OAAO;CAE3C,IAAI,CAAC,UAAU,YAAY,WAAW,SAAS,GAC7C,OAAO,QAAQ,qCAAqC;CACtD,MAAM,UAAU,UAAU;CAE1B,IACE,CAAC,UAAU,YAAY,SAAS,YAAY,KAC5C,OAAO,QAAQ,eAAe,cAC9B,CAAC,UAAU,YAAY,SAAS,cAAc,KAC9C,OAAO,QAAQ,iBAAiB,YAEhC,OAAO,QAAQ,2CAA2C;CAE5D,IACE,UAAU,YAAY,SAAS,QAAQ,KACvC,QAAQ,WAAW,KAAA,MAClB,CAAC,UAAU,YAAY,QAAQ,QAAQ,OAAO,KAAK,OAAO,QAAQ,OAAO,UAAU,aAEpF,OAAO,QAAQ,iCAAiC;CAGlD,OAAO;EAAY;EAAuC;CAA2B;AACvF;AAEA,MAAM,eACH,aACA,eAAwC;CACvC,MAAM,QAAkB,CAAC;CAEzB,MAAM,QAAQ,WAAW,QAAQ;EAC/B,aAAa,SAAS;GACpB,IAAI,KAAK,SAAS,IAAI,GAAG,OAAO,QAAQ,uBAAuB;GAE/D,OAAO,QAAQ,WAAW,IAAI;EAChC;EACA,eAAe,UAAU;GACvB,IAAI,MAAM,SAAS,IAAI,GAAG,OAAO,QAAQ,oBAAoB;GAE7D,OAAO,QAAQ,aAAa,KAAK;EACnC;EACA,cAAc,UAAU;GACtB,IAAI,UAAU,MAAM,QAAQ,OAAO,QAAQ,iCAAiC;GAC5E,MAAM,OAAO,qBAAqB;GAElC,MAAM,KAAK,IAAI;GAEf,OAAO,KAAK,KAAK;EACnB;EACA,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;CACnE,CAAC;CAKD,MAAM,QAAQ,MAAM,IAAI,MAAM,IAAI;CAElC,IAAI,MAAM,WAAW,MAAM,SAAS,IAAI,KAAK,MAAM,OAAO,WAAW,MAAM,QACzE,OAAO,QAAQ,kDAAkD;CAEnE,MAAM,WAAgC,CAAC;CACvC,MAAM,2BAAW,IAAI,IAAY;CAEjC,KAAK,IAAI,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,GAAG;EACvD,SAAS,KAAKA,YAAU,QAAQ,MAAM,OAAO,CAAC;EAC9C,IAAI,SAAS,MAAM,MAAM,QAAQ;EACjC,MAAM,QAAQ,MAAM,QAAQ,MAAM,SAAS,EAAE;EAE7C,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,GACjC,OAAO,QAAQ,kDAAkD;EACnE,SAAS,IAAI,KAAK;EAClB,MAAM,QAAiB,MAAM,OAAO;EAEpC,IAAI,GAAG,OAAO,WAAW,KAAK,GAAG,OAAO,KAAK,GAAG,OAAO,QAAQ,6BAA6B;EAC5F,IAAIA,YAAU,WAAW,KAAK,GAAG,SAAS,KAAK,GAAG,MAAM,QAAQ;OAC3D,SAAS,KAAKA,YAAU,UAAU,KAAK,CAAC;CAC/C;CAEA,OAAOA,YAAU,SAAS,QAAQ;AACpC;;;AAIF,MAAM,eAAe,WACnB,OAAO,YACL,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAC3C,KACAA,YAAU,WAAW,KAAK,IAAI,GAAG,GAAG,IAAI,MAAM,KAAK,MAAM,KAC3D,CAAC,CACH;;;AAIF,MAAa,wBACX,QACA,qBACoB;CACpB,MAAM,EAAE,UAAU,YAAY,QAAQ,gBAAgB;CACtD,MAAM,UAAU,YAAY,OAAO;CAEnC,OAAO,oBACL,SACC,SAAS,aAAuB;EAC/B,IAAI,CAAC,GAAG,UAAU,KAAK,GAAG,OAAO,QAAQ,0BAA0B;EACnE,MAAM,UAAU,gBAAgB,QAAQ;EACxC,MAAM,UAAU,OAAO,QAAQ,OAAO;EAEtC,MAAM,SAAS,GAAG,UAAU,OAAO,IAC/BC,iBAAiB,QAAQ,CAAC,CAAC,SAC3B,GAAG,UAAU,UAAU,IACrBC,eAAoB,QAAQ,CAAC,CAAC,SAC9B,KAAA;EAEN,MAAM,QAAQ;GAAE,MAAM,aAAa,QAAQ;GAAG,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAAG;EAE1F,MAAM,aAAa,QAAgB;GACjC,MAAM,SAAS,OAAO,OAAO,SAAS,GAAG,IAAI,QAAQ,OAAO,KAAA;GAE5D,IAAI,WAAW,KAAA,GAAW,OAAO,QAAQ,wBAAwB;GAEjE,OAAO;EACT;EAEA,MAAM,QAAQ,UAA6B;GACzC,MAAM,aAAa,QAAgB;IACjC,MAAM,SAAS,UAAU,GAAG;IAE5B,OAAO,UAAU,KAAA,IACb,GAAG,GAAG,WACN,GAAG,GAAG,IAAI,WAAW,KAAK,EAAE,GAAG,IAAI,WAAW,OAAO,IAAI;GAC/D;GAEA,MAAM,aAAa,QAAgB;IACjC,MAAM,SAAS,UAAU,GAAG;IAE5B,OAAO,QAAQ,WAAW,KAAA,IACtB,UAAU,GAAG,IACb,QAAQ,OAAO,MAAM,QAAQ,QAAQ,UAAU,GAAG,CAAC;GACzD;GAEA,OAAO;IACL,MAAM,QAAQ,KAAK,CAAC,SAAS,GAAG;IAChC,MAAM,QACJ,UAAU,KAAA,IAAY,GAAG,GAAG,aAAa,GAAG,GAAG,SAAS,MAAM,IAAI,WAAW,KAAK,GACpF;IACA,IAAI;IACJ,SAAS,QAAQ,QAAQ,UAAU,GAAG,CAAC;IACvC,aAAa,QAAQ,QAAQ,GAAG,GAAG,IAAI,WAAW,UAAU,GAAG,CAAC,CAAC,IAAI,GAAG;IACxE,iBAAiB,QAAQ,QAAQ,GAAG,GAAG,UAAU,GAAG,GAAG;IACvD,sBAAsB,QAAQ;KAC5B,MAAM,SAAS,UAAU,GAAG;KAE5B,OAAO;MAAC;MAAU;MAAa;MAAc;MAAa;KAAc,CAAC,CAAC,SACxE,OAAO,UACT,KACE,UAAU,YAAY,OAAO,kBAAkB,QAAQ,KACvD,OAAO,iBAAiB,WAAW,QACnC,UAAU,YAAY,OAAO,oBAAoB,QAAQ,KACzD,OAAO,mBAAmB,WAAW,SACpC,QAAQ,WAAW,KAAA,KACjB,UAAU,YAAY,QAAQ,QAAQ,KAAK,KAC1C,OAAO,QAAQ,OAAO,QAAQ,cAC7B;MAAC;MAAQ;MAAa;MAAa;KAAgB,CAAC,CAAW,OAC7D,SAAS,QAAQ,QAAQ,IAAI,QAAQ,IAAI,MAAM,KAAA,CAClD,KACF;MAAE;MAAO,MAAM,OAAO;KAAK,IAC3B,KAAA;IACN;IACA,SAAS,WACP,QACE,IAAI,KACF,QAAQ,KACL,CAAC,MAAM,UACN,GAAG,GAAG,UAAU,GAAG,EAAE,MAAM,IAAI,WAAW,eAAe,QAAQ,KAAK,CAAC,GAC3E,GACA,GAAG,IACL,CACF;IACF,SAAS,KAAK,WACZ,OAAO,YACL,QAAQ,KAAK,CAAC,KAAK,SAAS,UAAU;KACpC,MAAM,QAAQ,eAAe,QAAQ,KAAK;KAE1C,IAAI,CAAC,OAAO,OAAO,KAAK,KAAK,GAAG,OAAO,QAAQ,8BAA8B;KAC7E,MAAM,QAAQ,IAAI;KAElB,OAAO,CACL,KACA,UAAU,OACN,OACA,OAAO,mBACL,QAAQ,WAAW,KAAA,IACf,QACA,QAAQ,OAAO,MAAM,QAAQ,aAAa,KAAK,CACrD,CACN;IACF,CAAC,CACH;IACF,QAAQ,KAAK,UAAU;KACrB,MAAM,SAAS,UAAU,GAAG;KAE5B,OAAOF,YAAU,WAAW,KAAK,IAAI,QAAQ,QAAQ,GAAG,GAAG,IAAI,MAAM,OAAO,MAAM,GAAG;IACvF;IACA,SAAS,WACP,QAAQ,SAAS,OAAO,QAAQ,CAAC,CAAC,OAAO,YAAY,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACxE,SAAS,WAAW,QAAQ,SAAS,OAAO,QAAQ,CAAC,CAAC,IAAI,YAAY,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;GACzF;EACF;EAEA,OAAO,KAAK;CACd,IACC,UAAU;EACT,IAAIA,YAAU,WAAW,KAAK,GAAG,OAAO;EACxC,IAAI,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,QAAQ,mCAAmC;EAEvE,OAAO,QAAQ,KAAK;CACtB,CACF;AACF"}
1
+ {"version":3,"file":"native-sql-table.mjs","names":["Statement","getPgTableConfig","getMysqlTableConfig"],"sources":["../../src/drizzle/native-sql-table.ts"],"sourcesContent":["import {\n PersistenceMappingError,\n makeNativeSqlTables,\n nativeSqlAlias,\n type NativeSqlTables,\n type SqlTable,\n} from \"@yielded/auth-persistence/Adapter\";\nimport {\n getTableColumns,\n getTableName,\n is,\n Param,\n Placeholder,\n SQL,\n Table,\n sql,\n type BuildQueryConfig,\n type SQLWrapper,\n} from \"drizzle-orm\";\nimport { getTableConfig as getMysqlTableConfig, MySqlTable } from \"drizzle-orm/mysql-core\";\nimport { getTableConfig as getPgTableConfig, PgTable } from \"drizzle-orm/pg-core\";\nimport { Predicate } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\nimport * as Statement from \"effect/sql/Statement\";\n\ntype CapturedDialect = Pick<BuildQueryConfig, \"escapeName\" | \"escapeString\" | \"codecs\">;\n\n/** Foreign compiler boundary only: builders are used to materialize SQL, never\n * executed. The select builder exposes the original dialect even through the\n * Durable Object database projection, which retains bound query methods. */\ninterface CapturedDatabase {\n readonly select: () => { readonly dialect: CapturedDialect };\n readonly insert: (table: Table) => {\n readonly values: (values: Record<string, unknown>) => SQLWrapper;\n };\n readonly update: (table: Table) => {\n readonly set: (values: Record<string, unknown>) => SQLWrapper;\n };\n}\n\nconst invalid = (cause: string): never => {\n throw PersistenceMappingError.make({ operation: \"mapping\", cause });\n};\n\nconst capture = (\n database: object,\n): { readonly database: CapturedDatabase; readonly dialect: CapturedDialect } => {\n if (\n !Predicate.hasProperty(database, \"select\") ||\n typeof database.select !== \"function\" ||\n !Predicate.hasProperty(database, \"insert\") ||\n typeof database.insert !== \"function\" ||\n !Predicate.hasProperty(database, \"update\") ||\n typeof database.update !== \"function\"\n )\n return invalid(\"Expected a captured Drizzle database\");\n\n const selection: unknown = database.select();\n\n if (!Predicate.hasProperty(selection, \"dialect\"))\n return invalid(\"Expected a captured Drizzle dialect\");\n const dialect = selection.dialect;\n\n if (\n !Predicate.hasProperty(dialect, \"escapeName\") ||\n typeof dialect.escapeName !== \"function\" ||\n !Predicate.hasProperty(dialect, \"escapeString\") ||\n typeof dialect.escapeString !== \"function\"\n )\n return invalid(\"Expected Drizzle dialect escaping methods\");\n\n if (\n Predicate.hasProperty(dialect, \"codecs\") &&\n dialect.codecs !== undefined &&\n (!Predicate.hasProperty(dialect.codecs, \"apply\") || typeof dialect.codecs.apply !== \"function\")\n )\n return invalid(\"Expected Drizzle dialect codecs\");\n\n // Drizzle's private dialect and generic query builders are erased only here.\n return { database: database as CapturedDatabase, dialect: dialect as CapturedDialect };\n};\n\nconst compileWith =\n (dialect: CapturedDialect) =>\n (expression: SQL): Statement.Fragment => {\n const slots: string[] = [];\n\n const query = expression.toQuery({\n escapeName: (name) => {\n if (name.includes(\"\\0\")) return invalid(\"NUL in SQL identifier\");\n\n return dialect.escapeName(name);\n },\n escapeString: (value) => {\n if (value.includes(\"\\0\")) return invalid(\"NUL in SQL literal\");\n\n return dialect.escapeString(value);\n },\n escapeParam: (index) => {\n if (index !== slots.length) return invalid(\"Invalid Drizzle parameter order\");\n const slot = `yielded_parameter_${index}`;\n\n slots.push(slot);\n\n return `\\0${slot}\\0`;\n },\n ...(dialect.codecs === undefined ? {} : { codecs: dialect.codecs }),\n });\n\n // Only compiler-emitted slots are translated. Native Statement parameters\n // receive their final positions when composed; SQL literals containing $1 or\n // ? are never inspected or rewritten. NUL is reserved for this compilation.\n const parts = query.sql.split(\"\\0\");\n\n if (parts.length !== slots.length * 2 + 1 || query.params.length !== slots.length)\n return invalid(\"NUL or parameter marker collision in Drizzle SQL\");\n\n const segments: Statement.Segment[] = [];\n const consumed = new Set<number>();\n\n for (let offset = 0; offset < parts.length; offset += 2) {\n segments.push(Statement.literal(parts[offset]));\n if (offset + 1 === parts.length) break;\n const index = slots.indexOf(parts[offset + 1]);\n\n if (index < 0 || consumed.has(index))\n return invalid(\"NUL or parameter marker collision in Drizzle SQL\");\n consumed.add(index);\n const value: unknown = query.params[index];\n\n if (is(value, Placeholder) || is(value, Param)) return invalid(\"Unbound Drizzle placeholder\");\n if (Statement.isFragment(value)) segments.push(...value.segments);\n else segments.push(Statement.parameter(value));\n }\n\n return Statement.fragment(segments);\n };\n\n/** Preserve native Statement expressions in writes without applying a column\n * codec to them. Ordinary values still pass through Drizzle's own builders. */\nconst writeValues = (values: Readonly<Record<string, unknown>>) =>\n Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n Statement.isFragment(value) ? sql`${sql.param(value)}` : value,\n ]),\n );\n\n/** Capture the root database's compiler, not a later transaction object's\n * client. Call insert/update inside the operation to materialize hooks once. */\nexport const makeDrizzleSqlTables = (\n client: SqlClient,\n capturedDatabase: object,\n): NativeSqlTables => {\n const { database, dialect } = capture(capturedDatabase);\n const compile = compileWith(dialect);\n\n return makeNativeSqlTables(\n client,\n (_client, physical): SqlTable => {\n if (!is(physical, Table)) return invalid(\"Expected a Drizzle table\");\n const columns = getTableColumns(physical);\n const entries = Object.entries(columns);\n\n const schema = is(physical, PgTable)\n ? getPgTableConfig(physical).schema\n : is(physical, MySqlTable)\n ? getMysqlTableConfig(physical).schema\n : undefined;\n\n const table = { name: getTableName(physical), ...(schema === undefined ? {} : { schema }) };\n\n const getColumn = (key: string) => {\n const column = Object.hasOwn(columns, key) ? columns[key] : undefined;\n\n if (column === undefined) return invalid(\"Missing Drizzle column\");\n\n return column;\n };\n\n const ordinals = new Map(entries.map(([key], index) => [key, index]));\n\n const projection = (keys?: ReadonlyArray<string>) =>\n keys === undefined ? entries : keys.map((key) => [key, getColumn(key)] as const);\n\n const bind = (alias?: string): SqlTable => {\n const reference = (key: string) => {\n const column = getColumn(key);\n\n return alias === undefined\n ? sql`${column}`\n : sql`${sql.identifier(alias)}.${sql.identifier(column.name)}`;\n };\n\n const selection = (key: string) => {\n const column = getColumn(key);\n\n return dialect.codecs === undefined\n ? reference(key)\n : dialect.codecs.apply(column, \"cast\", reference(key));\n };\n\n return {\n keys: entries.map(([key]) => key),\n name: compile(\n alias === undefined ? sql`${physical}` : sql`${physical} AS ${sql.identifier(alias)}`,\n ),\n as: bind,\n column: (key) => compile(reference(key)),\n columnName: (key) => compile(sql`${sql.identifier(getColumn(key).name)}`),\n selectedColumn: (key) => compile(sql`${selection(key)}`),\n unencodedTextColumn: (key) => {\n const column = getColumn(key);\n\n return [\"PgText\", \"PgVarchar\", \"SQLiteText\", \"MySqlText\", \"MySqlVarChar\"].includes(\n column.columnType,\n ) &&\n Predicate.hasProperty(column.mapToDriverValue, \"isNoop\") &&\n column.mapToDriverValue.isNoop === true &&\n Predicate.hasProperty(column.mapFromDriverValue, \"isNoop\") &&\n column.mapFromDriverValue.isNoop === true &&\n (dialect.codecs === undefined ||\n (Predicate.hasProperty(dialect.codecs, \"get\") &&\n typeof dialect.codecs.get === \"function\" &&\n ([\"cast\", \"normalize\", \"castParam\", \"normalizeParam\"] as const).every(\n (kind) => dialect.codecs?.get(column, kind) === undefined,\n )))\n ? { table, name: column.name }\n : undefined;\n },\n fields: (prefix, keys) =>\n compile(\n sql.join(\n projection(keys).map(\n ([key]) =>\n sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, ordinals.get(key)!))}`,\n ),\n sql`, `,\n ),\n ),\n decode: (row, prefix, keys) =>\n Object.fromEntries(\n projection(keys).map(([key, column]) => {\n const alias = nativeSqlAlias(prefix, ordinals.get(key)!);\n\n if (!Object.hasOwn(row, alias)) return invalid(\"Missing SQL projection field\");\n const value = row[alias];\n\n return [\n key,\n value === null\n ? null\n : column.mapFromDriverValue(\n dialect.codecs === undefined\n ? value\n : dialect.codecs.apply(column, \"normalize\", value),\n ),\n ];\n }),\n ),\n value: (key, value) => {\n const column = getColumn(key);\n\n return Statement.isFragment(value) ? value : compile(sql`${sql.param(value, column)}`);\n },\n insert: (values) =>\n compile(database.insert(physical).values(writeValues(values)).getSQL()),\n update: (values) => compile(database.update(physical).set(writeValues(values)).getSQL()),\n };\n };\n\n return bind();\n },\n (value) => {\n if (Statement.isFragment(value)) return value;\n if (!is(value, SQL)) return invalid(\"Expected a Drizzle SQL expression\");\n\n return compile(value);\n },\n );\n};\n"],"mappings":"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"}
@@ -2,16 +2,20 @@ import { nativeDatabase } from "../drizzle/native-database.mjs";
2
2
  import { makeDrizzleSqlTables } from "../drizzle/native-sql-table.mjs";
3
3
  import { PersistenceConfigurationError, createPersistence } from "@yielded/auth-persistence/Adapter";
4
4
  import { getTableColumns } from "drizzle-orm";
5
- import { bigint, boolean, getTableConfig, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
5
+ import { bigint, boolean, getTableConfig, index, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
6
6
  //#region src/internal/drizzle-postgres.ts
7
7
  const makeTable = (definition) => pgTable(definition.name, Object.fromEntries(Object.entries(definition.columns).map(([key, column]) => {
8
8
  const builder = column.type === "text" ? text(column.name) : column.type === "boolean" ? boolean(column.name) : bigint(column.name, { mode: "number" });
9
9
  return [key, column.nullable ? builder : builder.notNull()];
10
- })), (columns) => definition.unique.map((keys, i) => {
10
+ })), (columns) => [...definition.unique.map((keys, i) => {
11
11
  const [first, ...rest] = keys;
12
12
  if (first === void 0) throw PersistenceConfigurationError.make({ reason: "An empty unique key is invalid" });
13
13
  return uniqueIndex(`${definition.name}_key_${i}`).on(columns[first], ...rest.map((key) => columns[key]));
14
- }));
14
+ }), ...(definition.indexes ?? []).map((keys, i) => {
15
+ const [first, ...rest] = keys;
16
+ if (first === void 0) throw PersistenceConfigurationError.make({ reason: "An empty index is invalid" });
17
+ return index(`${definition.name}_index_${i}`).on(columns[first], ...rest.map((key) => columns[key]));
18
+ })]);
15
19
  const describe = (table) => {
16
20
  const config = getTableConfig(table);
17
21
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-postgres.mjs","names":[],"sources":["../../src/internal/drizzle-postgres.ts"],"sourcesContent":["import {\n PersistenceConfigurationError,\n createPersistence,\n} from \"@yielded/auth-persistence/Adapter\";\nimport type { StorageTable } from \"@yielded/auth-persistence/Adapter\";\nimport { getTableColumns } from \"drizzle-orm\";\nimport {\n getTableConfig,\n bigint,\n boolean,\n pgTable,\n text,\n uniqueIndex,\n type PgTable,\n} from \"drizzle-orm/pg-core\";\nimport type { Effect } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\n\nimport { nativeDatabase, type NativeDatabaseHandle } from \"../drizzle/native-database\";\nimport { makeDrizzleSqlTables } from \"../drizzle/native-sql-table\";\n\nconst makeTable = (definition: StorageTable) =>\n pgTable(\n definition.name,\n Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => {\n const builder =\n column.type === \"text\"\n ? text(column.name)\n : column.type === \"boolean\"\n ? boolean(column.name)\n : bigint(column.name, { mode: \"number\" });\n\n return [key, column.nullable ? builder : builder.notNull()];\n }),\n ),\n (columns) =>\n definition.unique.map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty unique key is invalid\" });\n\n return uniqueIndex(`${definition.name}_key_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n );\n\nconst describe = (table: PgTable): StorageTable => {\n const config = getTableConfig(table);\n\n return {\n name: config.name,\n ...(config.schema === undefined ? {} : { schema: config.schema }),\n columns: Object.fromEntries(\n Object.entries(getTableColumns(table)).map(([key, column]) => [\n key,\n {\n name: column.name,\n type:\n column.dataType === \"boolean\"\n ? \"boolean\"\n : column.dataType === \"number\"\n ? \"integer\"\n : \"text\",\n nullable: !column.notNull,\n },\n ]),\n ),\n unique: [],\n };\n};\n\nexport const postgresPersistence = <R>(acquire: Effect.Effect<object, never, R | SqlClient>) =>\n createPersistence<PgTable, R, NativeDatabaseHandle>({\n nativeTables: (database) => makeDrizzleSqlTables(database.$client, database),\n makeTable,\n describe,\n acquire: nativeDatabase(acquire),\n });\n"],"mappings":";;;;;;AAqBA,MAAM,aAAa,eACjB,QACE,WAAW,MACX,OAAO,YACL,OAAO,QAAQ,WAAW,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;CACxD,MAAM,UACJ,OAAO,SAAS,SACZ,KAAK,OAAO,IAAI,IAChB,OAAO,SAAS,YACd,QAAQ,OAAO,IAAI,IACnB,OAAO,OAAO,MAAM,EAAE,MAAM,SAAS,CAAC;CAE9C,OAAO,CAAC,KAAK,OAAO,WAAW,UAAU,QAAQ,QAAQ,CAAC;AAC5D,CAAC,CACH,IACC,YACC,WAAW,OAAO,KAAK,MAAM,MAAM;CACjC,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,iCAAiC,CAAC;CAEvF,OAAO,YAAY,GAAG,WAAW,KAAK,OAAO,GAAG,CAAC,CAAC,GAChD,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,CACL;AAEF,MAAM,YAAY,UAAiC;CACjD,MAAM,SAAS,eAAe,KAAK;CAEnC,OAAO;EACL,MAAM,OAAO;EACb,GAAI,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,OAAO,OAAO;EAC/D,SAAS,OAAO,YACd,OAAO,QAAQ,gBAAgB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,CAC5D,KACA;GACE,MAAM,OAAO;GACb,MACE,OAAO,aAAa,YAChB,YACA,OAAO,aAAa,WAClB,YACA;GACR,UAAU,CAAC,OAAO;EACpB,CACF,CAAC,CACH;EACA,QAAQ,CAAC;CACX;AACF;AAEA,MAAa,uBAA0B,YACrC,kBAAoD;CAClD,eAAe,aAAa,qBAAqB,SAAS,SAAS,QAAQ;CAC3E;CACA;CACA,SAAS,eAAe,OAAO;AACjC,CAAC"}
1
+ {"version":3,"file":"drizzle-postgres.mjs","names":[],"sources":["../../src/internal/drizzle-postgres.ts"],"sourcesContent":["import {\n PersistenceConfigurationError,\n createPersistence,\n} from \"@yielded/auth-persistence/Adapter\";\nimport type { StorageTable } from \"@yielded/auth-persistence/Adapter\";\nimport { getTableColumns } from \"drizzle-orm\";\nimport {\n getTableConfig,\n bigint,\n boolean,\n pgTable,\n text,\n uniqueIndex,\n index,\n type PgTable,\n} from \"drizzle-orm/pg-core\";\nimport type { Effect } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\n\nimport { nativeDatabase, type NativeDatabaseHandle } from \"../drizzle/native-database\";\nimport { makeDrizzleSqlTables } from \"../drizzle/native-sql-table\";\n\nconst makeTable = (definition: StorageTable) =>\n pgTable(\n definition.name,\n Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => {\n const builder =\n column.type === \"text\"\n ? text(column.name)\n : column.type === \"boolean\"\n ? boolean(column.name)\n : bigint(column.name, { mode: \"number\" });\n\n return [key, column.nullable ? builder : builder.notNull()];\n }),\n ),\n (columns) => [\n ...definition.unique.map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty unique key is invalid\" });\n\n return uniqueIndex(`${definition.name}_key_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n ...(definition.indexes ?? []).map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty index is invalid\" });\n\n return index(`${definition.name}_index_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n ],\n );\n\nconst describe = (table: PgTable): StorageTable => {\n const config = getTableConfig(table);\n\n return {\n name: config.name,\n ...(config.schema === undefined ? {} : { schema: config.schema }),\n columns: Object.fromEntries(\n Object.entries(getTableColumns(table)).map(([key, column]) => [\n key,\n {\n name: column.name,\n type:\n column.dataType === \"boolean\"\n ? \"boolean\"\n : column.dataType === \"number\"\n ? \"integer\"\n : \"text\",\n nullable: !column.notNull,\n },\n ]),\n ),\n unique: [],\n };\n};\n\nexport const postgresPersistence = <R>(acquire: Effect.Effect<object, never, R | SqlClient>) =>\n createPersistence<PgTable, R, NativeDatabaseHandle>({\n nativeTables: (database) => makeDrizzleSqlTables(database.$client, database),\n makeTable,\n describe,\n acquire: nativeDatabase(acquire),\n });\n"],"mappings":";;;;;;AAsBA,MAAM,aAAa,eACjB,QACE,WAAW,MACX,OAAO,YACL,OAAO,QAAQ,WAAW,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;CACxD,MAAM,UACJ,OAAO,SAAS,SACZ,KAAK,OAAO,IAAI,IAChB,OAAO,SAAS,YACd,QAAQ,OAAO,IAAI,IACnB,OAAO,OAAO,MAAM,EAAE,MAAM,SAAS,CAAC;CAE9C,OAAO,CAAC,KAAK,OAAO,WAAW,UAAU,QAAQ,QAAQ,CAAC;AAC5D,CAAC,CACH,IACC,YAAY,CACX,GAAG,WAAW,OAAO,KAAK,MAAM,MAAM;CACpC,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,iCAAiC,CAAC;CAEvF,OAAO,YAAY,GAAG,WAAW,KAAK,OAAO,GAAG,CAAC,CAAC,GAChD,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,GACD,IAAI,WAAW,WAAW,CAAC,EAAA,CAAG,KAAK,MAAM,MAAM;CAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,4BAA4B,CAAC;CAElF,OAAO,MAAM,GAAG,WAAW,KAAK,SAAS,GAAG,CAAC,CAAC,GAC5C,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,CACH,CACF;AAEF,MAAM,YAAY,UAAiC;CACjD,MAAM,SAAS,eAAe,KAAK;CAEnC,OAAO;EACL,MAAM,OAAO;EACb,GAAI,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,OAAO,OAAO;EAC/D,SAAS,OAAO,YACd,OAAO,QAAQ,gBAAgB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,CAC5D,KACA;GACE,MAAM,OAAO;GACb,MACE,OAAO,aAAa,YAChB,YACA,OAAO,aAAa,WAClB,YACA;GACR,UAAU,CAAC,OAAO;EACpB,CACF,CAAC,CACH;EACA,QAAQ,CAAC;CACX;AACF;AAEA,MAAa,uBAA0B,YACrC,kBAAoD;CAClD,eAAe,aAAa,qBAAqB,SAAS,SAAS,QAAQ;CAC3E;CACA;CACA,SAAS,eAAe,OAAO;AACjC,CAAC"}
@@ -3,16 +3,20 @@ import { makeDrizzleSqlTables } from "../drizzle/native-sql-table.mjs";
3
3
  import { PersistenceConfigurationError, createPersistence } from "@yielded/auth-persistence/Adapter";
4
4
  import { getTableColumns } from "drizzle-orm";
5
5
  import { Effect } from "effect";
6
- import { getTableConfig, integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
6
+ import { getTableConfig, index, integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
7
7
  //#region src/internal/drizzle-sqlite.ts
8
8
  const makeTable = (definition) => sqliteTable(definition.name, Object.fromEntries(Object.entries(definition.columns).map(([key, column]) => {
9
9
  const builder = column.type === "text" ? text(column.name) : column.type === "boolean" ? integer(column.name, { mode: "boolean" }) : integer(column.name);
10
10
  return [key, column.nullable ? builder : builder.notNull()];
11
- })), (columns) => definition.unique.map((keys, i) => {
11
+ })), (columns) => [...definition.unique.map((keys, i) => {
12
12
  const [first, ...rest] = keys;
13
13
  if (first === void 0) throw PersistenceConfigurationError.make({ reason: "An empty unique key is invalid" });
14
14
  return uniqueIndex(`${definition.name}_key_${i}`).on(columns[first], ...rest.map((key) => columns[key]));
15
- }));
15
+ }), ...(definition.indexes ?? []).map((keys, i) => {
16
+ const [first, ...rest] = keys;
17
+ if (first === void 0) throw PersistenceConfigurationError.make({ reason: "An empty index is invalid" });
18
+ return index(`${definition.name}_index_${i}`).on(columns[first], ...rest.map((key) => columns[key]));
19
+ })]);
16
20
  const describe = (table) => {
17
21
  return {
18
22
  name: getTableConfig(table).name,
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-sqlite.mjs","names":[],"sources":["../../src/internal/drizzle-sqlite.ts"],"sourcesContent":["import {\n PersistenceConfigurationError,\n createPersistence,\n} from \"@yielded/auth-persistence/Adapter\";\nimport type { StorageTable } from \"@yielded/auth-persistence/Adapter\";\nimport { getTableColumns } from \"drizzle-orm\";\nimport {\n getTableConfig,\n integer,\n sqliteTable,\n text,\n uniqueIndex,\n type SQLiteTable,\n} from \"drizzle-orm/sqlite-core\";\nimport { Effect } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\n\nimport { nativeDatabase, type NativeDatabaseHandle } from \"../drizzle/native-database\";\nimport { makeDrizzleSqlTables } from \"../drizzle/native-sql-table\";\n\nconst makeTable = (definition: StorageTable) =>\n sqliteTable(\n definition.name,\n Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => {\n const builder =\n column.type === \"text\"\n ? text(column.name)\n : column.type === \"boolean\"\n ? integer(column.name, { mode: \"boolean\" })\n : integer(column.name);\n\n return [key, column.nullable ? builder : builder.notNull()];\n }),\n ),\n (columns) =>\n definition.unique.map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty unique key is invalid\" });\n\n return uniqueIndex(`${definition.name}_key_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n );\n\nconst describe = (table: SQLiteTable): StorageTable => {\n const config = getTableConfig(table);\n\n return {\n name: config.name,\n columns: Object.fromEntries(\n Object.entries(getTableColumns(table)).map(([key, column]) => [\n key,\n {\n name: column.name,\n type:\n column.dataType === \"boolean\"\n ? \"boolean\"\n : column.dataType === \"number\"\n ? \"integer\"\n : \"text\",\n nullable: !column.notNull,\n },\n ]),\n ),\n unique: [],\n };\n};\n\nexport const sqlitePersistence = <R>(\n acquire: Effect.Effect<object, never, R | SqlClient>,\n options?: { readonly batch: true },\n) =>\n createPersistence<SQLiteTable, R, NativeDatabaseHandle>({\n nativeTables: (database) => makeDrizzleSqlTables(database.$client, database),\n makeTable,\n describe,\n acquire: nativeDatabase(acquire),\n ...(options?.batch === true\n ? {\n batch: (database: NativeDatabaseHandle) => ({\n client: database.$client,\n execute: (statements: Parameters<typeof database.$client.batch>[0]) =>\n database.$client.batch(statements).pipe(Effect.asVoid),\n }),\n }\n : {}),\n });\n"],"mappings":";;;;;;;AAoBA,MAAM,aAAa,eACjB,YACE,WAAW,MACX,OAAO,YACL,OAAO,QAAQ,WAAW,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;CACxD,MAAM,UACJ,OAAO,SAAS,SACZ,KAAK,OAAO,IAAI,IAChB,OAAO,SAAS,YACd,QAAQ,OAAO,MAAM,EAAE,MAAM,UAAU,CAAC,IACxC,QAAQ,OAAO,IAAI;CAE3B,OAAO,CAAC,KAAK,OAAO,WAAW,UAAU,QAAQ,QAAQ,CAAC;AAC5D,CAAC,CACH,IACC,YACC,WAAW,OAAO,KAAK,MAAM,MAAM;CACjC,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,iCAAiC,CAAC;CAEvF,OAAO,YAAY,GAAG,WAAW,KAAK,OAAO,GAAG,CAAC,CAAC,GAChD,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,CACL;AAEF,MAAM,YAAY,UAAqC;CAGrD,OAAO;EACL,MAHa,eAAe,KAGjB,CAAC,CAAC;EACb,SAAS,OAAO,YACd,OAAO,QAAQ,gBAAgB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,CAC5D,KACA;GACE,MAAM,OAAO;GACb,MACE,OAAO,aAAa,YAChB,YACA,OAAO,aAAa,WAClB,YACA;GACR,UAAU,CAAC,OAAO;EACpB,CACF,CAAC,CACH;EACA,QAAQ,CAAC;CACX;AACF;AAEA,MAAa,qBACX,SACA,YAEA,kBAAwD;CACtD,eAAe,aAAa,qBAAqB,SAAS,SAAS,QAAQ;CAC3E;CACA;CACA,SAAS,eAAe,OAAO;CAC/B,GAAI,SAAS,UAAU,OACnB,EACE,QAAQ,cAAoC;EAC1C,QAAQ,SAAS;EACjB,UAAU,eACR,SAAS,QAAQ,MAAM,UAAU,CAAC,CAAC,KAAK,OAAO,MAAM;CACzD,GACF,IACA,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"drizzle-sqlite.mjs","names":[],"sources":["../../src/internal/drizzle-sqlite.ts"],"sourcesContent":["import {\n PersistenceConfigurationError,\n createPersistence,\n} from \"@yielded/auth-persistence/Adapter\";\nimport type { StorageTable } from \"@yielded/auth-persistence/Adapter\";\nimport { getTableColumns } from \"drizzle-orm\";\nimport {\n getTableConfig,\n integer,\n sqliteTable,\n text,\n uniqueIndex,\n index,\n type SQLiteTable,\n} from \"drizzle-orm/sqlite-core\";\nimport { Effect } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\n\nimport { nativeDatabase, type NativeDatabaseHandle } from \"../drizzle/native-database\";\nimport { makeDrizzleSqlTables } from \"../drizzle/native-sql-table\";\n\nconst makeTable = (definition: StorageTable) =>\n sqliteTable(\n definition.name,\n Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => {\n const builder =\n column.type === \"text\"\n ? text(column.name)\n : column.type === \"boolean\"\n ? integer(column.name, { mode: \"boolean\" })\n : integer(column.name);\n\n return [key, column.nullable ? builder : builder.notNull()];\n }),\n ),\n (columns) => [\n ...definition.unique.map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty unique key is invalid\" });\n\n return uniqueIndex(`${definition.name}_key_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n ...(definition.indexes ?? []).map((keys, i) => {\n const [first, ...rest] = keys;\n\n if (first === undefined)\n throw PersistenceConfigurationError.make({ reason: \"An empty index is invalid\" });\n\n return index(`${definition.name}_index_${i}`).on(\n columns[first],\n ...rest.map((key) => columns[key]),\n );\n }),\n ],\n );\n\nconst describe = (table: SQLiteTable): StorageTable => {\n const config = getTableConfig(table);\n\n return {\n name: config.name,\n columns: Object.fromEntries(\n Object.entries(getTableColumns(table)).map(([key, column]) => [\n key,\n {\n name: column.name,\n type:\n column.dataType === \"boolean\"\n ? \"boolean\"\n : column.dataType === \"number\"\n ? \"integer\"\n : \"text\",\n nullable: !column.notNull,\n },\n ]),\n ),\n unique: [],\n };\n};\n\nexport const sqlitePersistence = <R>(\n acquire: Effect.Effect<object, never, R | SqlClient>,\n options?: { readonly batch: true },\n) =>\n createPersistence<SQLiteTable, R, NativeDatabaseHandle>({\n nativeTables: (database) => makeDrizzleSqlTables(database.$client, database),\n makeTable,\n describe,\n acquire: nativeDatabase(acquire),\n ...(options?.batch === true\n ? {\n batch: (database: NativeDatabaseHandle) => ({\n client: database.$client,\n execute: (statements: Parameters<typeof database.$client.batch>[0]) =>\n database.$client.batch(statements).pipe(Effect.asVoid),\n }),\n }\n : {}),\n });\n"],"mappings":";;;;;;;AAqBA,MAAM,aAAa,eACjB,YACE,WAAW,MACX,OAAO,YACL,OAAO,QAAQ,WAAW,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;CACxD,MAAM,UACJ,OAAO,SAAS,SACZ,KAAK,OAAO,IAAI,IAChB,OAAO,SAAS,YACd,QAAQ,OAAO,MAAM,EAAE,MAAM,UAAU,CAAC,IACxC,QAAQ,OAAO,IAAI;CAE3B,OAAO,CAAC,KAAK,OAAO,WAAW,UAAU,QAAQ,QAAQ,CAAC;AAC5D,CAAC,CACH,IACC,YAAY,CACX,GAAG,WAAW,OAAO,KAAK,MAAM,MAAM;CACpC,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,iCAAiC,CAAC;CAEvF,OAAO,YAAY,GAAG,WAAW,KAAK,OAAO,GAAG,CAAC,CAAC,GAChD,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,GACD,IAAI,WAAW,WAAW,CAAC,EAAA,CAAG,KAAK,MAAM,MAAM;CAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ;CAEzB,IAAI,UAAU,KAAA,GACZ,MAAM,8BAA8B,KAAK,EAAE,QAAQ,4BAA4B,CAAC;CAElF,OAAO,MAAM,GAAG,WAAW,KAAK,SAAS,GAAG,CAAC,CAAC,GAC5C,QAAQ,QACR,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,CACnC;AACF,CAAC,CACH,CACF;AAEF,MAAM,YAAY,UAAqC;CAGrD,OAAO;EACL,MAHa,eAAe,KAGjB,CAAC,CAAC;EACb,SAAS,OAAO,YACd,OAAO,QAAQ,gBAAgB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,CAC5D,KACA;GACE,MAAM,OAAO;GACb,MACE,OAAO,aAAa,YAChB,YACA,OAAO,aAAa,WAClB,YACA;GACR,UAAU,CAAC,OAAO;EACpB,CACF,CAAC,CACH;EACA,QAAQ,CAAC;CACX;AACF;AAEA,MAAa,qBACX,SACA,YAEA,kBAAwD;CACtD,eAAe,aAAa,qBAAqB,SAAS,SAAS,QAAQ;CAC3E;CACA;CACA,SAAS,eAAe,OAAO;CAC/B,GAAI,SAAS,UAAU,OACnB,EACE,QAAQ,cAAoC;EAC1C,QAAQ,SAAS;EACjB,UAAU,eACR,SAAS,QAAQ,MAAM,UAAU,CAAC,CAAC,KAAK,OAAO,MAAM;CACzD,GACF,IACA,CAAC;AACP,CAAC"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/auth-persistence-drizzle","version":"0.1.0-beta.34","dependencies":{"@yielded/auth":"0.1.0-beta.34","@yielded/auth-persistence":"0.1.0-beta.34"},"devDependencies":{"@effect/platform-bun":"4.0.3","@effect/platform-node":"4.0.3","@effect/sql-d1":"4.0.3","@effect/sql-libsql":"4.0.3","@effect/sql-mysql2":"4.0.3","@effect/sql-pg":"4.0.3","@effect/sql-pglite":"4.0.3","@effect/sql-sqlite-bun":"4.0.3","@effect/sql-sqlite-do":"4.0.3","@effect/sql-sqlite-node":"4.0.3","@effect/sql-sqlite-wasm":"4.0.3","@effect/vitest":"4.0.3","@yielded/crypto":"0.1.0-beta.34","drizzle-orm":"1.0.0-rc.4","effect":"4.0.3","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"@effect/sql-d1":">=4.0.0","@effect/sql-libsql":">=4.0.0","@effect/sql-mysql2":">=4.0.0","@effect/sql-pg":">=4.0.0","@effect/sql-pglite":">=4.0.0","@effect/sql-sqlite-bun":">=4.0.0","@effect/sql-sqlite-do":">=4.0.0","@effect/sql-sqlite-node":">=4.0.0","@effect/sql-sqlite-wasm":">=4.0.0","drizzle-orm":">=1.0.0-rc.4","effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./D1":{"types":"./dist/D1.d.mts","default":"./dist/D1.mjs"},"./Libsql":{"types":"./dist/Libsql.d.mts","default":"./dist/Libsql.mjs"},"./Mysql2":{"types":"./dist/Mysql2.d.mts","default":"./dist/Mysql2.mjs"},"./Pglite":{"types":"./dist/Pglite.d.mts","default":"./dist/Pglite.mjs"},"./Postgres":{"types":"./dist/Postgres.d.mts","default":"./dist/Postgres.mjs"},"./SqliteBun":{"types":"./dist/SqliteBun.d.mts","default":"./dist/SqliteBun.mjs"},"./SqliteDo":{"types":"./dist/SqliteDo.d.mts","default":"./dist/SqliteDo.mjs"},"./SqliteNode":{"types":"./dist/SqliteNode.d.mts","default":"./dist/SqliteNode.mjs"},"./SqliteWasm":{"types":"./dist/SqliteWasm.d.mts","default":"./dist/SqliteWasm.mjs"}},"description":"Drizzle persistence, table mappings, and migration adapters for Yielded Auth.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/auth-persistence-drizzle"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests","example:totp":"bun test/fixtures/totp-sqlite-bun.ts"},"peerDependenciesMeta":{"@effect/sql-d1":{"optional":true},"@effect/sql-libsql":{"optional":true},"@effect/sql-mysql2":{"optional":true},"@effect/sql-pg":{"optional":true},"@effect/sql-pglite":{"optional":true},"@effect/sql-sqlite-bun":{"optional":true},"@effect/sql-sqlite-do":{"optional":true},"@effect/sql-sqlite-node":{"optional":true},"@effect/sql-sqlite-wasm":{"optional":true}}}
1
+ {"name":"@yielded/auth-persistence-drizzle","version":"0.1.0-beta.35","dependencies":{"@yielded/auth":"0.1.0-beta.35","@yielded/auth-persistence":"0.1.0-beta.35"},"devDependencies":{"@effect/platform-bun":"4.0.3","@effect/platform-node":"4.0.3","@effect/sql-d1":"4.0.3","@effect/sql-libsql":"4.0.3","@effect/sql-mysql2":"4.0.3","@effect/sql-pg":"4.0.3","@effect/sql-pglite":"4.0.3","@effect/sql-sqlite-bun":"4.0.3","@effect/sql-sqlite-do":"4.0.3","@effect/sql-sqlite-node":"4.0.3","@effect/sql-sqlite-wasm":"4.0.3","@effect/vitest":"4.0.3","@yielded/crypto":"0.1.0-beta.35","drizzle-orm":"1.0.0-rc.4","effect":"4.0.3","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"@effect/sql-d1":">=4.0.0","@effect/sql-libsql":">=4.0.0","@effect/sql-mysql2":">=4.0.0","@effect/sql-pg":">=4.0.0","@effect/sql-pglite":">=4.0.0","@effect/sql-sqlite-bun":">=4.0.0","@effect/sql-sqlite-do":">=4.0.0","@effect/sql-sqlite-node":">=4.0.0","@effect/sql-sqlite-wasm":">=4.0.0","drizzle-orm":">=1.0.0-rc.4","effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./D1":{"types":"./dist/D1.d.mts","default":"./dist/D1.mjs"},"./Libsql":{"types":"./dist/Libsql.d.mts","default":"./dist/Libsql.mjs"},"./Mysql2":{"types":"./dist/Mysql2.d.mts","default":"./dist/Mysql2.mjs"},"./Pglite":{"types":"./dist/Pglite.d.mts","default":"./dist/Pglite.mjs"},"./Postgres":{"types":"./dist/Postgres.d.mts","default":"./dist/Postgres.mjs"},"./SqliteBun":{"types":"./dist/SqliteBun.d.mts","default":"./dist/SqliteBun.mjs"},"./SqliteDo":{"types":"./dist/SqliteDo.d.mts","default":"./dist/SqliteDo.mjs"},"./SqliteNode":{"types":"./dist/SqliteNode.d.mts","default":"./dist/SqliteNode.mjs"},"./SqliteWasm":{"types":"./dist/SqliteWasm.d.mts","default":"./dist/SqliteWasm.mjs"}},"description":"Drizzle persistence, table mappings, and migration adapters for Yielded Auth.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/auth-persistence-drizzle"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests","example:totp":"bun test/fixtures/totp-sqlite-bun.ts"},"peerDependenciesMeta":{"@effect/sql-d1":{"optional":true},"@effect/sql-libsql":{"optional":true},"@effect/sql-mysql2":{"optional":true},"@effect/sql-pg":{"optional":true},"@effect/sql-pglite":{"optional":true},"@effect/sql-sqlite-bun":{"optional":true},"@effect/sql-sqlite-do":{"optional":true},"@effect/sql-sqlite-node":{"optional":true},"@effect/sql-sqlite-wasm":{"optional":true}}}
@@ -178,6 +178,11 @@ export const makeDrizzleSqlTables = (
178
178
  return column;
179
179
  };
180
180
 
181
+ const ordinals = new Map(entries.map(([key], index) => [key, index]));
182
+
183
+ const projection = (keys?: ReadonlyArray<string>) =>
184
+ keys === undefined ? entries : keys.map((key) => [key, getColumn(key)] as const);
185
+
181
186
  const bind = (alias?: string): SqlTable => {
182
187
  const reference = (key: string) => {
183
188
  const column = getColumn(key);
@@ -223,20 +228,20 @@ export const makeDrizzleSqlTables = (
223
228
  ? { table, name: column.name }
224
229
  : undefined;
225
230
  },
226
- fields: (prefix) =>
231
+ fields: (prefix, keys) =>
227
232
  compile(
228
233
  sql.join(
229
- entries.map(
230
- ([key], index) =>
231
- sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, index))}`,
234
+ projection(keys).map(
235
+ ([key]) =>
236
+ sql`${selection(key)} as ${sql.identifier(nativeSqlAlias(prefix, ordinals.get(key)!))}`,
232
237
  ),
233
238
  sql`, `,
234
239
  ),
235
240
  ),
236
- decode: (row, prefix) =>
241
+ decode: (row, prefix, keys) =>
237
242
  Object.fromEntries(
238
- entries.map(([key, column], index) => {
239
- const alias = nativeSqlAlias(prefix, index);
243
+ projection(keys).map(([key, column]) => {
244
+ const alias = nativeSqlAlias(prefix, ordinals.get(key)!);
240
245
 
241
246
  if (!Object.hasOwn(row, alias)) return invalid("Missing SQL projection field");
242
247
  const value = row[alias];
@@ -11,6 +11,7 @@ import {
11
11
  pgTable,
12
12
  text,
13
13
  uniqueIndex,
14
+ index,
14
15
  type PgTable,
15
16
  } from "drizzle-orm/pg-core";
16
17
  import type { Effect } from "effect";
@@ -34,8 +35,8 @@ const makeTable = (definition: StorageTable) =>
34
35
  return [key, column.nullable ? builder : builder.notNull()];
35
36
  }),
36
37
  ),
37
- (columns) =>
38
- definition.unique.map((keys, i) => {
38
+ (columns) => [
39
+ ...definition.unique.map((keys, i) => {
39
40
  const [first, ...rest] = keys;
40
41
 
41
42
  if (first === undefined)
@@ -46,6 +47,18 @@ const makeTable = (definition: StorageTable) =>
46
47
  ...rest.map((key) => columns[key]),
47
48
  );
48
49
  }),
50
+ ...(definition.indexes ?? []).map((keys, i) => {
51
+ const [first, ...rest] = keys;
52
+
53
+ if (first === undefined)
54
+ throw PersistenceConfigurationError.make({ reason: "An empty index is invalid" });
55
+
56
+ return index(`${definition.name}_index_${i}`).on(
57
+ columns[first],
58
+ ...rest.map((key) => columns[key]),
59
+ );
60
+ }),
61
+ ],
49
62
  );
50
63
 
51
64
  const describe = (table: PgTable): StorageTable => {
@@ -10,6 +10,7 @@ import {
10
10
  sqliteTable,
11
11
  text,
12
12
  uniqueIndex,
13
+ index,
13
14
  type SQLiteTable,
14
15
  } from "drizzle-orm/sqlite-core";
15
16
  import { Effect } from "effect";
@@ -33,8 +34,8 @@ const makeTable = (definition: StorageTable) =>
33
34
  return [key, column.nullable ? builder : builder.notNull()];
34
35
  }),
35
36
  ),
36
- (columns) =>
37
- definition.unique.map((keys, i) => {
37
+ (columns) => [
38
+ ...definition.unique.map((keys, i) => {
38
39
  const [first, ...rest] = keys;
39
40
 
40
41
  if (first === undefined)
@@ -45,6 +46,18 @@ const makeTable = (definition: StorageTable) =>
45
46
  ...rest.map((key) => columns[key]),
46
47
  );
47
48
  }),
49
+ ...(definition.indexes ?? []).map((keys, i) => {
50
+ const [first, ...rest] = keys;
51
+
52
+ if (first === undefined)
53
+ throw PersistenceConfigurationError.make({ reason: "An empty index is invalid" });
54
+
55
+ return index(`${definition.name}_index_${i}`).on(
56
+ columns[first],
57
+ ...rest.map((key) => columns[key]),
58
+ );
59
+ }),
60
+ ],
48
61
  );
49
62
 
50
63
  const describe = (table: SQLiteTable): StorageTable => {