@yielded/auth-persistence 0.1.0-beta.16 → 0.1.0-beta.18

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 +1 @@
1
- {"version":3,"file":"sql-query.mjs","names":[],"sources":["../../src/internal/sql-query.ts"],"sourcesContent":["import { Effect, Predicate } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { QueryOperations } from \"./query-operations\";\nimport {\n type Column,\n Fragment,\n Table,\n identifier,\n type Compiler,\n type Dialect,\n type Row,\n} from \"./sql-table\";\n\nconst render = (value: unknown, compiler: Compiler): string => {\n if (value instanceof Fragment) return value.render(compiler);\n if (Predicate.hasProperty(value, \"getSQL\") && typeof value.getSQL === \"function\") {\n return render(value.getSQL(), compiler);\n }\n\n compiler.parameters.push(\n compiler.dialect === \"sqlite\" && typeof value === \"boolean\" ? Number(value) : value,\n );\n\n return compiler.dialect === \"pg\" ? `$${compiler.parameters.length}` : \"?\";\n};\n\nconst template = (parts: TemplateStringsArray, ...values: unknown[]): Fragment =>\n new Fragment((compiler) =>\n parts.reduce(\n (sql, part, i) => sql + (i === 0 ? \"\" : render(values[i - 1], compiler)) + part,\n \"\",\n ),\n );\n\nconst combine = (separator: string, values: ReadonlyArray<Fragment | undefined>) => {\n const fragments = values.filter((value) => value !== undefined);\n\n return fragments.length === 0\n ? undefined\n : new Fragment(\n (compiler) =>\n \"(\" + fragments.map((fragment) => fragment.render(compiler)).join(separator) + \")\",\n );\n};\n\nconst and = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" AND \", values);\nconst or = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" OR \", values);\n\nconst operations = {\n and,\n or,\n asc: (value: unknown) => template`${value} ASC`,\n eq: (left: unknown, right: unknown) => template`${left} = ${right}`,\n gt: (left: unknown, right: unknown) => template`${left} > ${right}`,\n gte: (left: unknown, right: unknown) => template`${left} >= ${right}`,\n lte: (left: unknown, right: unknown) => template`${left} <= ${right}`,\n isNull: (value: unknown) => template`${value} IS NULL`,\n notExists: (value: unknown) => template`NOT EXISTS (${value})`,\n inArray: (column: unknown, values: ReadonlyArray<unknown>) =>\n values.length === 0\n ? template`false`\n : new Fragment(\n (compiler) =>\n `${render(column, compiler)} IN (${values.map((value) => render(value, compiler)).join(\", \")})`,\n ),\n sql: Object.assign(template, {\n param: (value: unknown, column: Column) => column.mapToDriverValue(value),\n join: (values: ReadonlyArray<unknown>, separator: Fragment = template``) =>\n new Fragment((compiler) =>\n values\n .map(\n (value, index) =>\n (index === 0 ? \"\" : separator.render(compiler)) + render(value, compiler),\n )\n .join(\"\"),\n ),\n }),\n getTableColumns: (table: Table) => table.columns,\n column: (table: Table, key: string) => {\n const column = table.columns[key];\n\n if (column === undefined)\n throw PersistenceMappingError.make({ operation: \"column\", cause: key });\n\n return column;\n },\n updateValues: (entries: ReadonlyArray<readonly [string, unknown]>) => Object.fromEntries(entries),\n balancedD1And: and,\n // Raw clients use interactive transactions, so no D1 batch compaction is needed.\n compactD1GeneratedStatement: <S>(_client: unknown, statement: S) => statement,\n};\n\n// The existing kernels erase query-builder shapes at this boundary. The raw compiler\n// implements precisely those operations; no row decoding or Effect requirements are cast.\nexport const sqlQueryOperations = operations as unknown as QueryOperations;\n\ntype Selection = Readonly<Record<string, Fragment>>;\n\ninterface QueryState {\n readonly operation: \"select\" | \"insert\" | \"update\" | \"delete\";\n readonly table?: Table | Fragment;\n readonly joins?: ReadonlyArray<{\n readonly table: Table | Fragment;\n readonly on: Fragment;\n }>;\n readonly selection?: Selection;\n readonly where?: Fragment;\n readonly values?: Row;\n readonly returning?: Selection | true;\n readonly order?: ReadonlyArray<Fragment>;\n readonly limit?: number;\n readonly lock?: boolean;\n readonly conflict?: boolean;\n}\n\nconst selectionFor = (state: QueryState): Selection =>\n state.selection ?? (state.table instanceof Table ? state.table.columns : {});\n\nconst selectionFields = (selection: Selection) => {\n const used = new Set(Object.keys(selection));\n let index = 0;\n\n return Object.entries(selection).flatMap<{\n readonly key: string;\n readonly name: string | undefined;\n readonly column: Fragment;\n readonly alias: string;\n }>(([key, value]) =>\n value instanceof Table\n ? Object.entries(value.columns).map(([name, column]) => {\n let alias: string;\n\n do alias = `auth_column_${index++}`;\n while (used.has(alias));\n used.add(alias);\n\n return { key, name, column, alias };\n })\n : [{ key, name: undefined, column: value, alias: key }],\n );\n};\n\nconst projection = (selection: Selection, compiler: Compiler) =>\n selectionFields(selection)\n .map(({ column, alias }) => `${column.render(compiler)} AS ${identifier(alias)}`)\n .join(\", \");\n\n// Joined table selections retain their own column codecs and nested row names.\nconst decodeRow = (selection: Selection, row: Row): Row => {\n const entries: Array<readonly [string, unknown]> = [];\n const groups = new Map<string, Array<readonly [string, unknown]>>();\n\n for (const field of selectionFields(selection)) {\n const value = field.column.decode(row[field.alias]);\n\n if (field.name === undefined) entries.push([field.key, value]);\n else {\n const group = groups.get(field.key) ?? [];\n\n group.push([field.name, value]);\n groups.set(field.key, group);\n }\n }\n\n return Object.fromEntries([\n ...entries,\n ...Array.from(groups, ([key, values]) => [key, Object.fromEntries(values)]),\n ]);\n};\n\nconst compile = (state: QueryState, compiler: Compiler): string => {\n const table = state.table;\n\n if (table === undefined)\n throw PersistenceMappingError.make({ operation: \"query\", cause: \"Missing table\" });\n let query: string;\n\n if (state.operation === \"select\") {\n query = `SELECT ${projection(selectionFor(state), compiler)} FROM ${table.render(compiler)}`;\n for (const join of state.joins ?? [])\n query += ` INNER JOIN ${join.table.render(compiler)} ON ${join.on.render(compiler)}`;\n } else {\n if (!(table instanceof Table))\n throw PersistenceMappingError.make({\n operation: \"query\",\n cause: \"Mutation requires a table\",\n });\n const target = table.render(compiler);\n\n const fields = Object.entries(state.values ?? {}).filter(\n ([key, value]) => table.columns[key] !== undefined && value !== undefined,\n );\n\n if (state.operation === \"insert\") {\n query = `INSERT INTO ${target} (${fields.map(([key]) => identifier(table.columns[key].options.name)).join(\", \")}) VALUES (${fields.map(([, value]) => render(value, compiler)).join(\", \")})`;\n } else if (state.operation === \"update\") {\n query = `UPDATE ${target} SET ${fields.map(([key, value]) => `${identifier(table.columns[key].options.name)} = ${render(value, compiler)}`).join(\", \")}`;\n } else query = `DELETE FROM ${target}`;\n }\n if (state.where !== undefined) query += ` WHERE ${state.where.render(compiler)}`;\n if (state.order?.length)\n query += ` ORDER BY ${state.order.map((field) => field.render(compiler)).join(\", \")}`;\n if (state.limit !== undefined) query += ` LIMIT ${render(state.limit, compiler)}`;\n if (state.conflict) query += \" ON CONFLICT DO NOTHING\";\n if (state.returning)\n query += ` RETURNING ${projection(state.returning === true && table instanceof Table ? table.columns : state.returning === true ? {} : state.returning, compiler)}`;\n if (state.lock && compiler.dialect === \"pg\") query += \" FOR UPDATE\";\n\n return query;\n};\n\n/** Captures one Effect SQL client. Its transaction service remains the physical owner. */\nexport const makeSqlDatabase = Effect.fnUntraced(function* (dialect: Dialect) {\n const client = yield* SqlClient;\n\n const query = (state: QueryState): Query => {\n const execute = Effect.suspend(() => {\n const compiler: Compiler = { dialect, parameters: [] };\n const text = compile(state, compiler);\n\n const selected: Selection =\n state.operation === \"select\"\n ? selectionFor(state)\n : state.returning === true\n ? state.table instanceof Table\n ? state.table.columns\n : {}\n : state.returning || {};\n\n return client\n .unsafe<Row>(text, compiler.parameters)\n .pipe(Effect.map((rows) => rows.map((row) => decodeRow(selected, row))));\n });\n\n return Object.assign(execute, {\n toSQL: () => {\n const compiler: Compiler = { dialect, parameters: [] };\n\n return { sql: compile(state, compiler), params: compiler.parameters };\n },\n getSQL: () => new Fragment((compiler) => compile(state, compiler)),\n from: (table: Table | Fragment) => query({ ...state, table }),\n innerJoin: (table: Table | Fragment, on: Fragment) =>\n query({ ...state, joins: [...(state.joins ?? []), { table, on }] }),\n where: (where: Fragment | undefined) => query({ ...state, where }),\n limit: (limit: number) => query({ ...state, limit }),\n orderBy: (...order: Fragment[]) => query({ ...state, order }),\n for: (_lock: \"update\") => query({ ...state, lock: true }),\n values: (values: Row) => query({ ...state, values }),\n set: (values: Row) => query({ ...state, values }),\n returning: (returning: Selection | true = true) => query({ ...state, returning }),\n onConflictDoNothing: () => query({ ...state, conflict: true }),\n });\n };\n\n const database: SqlDatabase = {\n $client: client,\n select: (selection?: Selection) => query({ operation: \"select\", selection }),\n insert: (table: Table) => query({ operation: \"insert\", table }),\n update: (table: Table) => query({ operation: \"update\", table }),\n delete: (table: Table) => query({ operation: \"delete\", table }),\n transaction: <A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R> =>\n client.withTransaction(Effect.suspend(() => body(database))),\n };\n\n return database;\n});\n\ninterface Query extends Effect.Effect<Row[], SqlError> {\n toSQL(): { readonly sql: string; readonly params: ReadonlyArray<unknown> };\n getSQL(): Fragment;\n from(table: Table | Fragment): Query;\n innerJoin(table: Table | Fragment, on: Fragment): Query;\n where(where: Fragment | undefined): Query;\n limit(limit: number): Query;\n orderBy(...order: Fragment[]): Query;\n for(lock: \"update\"): Query;\n values(values: Row): Query;\n set(values: Row): Query;\n returning(returning?: Selection | true): Query;\n onConflictDoNothing(): Query;\n}\n\nexport interface SqlDatabase {\n readonly $client: SqlClient;\n select(selection?: Selection): Query;\n insert(table: Table): Query;\n update(table: Table): Query;\n delete(table: Table): Query;\n transaction<A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport const sql = template;\n"],"mappings":"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"}
1
+ {"version":3,"file":"sql-query.mjs","names":[],"sources":["../../src/internal/sql-query.ts"],"sourcesContent":["import { Effect, Predicate } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { QueryOperations } from \"./query-operations\";\nimport {\n type Column,\n Fragment,\n Table,\n identifier,\n type Compiler,\n type Dialect,\n type Row,\n} from \"./sql-table\";\n\nconst render = (value: unknown, compiler: Compiler): string => {\n if (value instanceof Fragment) return value.render(compiler);\n if (Predicate.hasProperty(value, \"getSQL\") && typeof value.getSQL === \"function\") {\n return render(value.getSQL(), compiler);\n }\n\n compiler.parameters.push(\n compiler.dialect === \"sqlite\" && typeof value === \"boolean\" ? Number(value) : value,\n );\n\n return compiler.dialect === \"pg\" ? `$${compiler.parameters.length}` : \"?\";\n};\n\nconst template = (parts: TemplateStringsArray, ...values: unknown[]): Fragment =>\n new Fragment((compiler) =>\n parts.reduce(\n (sql, part, i) => sql + (i === 0 ? \"\" : render(values[i - 1], compiler)) + part,\n \"\",\n ),\n );\n\nconst combine = (separator: string, values: ReadonlyArray<Fragment | undefined>) => {\n const fragments = values.filter((value) => value !== undefined);\n\n return fragments.length === 0\n ? undefined\n : new Fragment(\n (compiler) =>\n \"(\" + fragments.map((fragment) => fragment.render(compiler)).join(separator) + \")\",\n );\n};\n\nconst and = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" AND \", values);\nconst or = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" OR \", values);\n\nconst operations = {\n and,\n or,\n asc: (value: unknown) => template`${value} ASC`,\n eq: (left: unknown, right: unknown) => template`${left} = ${right}`,\n gt: (left: unknown, right: unknown) => template`${left} > ${right}`,\n gte: (left: unknown, right: unknown) => template`${left} >= ${right}`,\n lte: (left: unknown, right: unknown) => template`${left} <= ${right}`,\n isNull: (value: unknown) => template`${value} IS NULL`,\n notExists: (value: unknown) => template`NOT EXISTS (${value})`,\n inArray: (column: unknown, values: ReadonlyArray<unknown>) =>\n values.length === 0\n ? template`false`\n : new Fragment(\n (compiler) =>\n `${render(column, compiler)} IN (${values.map((value) => render(value, compiler)).join(\", \")})`,\n ),\n sql: Object.assign(template, {\n param: (value: unknown, column: Column) => column.mapToDriverValue(value),\n join: (values: ReadonlyArray<unknown>, separator: Fragment = template``) =>\n new Fragment((compiler) =>\n values\n .map(\n (value, index) =>\n (index === 0 ? \"\" : separator.render(compiler)) + render(value, compiler),\n )\n .join(\"\"),\n ),\n }),\n getTableColumns: (table: Table) => table.columns,\n column: (table: Table, key: string) => {\n const column = table.columns[key];\n\n if (column === undefined)\n throw PersistenceMappingError.make({ operation: \"column\", cause: key });\n\n return column;\n },\n updateValues: (entries: ReadonlyArray<readonly [string, unknown]>) => Object.fromEntries(entries),\n balancedD1And: and,\n // Raw clients use interactive transactions, so no D1 batch compaction is needed.\n compactD1GeneratedStatement: <S>(_client: unknown, statement: S) => statement,\n};\n\n// The existing kernels erase query-builder shapes at this boundary. The raw compiler\n// implements precisely those operations; no row decoding or Effect requirements are cast.\nexport const sqlQueryOperations = operations as unknown as QueryOperations;\n\ntype Selection = Readonly<Record<string, Fragment>>;\n\ninterface QueryState {\n readonly operation: \"select\" | \"insert\" | \"update\" | \"delete\";\n readonly table?: Table | Fragment;\n readonly joins?: ReadonlyArray<{\n readonly table: Table | Fragment;\n readonly on: Fragment;\n }>;\n readonly selection?: Selection;\n readonly where?: Fragment | undefined;\n readonly values?: Row;\n readonly returning?: Selection | true;\n readonly order?: ReadonlyArray<Fragment>;\n readonly limit?: number;\n readonly lock?: boolean;\n readonly conflict?: boolean;\n}\n\nconst selectionFor = (state: QueryState): Selection =>\n state.selection ?? (state.table instanceof Table ? state.table.columns : {});\n\nconst selectionFields = (selection: Selection) => {\n const used = new Set(Object.keys(selection));\n let index = 0;\n\n return Object.entries(selection).flatMap<{\n readonly key: string;\n readonly name: string | undefined;\n readonly column: Fragment;\n readonly alias: string;\n }>(([key, value]) =>\n value instanceof Table\n ? Object.entries(value.columns).map(([name, column]) => {\n let alias: string;\n\n do alias = `auth_column_${index++}`;\n while (used.has(alias));\n used.add(alias);\n\n return { key, name, column, alias };\n })\n : [{ key, name: undefined, column: value, alias: key }],\n );\n};\n\nconst projection = (selection: Selection, compiler: Compiler) =>\n selectionFields(selection)\n .map(({ column, alias }) => `${column.render(compiler)} AS ${identifier(alias)}`)\n .join(\", \");\n\n// Joined table selections retain their own column codecs and nested row names.\nconst decodeRow = (selection: Selection, row: Row): Row => {\n const entries: Array<readonly [string, unknown]> = [];\n const groups = new Map<string, Array<readonly [string, unknown]>>();\n\n for (const field of selectionFields(selection)) {\n const value = field.column.decode(row[field.alias]);\n\n if (field.name === undefined) entries.push([field.key, value]);\n else {\n const group = groups.get(field.key) ?? [];\n\n group.push([field.name, value]);\n groups.set(field.key, group);\n }\n }\n\n return Object.fromEntries([\n ...entries,\n ...Array.from(groups, ([key, values]) => [key, Object.fromEntries(values)]),\n ]);\n};\n\nconst compile = (state: QueryState, compiler: Compiler): string => {\n const table = state.table;\n\n if (table === undefined)\n throw PersistenceMappingError.make({ operation: \"query\", cause: \"Missing table\" });\n let query: string;\n\n if (state.operation === \"select\") {\n query = `SELECT ${projection(selectionFor(state), compiler)} FROM ${table.render(compiler)}`;\n for (const join of state.joins ?? [])\n query += ` INNER JOIN ${join.table.render(compiler)} ON ${join.on.render(compiler)}`;\n } else {\n if (!(table instanceof Table))\n throw PersistenceMappingError.make({\n operation: \"query\",\n cause: \"Mutation requires a table\",\n });\n const target = table.render(compiler);\n\n const fields = Object.entries(state.values ?? {}).filter(\n ([key, value]) => table.columns[key] !== undefined && value !== undefined,\n );\n\n if (state.operation === \"insert\") {\n query = `INSERT INTO ${target} (${fields.map(([key]) => identifier(table.columns[key].options.name)).join(\", \")}) VALUES (${fields.map(([, value]) => render(value, compiler)).join(\", \")})`;\n } else if (state.operation === \"update\") {\n query = `UPDATE ${target} SET ${fields.map(([key, value]) => `${identifier(table.columns[key].options.name)} = ${render(value, compiler)}`).join(\", \")}`;\n } else query = `DELETE FROM ${target}`;\n }\n if (state.where !== undefined) query += ` WHERE ${state.where.render(compiler)}`;\n if (state.order?.length)\n query += ` ORDER BY ${state.order.map((field) => field.render(compiler)).join(\", \")}`;\n if (state.limit !== undefined) query += ` LIMIT ${render(state.limit, compiler)}`;\n if (state.conflict) query += \" ON CONFLICT DO NOTHING\";\n if (state.returning)\n query += ` RETURNING ${projection(state.returning === true && table instanceof Table ? table.columns : state.returning === true ? {} : state.returning, compiler)}`;\n if (state.lock && compiler.dialect === \"pg\") query += \" FOR UPDATE\";\n\n return query;\n};\n\n/** Captures one Effect SQL client. Its transaction service remains the physical owner. */\nexport const makeSqlDatabase = Effect.fnUntraced(function* (dialect: Dialect) {\n const client = yield* SqlClient;\n\n const query = (state: QueryState): Query => {\n const execute = Effect.suspend(() => {\n const compiler: Compiler = { dialect, parameters: [] };\n const text = compile(state, compiler);\n\n const selected: Selection =\n state.operation === \"select\"\n ? selectionFor(state)\n : state.returning === true\n ? state.table instanceof Table\n ? state.table.columns\n : {}\n : state.returning || {};\n\n return client\n .unsafe<Row>(text, compiler.parameters)\n .pipe(Effect.map((rows) => rows.map((row) => decodeRow(selected, row))));\n });\n\n return Object.assign(execute, {\n toSQL: () => {\n const compiler: Compiler = { dialect, parameters: [] };\n\n return { sql: compile(state, compiler), params: compiler.parameters };\n },\n getSQL: () => new Fragment((compiler) => compile(state, compiler)),\n from: (table: Table | Fragment) => query({ ...state, table }),\n innerJoin: (table: Table | Fragment, on: Fragment) =>\n query({ ...state, joins: [...(state.joins ?? []), { table, on }] }),\n where: (where: Fragment | undefined) => query({ ...state, where }),\n limit: (limit: number) => query({ ...state, limit }),\n orderBy: (...order: Fragment[]) => query({ ...state, order }),\n for: (_lock: \"update\") => query({ ...state, lock: true }),\n values: (values: Row) => query({ ...state, values }),\n set: (values: Row) => query({ ...state, values }),\n returning: (returning: Selection | true = true) => query({ ...state, returning }),\n onConflictDoNothing: () => query({ ...state, conflict: true }),\n });\n };\n\n const database: SqlDatabase = {\n $client: client,\n select: (selection?: Selection) =>\n query({ operation: \"select\", ...(selection === undefined ? {} : { selection }) }),\n insert: (table: Table) => query({ operation: \"insert\", table }),\n update: (table: Table) => query({ operation: \"update\", table }),\n delete: (table: Table) => query({ operation: \"delete\", table }),\n transaction: <A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R> =>\n client.withTransaction(Effect.suspend(() => body(database))),\n };\n\n return database;\n});\n\ninterface Query extends Effect.Effect<Row[], SqlError> {\n toSQL(): { readonly sql: string; readonly params: ReadonlyArray<unknown> };\n getSQL(): Fragment;\n from(table: Table | Fragment): Query;\n innerJoin(table: Table | Fragment, on: Fragment): Query;\n where(where: Fragment | undefined): Query;\n limit(limit: number): Query;\n orderBy(...order: Fragment[]): Query;\n for(lock: \"update\"): Query;\n values(values: Row): Query;\n set(values: Row): Query;\n returning(returning?: Selection | true): Query;\n onConflictDoNothing(): Query;\n}\n\nexport interface SqlDatabase {\n readonly $client: SqlClient;\n select(selection?: Selection): Query;\n insert(table: Table): Query;\n update(table: Table): Query;\n delete(table: Table): Query;\n transaction<A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport const sql = template;\n"],"mappings":";;;;;AAgBA,MAAM,UAAU,OAAgB,aAA+B;CAC7D,IAAI,iBAAiB,UAAU,OAAO,MAAM,OAAO,QAAQ;CAC3D,IAAI,UAAU,YAAY,OAAO,QAAQ,KAAK,OAAO,MAAM,WAAW,YACpE,OAAO,OAAO,MAAM,OAAO,GAAG,QAAQ;CAGxC,SAAS,WAAW,KAClB,SAAS,YAAY,YAAY,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI,KAChF;CAEA,OAAO,SAAS,YAAY,OAAO,IAAI,SAAS,WAAW,WAAW;AACxE;AAEA,MAAM,YAAY,OAA6B,GAAG,WAChD,IAAI,UAAU,aACZ,MAAM,QACH,KAAK,MAAM,MAAM,OAAO,MAAM,IAAI,KAAK,OAAO,OAAO,IAAI,IAAI,QAAQ,KAAK,MAC3E,EACF,CACF;AAEF,MAAM,WAAW,WAAmB,WAAgD;CAClF,MAAM,YAAY,OAAO,QAAQ,UAAU,UAAU,KAAA,CAAS;CAE9D,OAAO,UAAU,WAAW,IACxB,KAAA,IACA,IAAI,UACD,aACC,MAAM,UAAU,KAAK,aAAa,SAAS,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,GACnF;AACN;AAEA,MAAM,OAAO,GAAG,WAAgD,QAAQ,SAAS,MAAM;AACvF,MAAM,MAAM,GAAG,WAAgD,QAAQ,QAAQ,MAAM;AAgDrF,MAAa,qBAAqB;CA7ChC;CACA;CACA,MAAM,UAAmB,QAAQ,GAAG,MAAM;CAC1C,KAAK,MAAe,UAAmB,QAAQ,GAAG,KAAK,KAAK;CAC5D,KAAK,MAAe,UAAmB,QAAQ,GAAG,KAAK,KAAK;CAC5D,MAAM,MAAe,UAAmB,QAAQ,GAAG,KAAK,MAAM;CAC9D,MAAM,MAAe,UAAmB,QAAQ,GAAG,KAAK,MAAM;CAC9D,SAAS,UAAmB,QAAQ,GAAG,MAAM;CAC7C,YAAY,UAAmB,QAAQ,eAAe,MAAM;CAC5D,UAAU,QAAiB,WACzB,OAAO,WAAW,IACd,QAAQ,UACR,IAAI,UACD,aACC,GAAG,OAAO,QAAQ,QAAQ,EAAE,OAAO,OAAO,KAAK,UAAU,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EACjG;CACN,KAAK,OAAO,OAAO,UAAU;EAC3B,QAAQ,OAAgB,WAAmB,OAAO,iBAAiB,KAAK;EACxE,OAAO,QAAgC,YAAsB,QAAQ,OACnE,IAAI,UAAU,aACZ,OACG,KACE,OAAO,WACL,UAAU,IAAI,KAAK,UAAU,OAAO,QAAQ,KAAK,OAAO,OAAO,QAAQ,CAC5E,CAAC,CACA,KAAK,EAAE,CACZ;CACJ,CAAC;CACD,kBAAkB,UAAiB,MAAM;CACzC,SAAS,OAAc,QAAgB;EACrC,MAAM,SAAS,MAAM,QAAQ;EAE7B,IAAI,WAAW,KAAA,GACb,MAAM,wBAAwB,KAAK;GAAE,WAAW;GAAU,OAAO;EAAI,CAAC;EAExE,OAAO;CACT;CACA,eAAe,YAAuD,OAAO,YAAY,OAAO;CAChG,eAAe;CAEf,8BAAiC,SAAkB,cAAiB;AAKpC;AAqBlC,MAAM,gBAAgB,UACpB,MAAM,cAAc,MAAM,iBAAiB,QAAQ,MAAM,MAAM,UAAU,CAAC;AAE5E,MAAM,mBAAmB,cAAyB;CAChD,MAAM,OAAO,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC;CAC3C,IAAI,QAAQ;CAEZ,OAAO,OAAO,QAAQ,SAAS,CAAC,CAAC,SAK7B,CAAC,KAAK,WACR,iBAAiB,QACb,OAAO,QAAQ,MAAM,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,YAAY;EACpD,IAAI;EAEJ;GAAG,QAAQ,eAAe;SACnB,KAAK,IAAI,KAAK;EACrB,KAAK,IAAI,KAAK;EAEd,OAAO;GAAE;GAAK;GAAM;GAAQ;EAAM;CACpC,CAAC,IACD,CAAC;EAAE;EAAK,MAAM,KAAA;EAAW,QAAQ;EAAO,OAAO;CAAI,CAAC,CAC1D;AACF;AAEA,MAAM,cAAc,WAAsB,aACxC,gBAAgB,SAAS,CAAC,CACvB,KAAK,EAAE,QAAQ,YAAY,GAAG,OAAO,OAAO,QAAQ,EAAE,MAAM,WAAW,KAAK,GAAG,CAAC,CAChF,KAAK,IAAI;AAGd,MAAM,aAAa,WAAsB,QAAkB;CACzD,MAAM,UAA6C,CAAC;CACpD,MAAM,yBAAS,IAAI,IAA+C;CAElE,KAAK,MAAM,SAAS,gBAAgB,SAAS,GAAG;EAC9C,MAAM,QAAQ,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;EAElD,IAAI,MAAM,SAAS,KAAA,GAAW,QAAQ,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC;OACxD;GACH,MAAM,QAAQ,OAAO,IAAI,MAAM,GAAG,KAAK,CAAC;GAExC,MAAM,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC;GAC9B,OAAO,IAAI,MAAM,KAAK,KAAK;EAC7B;CACF;CAEA,OAAO,OAAO,YAAY,CACxB,GAAG,SACH,GAAG,MAAM,KAAK,SAAS,CAAC,KAAK,YAAY,CAAC,KAAK,OAAO,YAAY,MAAM,CAAC,CAAC,CAC5E,CAAC;AACH;AAEA,MAAM,WAAW,OAAmB,aAA+B;CACjE,MAAM,QAAQ,MAAM;CAEpB,IAAI,UAAU,KAAA,GACZ,MAAM,wBAAwB,KAAK;EAAE,WAAW;EAAS,OAAO;CAAgB,CAAC;CACnF,IAAI;CAEJ,IAAI,MAAM,cAAc,UAAU;EAChC,QAAQ,UAAU,WAAW,aAAa,KAAK,GAAG,QAAQ,EAAE,QAAQ,MAAM,OAAO,QAAQ;EACzF,KAAK,MAAM,QAAQ,MAAM,SAAS,CAAC,GACjC,SAAS,eAAe,KAAK,MAAM,OAAO,QAAQ,EAAE,MAAM,KAAK,GAAG,OAAO,QAAQ;CACrF,OAAO;EACL,IAAI,EAAE,iBAAiB,QACrB,MAAM,wBAAwB,KAAK;GACjC,WAAW;GACX,OAAO;EACT,CAAC;EACH,MAAM,SAAS,MAAM,OAAO,QAAQ;EAEpC,MAAM,SAAS,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,QAC/C,CAAC,KAAK,WAAW,MAAM,QAAQ,SAAS,KAAA,KAAa,UAAU,KAAA,CAClE;EAEA,IAAI,MAAM,cAAc,UACtB,QAAQ,eAAe,OAAO,IAAI,OAAO,KAAK,CAAC,SAAS,WAAW,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,YAAY,OAAO,KAAK,GAAG,WAAW,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;OACrL,IAAI,MAAM,cAAc,UAC7B,QAAQ,UAAU,OAAO,OAAO,OAAO,KAAK,CAAC,KAAK,WAAW,GAAG,WAAW,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,OAAO,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,IAAI;OAChJ,QAAQ,eAAe;CAChC;CACA,IAAI,MAAM,UAAU,KAAA,GAAW,SAAS,UAAU,MAAM,MAAM,OAAO,QAAQ;CAC7E,IAAI,MAAM,OAAO,QACf,SAAS,aAAa,MAAM,MAAM,KAAK,UAAU,MAAM,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;CACpF,IAAI,MAAM,UAAU,KAAA,GAAW,SAAS,UAAU,OAAO,MAAM,OAAO,QAAQ;CAC9E,IAAI,MAAM,UAAU,SAAS;CAC7B,IAAI,MAAM,WACR,SAAS,cAAc,WAAW,MAAM,cAAc,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,MAAM,cAAc,OAAO,CAAC,IAAI,MAAM,WAAW,QAAQ;CAClK,IAAI,MAAM,QAAQ,SAAS,YAAY,MAAM,SAAS;CAEtD,OAAO;AACT;;AAGA,MAAa,kBAAkB,OAAO,WAAW,WAAW,SAAkB;CAC5E,MAAM,SAAS,OAAO;CAEtB,MAAM,SAAS,UAA6B;EAC1C,MAAM,UAAU,OAAO,cAAc;GACnC,MAAM,WAAqB;IAAE;IAAS,YAAY,CAAC;GAAE;GACrD,MAAM,OAAO,QAAQ,OAAO,QAAQ;GAEpC,MAAM,WACJ,MAAM,cAAc,WAChB,aAAa,KAAK,IAClB,MAAM,cAAc,OAClB,MAAM,iBAAiB,QACrB,MAAM,MAAM,UACZ,CAAC,IACH,MAAM,aAAa,CAAC;GAE5B,OAAO,OACJ,OAAY,MAAM,SAAS,UAAU,CAAC,CACtC,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,UAAU,GAAG,CAAC,CAAC,CAAC;EAC3E,CAAC;EAED,OAAO,OAAO,OAAO,SAAS;GAC5B,aAAa;IACX,MAAM,WAAqB;KAAE;KAAS,YAAY,CAAC;IAAE;IAErD,OAAO;KAAE,KAAK,QAAQ,OAAO,QAAQ;KAAG,QAAQ,SAAS;IAAW;GACtE;GACA,cAAc,IAAI,UAAU,aAAa,QAAQ,OAAO,QAAQ,CAAC;GACjE,OAAO,UAA4B,MAAM;IAAE,GAAG;IAAO;GAAM,CAAC;GAC5D,YAAY,OAAyB,OACnC,MAAM;IAAE,GAAG;IAAO,OAAO,CAAC,GAAI,MAAM,SAAS,CAAC,GAAI;KAAE;KAAO;IAAG,CAAC;GAAE,CAAC;GACpE,QAAQ,UAAgC,MAAM;IAAE,GAAG;IAAO;GAAM,CAAC;GACjE,QAAQ,UAAkB,MAAM;IAAE,GAAG;IAAO;GAAM,CAAC;GACnD,UAAU,GAAG,UAAsB,MAAM;IAAE,GAAG;IAAO;GAAM,CAAC;GAC5D,MAAM,UAAoB,MAAM;IAAE,GAAG;IAAO,MAAM;GAAK,CAAC;GACxD,SAAS,WAAgB,MAAM;IAAE,GAAG;IAAO;GAAO,CAAC;GACnD,MAAM,WAAgB,MAAM;IAAE,GAAG;IAAO;GAAO,CAAC;GAChD,YAAY,YAA8B,SAAS,MAAM;IAAE,GAAG;IAAO;GAAU,CAAC;GAChF,2BAA2B,MAAM;IAAE,GAAG;IAAO,UAAU;GAAK,CAAC;EAC/D,CAAC;CACH;CAEA,MAAM,WAAwB;EAC5B,SAAS;EACT,SAAS,cACP,MAAM;GAAE,WAAW;GAAU,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;EAAG,CAAC;EAClF,SAAS,UAAiB,MAAM;GAAE,WAAW;GAAU;EAAM,CAAC;EAC9D,SAAS,UAAiB,MAAM;GAAE,WAAW;GAAU;EAAM,CAAC;EAC9D,SAAS,UAAiB,MAAM;GAAE,WAAW;GAAU;EAAM,CAAC;EAC9D,cACE,SAEA,OAAO,gBAAgB,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC;CAC/D;CAEA,OAAO;AACT,CAAC"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/auth-persistence","version":"0.1.0-beta.16","dependencies":{"@noble/hashes":"2.3.0","@yielded/auth":"0.1.0-beta.16","@yielded/auth-crypto":"0.1.0-beta.16"},"devDependencies":{"@effect/platform-node":"4.0.0","@effect/sql-libsql":"4.0.0","@effect/sql-sqlite-node":"4.0.0","@effect/vitest":"4.0.0","effect":"4.0.0","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Adapter":{"types":"./dist/Adapter.d.mts","default":"./dist/Adapter.mjs"}},"description":"Direct Effect SQL persistence and shared storage contracts 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"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
1
+ {"name":"@yielded/auth-persistence","version":"0.1.0-beta.18","dependencies":{"@noble/hashes":"2.3.0","@yielded/auth":"0.1.0-beta.18","@yielded/auth-crypto":"0.1.0-beta.18"},"devDependencies":{"@effect/platform-node":"4.0.0","@effect/sql-libsql":"4.0.0","@effect/sql-sqlite-node":"4.0.0","@effect/vitest":"4.0.0","effect":"4.0.0","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Adapter":{"types":"./dist/Adapter.d.mts","default":"./dist/Adapter.mjs"}},"description":"Direct Effect SQL persistence and shared storage contracts 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"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
@@ -62,7 +62,7 @@ export interface Strategy {
62
62
  export interface Definition<C extends ClaimsCodec, Id extends string> {
63
63
  readonly namespace: string;
64
64
  readonly claims: C;
65
- readonly sessionMode?: string;
65
+ readonly sessionMode?: string | undefined;
66
66
  readonly sessions: ReturnType<typeof makeSessions<C, Id>>;
67
67
  readonly strategies: Readonly<Record<string, Strategy>>;
68
68
  }
@@ -1168,9 +1168,9 @@ export const makePasswordKernel = <
1168
1168
  moduleId: input.moduleId,
1169
1169
  action: input.action,
1170
1170
  identifier: input.identifier,
1171
- ...(resolved === undefined
1171
+ ...(resolved?.snapshot === undefined
1172
1172
  ? {}
1173
- : { subjectId: resolved.snapshot?.revision.subjectId }),
1173
+ : { subjectId: resolved.snapshot.revision.subjectId }),
1174
1174
  });
1175
1175
 
1176
1176
  const scopes = scopeEntries(keys, input.policy);
@@ -403,7 +403,7 @@ export const createPersistence = <T extends object, R>(
403
403
  locking: dialect === "pg",
404
404
  standaloneGuard: standalone(() => PasswordUnavailable.make({})),
405
405
  insertIfAbsent: (query) => query.onConflictDoNothing(),
406
- proof: proofConfiguration,
406
+ ...(proofConfiguration === undefined ? {} : { proof: proofConfiguration }),
407
407
  })
408
408
  .pipe(
409
409
  Effect.provideService(CurrentPasswordSql, native),
@@ -439,7 +439,7 @@ export const createPersistence = <T extends object, R>(
439
439
  mode: "interactive",
440
440
  locking: dialect === "pg",
441
441
  standaloneGuard: standalone(() => EmailUnavailable.make({})),
442
- proof: proofConfiguration,
442
+ ...(proofConfiguration === undefined ? {} : { proof: proofConfiguration }),
443
443
  })
444
444
  .pipe(
445
445
  Effect.provideService(CurrentEmailSql, native),
@@ -466,7 +466,7 @@ export const makeSessionKernel = (operations: QueryOperations) => {
466
466
  const ensureDirectFlowAvailable = Effect.fn("DrizzleSession.ensureFlowAvailable")(function* (
467
467
  mapping: AnyAuthorityMapping &
468
468
  AnyFlowMapping & {
469
- readonly pending?: PendingAuthenticationTables<any, any, any, any>["pending"];
469
+ readonly pending?: PendingAuthenticationTables<any, any, any, any>["pending"] | undefined;
470
470
  },
471
471
  evidence: AuthenticationEvidence,
472
472
  nativeSubjectId: unknown,
@@ -1389,10 +1389,11 @@ export const makeSessionKernel = (operations: QueryOperations) => {
1389
1389
  );
1390
1390
 
1391
1391
  const extra = decoded[input.limit];
1392
+ const nextCursor = extra === undefined ? undefined : sessions.at(-1)?.sessionId;
1392
1393
 
1393
1394
  return {
1394
1395
  sessions,
1395
- ...(extra === undefined ? {} : { nextCursor: sessions.at(-1)?.sessionId }),
1396
+ ...(nextCursor === undefined ? {} : { nextCursor }),
1396
1397
  };
1397
1398
  }),
1398
1399
  ),
@@ -107,7 +107,7 @@ interface QueryState {
107
107
  readonly on: Fragment;
108
108
  }>;
109
109
  readonly selection?: Selection;
110
- readonly where?: Fragment;
110
+ readonly where?: Fragment | undefined;
111
111
  readonly values?: Row;
112
112
  readonly returning?: Selection | true;
113
113
  readonly order?: ReadonlyArray<Fragment>;
@@ -258,7 +258,8 @@ export const makeSqlDatabase = Effect.fnUntraced(function* (dialect: Dialect) {
258
258
 
259
259
  const database: SqlDatabase = {
260
260
  $client: client,
261
- select: (selection?: Selection) => query({ operation: "select", selection }),
261
+ select: (selection?: Selection) =>
262
+ query({ operation: "select", ...(selection === undefined ? {} : { selection }) }),
262
263
  insert: (table: Table) => query({ operation: "insert", table }),
263
264
  update: (table: Table) => query({ operation: "update", table }),
264
265
  delete: (table: Table) => query({ operation: "delete", table }),