easy-ping 0.10.1 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +10 -5
  2. package/dist/adapters/drizzle.cjs +0 -2
  3. package/dist/adapters/drizzle.js +3 -5
  4. package/dist/adapters/mongodb.cjs +0 -2
  5. package/dist/adapters/mongodb.js +4 -6
  6. package/dist/adapters/mysql.cjs +0 -2
  7. package/dist/adapters/mysql.js +6 -8
  8. package/dist/adapters/postgres.cjs +0 -2
  9. package/dist/adapters/postgres.js +8 -10
  10. package/dist/adapters/sqlite.cjs +0 -2
  11. package/dist/adapters/sqlite.js +6 -8
  12. package/dist/browser.cjs +0 -2
  13. package/dist/browser.js +0 -2
  14. package/dist/{chunk-JKTMUMQK.js → chunk-2UOEAG6H.js} +1 -3
  15. package/dist/{chunk-R3BE67L7.js → chunk-74KSKP6B.js} +0 -2
  16. package/dist/{chunk-O2PBBL5X.js → chunk-7C4K5WKW.js} +1 -3
  17. package/dist/{chunk-CK5UPVYP.js → chunk-CRSGL5SG.js} +0 -2
  18. package/dist/{chunk-PTGHMCCG.js → chunk-D3UX3WWD.js} +0 -2
  19. package/dist/{chunk-CMWOIYVQ.js → chunk-EN3NMHSI.js} +4 -6
  20. package/dist/{chunk-ORZKH224.js → chunk-G32BYQAT.js} +0 -2
  21. package/dist/{chunk-A4HX5YTG.js → chunk-IXXPJMYS.js} +3 -5
  22. package/dist/{chunk-CFLVAF2R.js → chunk-JDR3U7X4.js} +2 -4
  23. package/dist/{chunk-AEYYTE5I.js → chunk-JRZ2U4IT.js} +0 -2
  24. package/dist/{chunk-UM2L26PV.js → chunk-KOS3YZMZ.js} +1 -3
  25. package/dist/{chunk-HSB5T3LD.js → chunk-OKIQ5BEV.js} +1 -3
  26. package/dist/{chunk-JN3UCQBP.js → chunk-SZWEW3WN.js} +0 -2
  27. package/dist/{chunk-SSHVZHSJ.js → chunk-VA4W4UFI.js} +0 -2
  28. package/dist/client.cjs +0 -2
  29. package/dist/client.js +0 -2
  30. package/dist/index.cjs +0 -2
  31. package/dist/index.js +12 -14
  32. package/dist/node.cjs +0 -2
  33. package/dist/node.js +3 -5
  34. package/dist/plugins/digests.cjs +0 -2
  35. package/dist/plugins/digests.js +1 -3
  36. package/dist/plugins/mobile-push.cjs +0 -2
  37. package/dist/plugins/mobile-push.js +3 -5
  38. package/dist/plugins/preferences-client.cjs +0 -2
  39. package/dist/plugins/preferences-client.js +1 -3
  40. package/dist/plugins/preferences-react.cjs +0 -1
  41. package/dist/plugins/preferences-react.js +0 -1
  42. package/dist/plugins/preferences.cjs +0 -2
  43. package/dist/plugins/preferences.js +3 -5
  44. package/dist/plugins/push.cjs +0 -2
  45. package/dist/plugins/push.js +4 -6
  46. package/dist/plugins/telegram.cjs +0 -2
  47. package/dist/plugins/telegram.js +5 -7
  48. package/dist/providers/expo-push.cjs +0 -2
  49. package/dist/providers/expo-push.js +0 -2
  50. package/dist/providers/resend.cjs +0 -2
  51. package/dist/providers/resend.js +0 -2
  52. package/dist/providers/telegram.cjs +0 -2
  53. package/dist/providers/telegram.js +1 -3
  54. package/dist/providers/web-push.cjs +0 -2
  55. package/dist/providers/web-push.js +1 -3
  56. package/dist/react-native.cjs +0 -1
  57. package/dist/react-native.js +0 -1
  58. package/dist/react.cjs +0 -1
  59. package/dist/react.js +0 -1
  60. package/dist/schema.cjs +0 -2
  61. package/dist/schema.js +4 -6
  62. package/dist/sw.cjs +0 -2
  63. package/dist/sw.js +0 -2
  64. package/dist/testing.cjs +0 -2
  65. package/dist/testing.js +0 -2
  66. package/package.json +7 -5
  67. package/dist/adapters/drizzle.cjs.map +0 -1
  68. package/dist/adapters/drizzle.js.map +0 -1
  69. package/dist/adapters/mongodb.cjs.map +0 -1
  70. package/dist/adapters/mongodb.js.map +0 -1
  71. package/dist/adapters/mysql.cjs.map +0 -1
  72. package/dist/adapters/mysql.js.map +0 -1
  73. package/dist/adapters/postgres.cjs.map +0 -1
  74. package/dist/adapters/postgres.js.map +0 -1
  75. package/dist/adapters/sqlite.cjs.map +0 -1
  76. package/dist/adapters/sqlite.js.map +0 -1
  77. package/dist/browser.cjs.map +0 -1
  78. package/dist/browser.js.map +0 -1
  79. package/dist/chunk-A4HX5YTG.js.map +0 -1
  80. package/dist/chunk-AEYYTE5I.js.map +0 -1
  81. package/dist/chunk-CFLVAF2R.js.map +0 -1
  82. package/dist/chunk-CK5UPVYP.js.map +0 -1
  83. package/dist/chunk-CMWOIYVQ.js.map +0 -1
  84. package/dist/chunk-HSB5T3LD.js.map +0 -1
  85. package/dist/chunk-JKTMUMQK.js.map +0 -1
  86. package/dist/chunk-JN3UCQBP.js.map +0 -1
  87. package/dist/chunk-O2PBBL5X.js.map +0 -1
  88. package/dist/chunk-ORZKH224.js.map +0 -1
  89. package/dist/chunk-PTGHMCCG.js.map +0 -1
  90. package/dist/chunk-R3BE67L7.js.map +0 -1
  91. package/dist/chunk-SSHVZHSJ.js.map +0 -1
  92. package/dist/chunk-UM2L26PV.js.map +0 -1
  93. package/dist/client.cjs.map +0 -1
  94. package/dist/client.js.map +0 -1
  95. package/dist/index.cjs.map +0 -1
  96. package/dist/index.js.map +0 -1
  97. package/dist/node.cjs.map +0 -1
  98. package/dist/node.js.map +0 -1
  99. package/dist/plugins/digests.cjs.map +0 -1
  100. package/dist/plugins/digests.js.map +0 -1
  101. package/dist/plugins/mobile-push.cjs.map +0 -1
  102. package/dist/plugins/mobile-push.js.map +0 -1
  103. package/dist/plugins/preferences-client.cjs.map +0 -1
  104. package/dist/plugins/preferences-client.js.map +0 -1
  105. package/dist/plugins/preferences-react.cjs.map +0 -1
  106. package/dist/plugins/preferences-react.js.map +0 -1
  107. package/dist/plugins/preferences.cjs.map +0 -1
  108. package/dist/plugins/preferences.js.map +0 -1
  109. package/dist/plugins/push.cjs.map +0 -1
  110. package/dist/plugins/push.js.map +0 -1
  111. package/dist/plugins/telegram.cjs.map +0 -1
  112. package/dist/plugins/telegram.js.map +0 -1
  113. package/dist/providers/expo-push.cjs.map +0 -1
  114. package/dist/providers/expo-push.js.map +0 -1
  115. package/dist/providers/resend.cjs.map +0 -1
  116. package/dist/providers/resend.js.map +0 -1
  117. package/dist/providers/telegram.cjs.map +0 -1
  118. package/dist/providers/telegram.js.map +0 -1
  119. package/dist/providers/web-push.cjs.map +0 -1
  120. package/dist/providers/web-push.js.map +0 -1
  121. package/dist/react-native.cjs.map +0 -1
  122. package/dist/react-native.js.map +0 -1
  123. package/dist/react.cjs.map +0 -1
  124. package/dist/react.js.map +0 -1
  125. package/dist/schema.cjs.map +0 -1
  126. package/dist/schema.js.map +0 -1
  127. package/dist/sw.cjs.map +0 -1
  128. package/dist/sw.js.map +0 -1
  129. package/dist/testing.cjs.map +0 -1
  130. package/dist/testing.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/base64url.ts","../../src/schema/declaration.ts","../../src/core/store.ts","../../src/adapters/sql/statement.ts","../../src/adapters/sql/adapter.ts","../../src/adapters/sql/dialect.ts","../../src/adapters/sqlite/adapter.ts","../../src/schema/render-sqlite.ts","../../src/adapters/sqlite/helpers.ts"],"names":["quote"],"mappings":"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","file":"sqlite.cjs","sourcesContent":["// Web APIs, not Buffer: this runs on Workers and Vercel Edge.\n\nexport function encodeBase64Url(input: string | Uint8Array): string {\n const bytes = typeof input === \"string\" ? new TextEncoder().encode(input) : input;\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n// Uint8Array<ArrayBuffer>: bare Uint8Array widens and is not a BufferSource.\nexport function decodeBase64UrlBytes(value: string): Uint8Array<ArrayBuffer> | null {\n try {\n const binary = atob(value.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n return Uint8Array.from(binary, (char) => char.charCodeAt(0));\n } catch {\n return null;\n }\n}\n\nexport function decodeBase64Url(value: string): string | null {\n const bytes = decodeBase64UrlBytes(value);\n return bytes ? new TextDecoder().decode(bytes) : null;\n}\n","import type { SchemaDeclaration } from \"../core/plugin\";\n\nexport const toSnakeCase = (value: string) => value.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n\n/** Core tables in the plugin format. A drift test asserts it agrees with the Drizzle schema. */\nexport const coreSchema = {\n notification: {\n tableName: \"notification\",\n fields: {\n id: { type: \"string\", required: true },\n userId: { type: \"string\", required: true },\n type: { type: \"string\", required: true },\n payload: { type: \"json\", required: true },\n actorId: { type: \"string\" },\n groupKey: { type: \"string\" },\n dedupeKey: { type: \"string\" },\n seenAt: { type: \"date\" },\n readAt: { type: \"date\" },\n archivedAt: { type: \"date\" },\n createdAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"id\"],\n indexes: [\n { on: [\"userId\", \"createdAt\"], name: \"notification_feed_idx\" },\n { on: [\"userId\", \"groupKey\"], name: \"notification_group_idx\" },\n { on: [\"userId\", \"dedupeKey\"], unique: true, name: \"notification_dedupe_idx\" },\n ],\n },\n\n notificationDelivery: {\n tableName: \"notification_delivery\",\n fields: {\n id: { type: \"string\", required: true },\n notificationId: { type: \"string\", required: true },\n channel: { type: \"string\", required: true },\n status: { type: \"string\", required: true, default: \"pending\" },\n attempts: { type: \"number\", required: true, default: 0 },\n maxAttempts: { type: \"number\", required: true, default: 5 },\n notBefore: { type: \"date\", required: true, defaultNow: true },\n claimedAt: { type: \"date\" },\n claimedBy: { type: \"string\" },\n lastError: { type: \"string\" },\n updatedAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"id\"],\n indexes: [\n { on: [\"status\", \"notBefore\"], name: \"delivery_claim_idx\" },\n { on: [\"notificationId\"], name: \"delivery_notification_idx\" },\n ],\n },\n\n notificationPreference: {\n tableName: \"notification_preference\",\n fields: {\n userId: { type: \"string\", required: true },\n type: { type: \"string\", required: true },\n channel: { type: \"string\", required: true },\n enabled: { type: \"boolean\", required: true, default: true },\n frequency: { type: \"string\", required: true, default: \"instant\" },\n updatedAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"userId\", \"type\", \"channel\"],\n },\n} satisfies SchemaDeclaration;\n","import { toSnakeCase } from \"../schema/declaration\";\nimport { ConfigError } from \"./errors\";\nimport type { FieldDeclaration, SchemaDeclaration, TableDeclaration } from \"./plugin\";\n\nexport type Scalar = string | number | boolean | Date | null;\n\n/** Operators are tagged objects so a bare value is always equality; json columns cannot be filtered. */\nexport type WhereCondition =\n | Scalar\n | { in: readonly (string | number)[] }\n | { lt: Date | number }\n | { lte: Date | number }\n | { gt: Date | number }\n | { gte: Date | number }\n | { not: Scalar };\n\nexport type WhereClause = Record<string, WhereCondition>;\n\nexport type QueryOptions = {\n limit?: number;\n orderBy?: { field: string; direction: \"asc\" | \"desc\" };\n};\n\nexport type UpsertOptions = { onConflict: readonly string[] };\n\n/** Table access for plugins, scoped to the tables the plugin declared. */\nexport type PluginStore = {\n find<T = Record<string, unknown>>(\n table: string,\n where?: WhereClause,\n options?: QueryOptions,\n ): Promise<T[]>;\n insert(table: string, rows: readonly Record<string, unknown>[]): Promise<number>;\n upsert(\n table: string,\n rows: readonly Record<string, unknown>[],\n options: UpsertOptions,\n ): Promise<number>;\n update(table: string, where: WhereClause, set: Record<string, unknown>): Promise<number>;\n remove(table: string, where: WhereClause): Promise<number>;\n};\n\nexport type TableStorage = {\n readonly naming?: \"snake_case\" | \"preserve\";\n readonly serializesJson?: boolean;\n\n queryTable(\n table: string,\n where: WhereClause,\n options: QueryOptions,\n ): Promise<Record<string, unknown>[]>;\n insertRows(\n table: string,\n rows: readonly Record<string, unknown>[],\n onConflict?: readonly string[],\n ): Promise<number>;\n updateRows(table: string, where: WhereClause, set: Record<string, unknown>): Promise<number>;\n deleteRows(table: string, where: WhereClause): Promise<number>;\n};\n\nconst OPERATORS = [\"in\", \"lt\", \"lte\", \"gt\", \"gte\", \"not\"] as const;\n\nexport const isOperator = (value: unknown): boolean =>\n typeof value === \"object\" &&\n value !== null &&\n !(value instanceof Date) &&\n OPERATORS.some((op) => Object.hasOwn(value, op));\n\nconst isScalar = (value: unknown): value is Scalar =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value instanceof Date;\n\n/** A forwarded JSON body can carry `{ $ne: … }`; refuse anything that is not a scalar or a known operator. */\nfunction assertCondition(pluginId: string, field: string, condition: unknown): void {\n if (isScalar(condition)) return;\n\n if (isOperator(condition)) {\n const operator = condition as Record<string, unknown>;\n const keys = Object.keys(operator);\n const [op] = keys;\n if (keys.length !== 1 || op === undefined) {\n throw new ConfigError(`plugin \"${pluginId}\" gave field \"${field}\" more than one operator.`);\n }\n const payload = operator[op];\n const valid =\n op === \"in\"\n ? Array.isArray(payload) &&\n payload.every((item) => typeof item === \"string\" || typeof item === \"number\")\n : isScalar(payload);\n if (valid) return;\n }\n\n throw new ConfigError(\n `plugin \"${pluginId}\" passed a non-scalar value for field \"${field}\"; ` +\n \"validate request bodies before querying with them.\",\n );\n}\n\nfunction assertValue(pluginId: string, field: string, spec: FieldDeclaration, value: unknown) {\n if (value === undefined || isScalar(value)) return;\n if (spec.type === \"json\" && typeof value === \"object\") return;\n throw new ConfigError(\n `plugin \"${pluginId}\" passed a non-scalar value for ${spec.type} field \"${field}\".`,\n );\n}\n\n/** Every table and column is checked against the plugin's own declaration. */\nexport function createPluginStore(\n pluginId: string,\n schema: SchemaDeclaration | undefined,\n storage: TableStorage,\n prefix: string,\n): PluginStore {\n const byTableName = new Map<string, TableDeclaration>();\n for (const declaration of Object.values(schema ?? {})) {\n byTableName.set(declaration.tableName, declaration);\n }\n\n function resolve(table: string): TableDeclaration {\n const declaration = byTableName.get(table);\n if (!declaration) {\n throw new ConfigError(\n `plugin \"${pluginId}\" accessed table \"${table}\", which it does not declare in schema().`,\n );\n }\n return declaration;\n }\n\n function writable(table: string): TableDeclaration {\n const declaration = resolve(table);\n if (declaration.readOnly) {\n throw new ConfigError(\n `plugin \"${pluginId}\" tried to write \"${table}\", which it declares readOnly.`,\n );\n }\n return declaration;\n }\n\n function notEverything(table: string, where: WhereClause, action: string) {\n if (Object.keys(where).length === 0) {\n throw new ConfigError(\n `plugin \"${pluginId}\" called ${action}(\"${table}\", {}), which would touch every row. ` +\n \"Pass a condition.\",\n );\n }\n }\n\n function checkFields(table: TableDeclaration, fields: Iterable<string>, context: string) {\n for (const field of fields) {\n // hasOwn, not a lookup: `constructor` and `__proto__` are not columns.\n const spec = Object.hasOwn(table.fields, field) ? table.fields[field] : undefined;\n if (!spec) {\n throw new ConfigError(\n `plugin \"${pluginId}\" used unknown field \"${field}\" on \"${table.tableName}\" (${context}).`,\n );\n }\n if (context === \"where\" && spec.type === \"json\") {\n throw new ConfigError(\n `plugin \"${pluginId}\" cannot filter on json field \"${field}\"; ` +\n \"a bare object value is indistinguishable from an operator.\",\n );\n }\n }\n }\n\n function checkWhere(table: TableDeclaration, where: WhereClause) {\n checkFields(table, Object.keys(where), \"where\");\n for (const [field, condition] of Object.entries(where)) {\n assertCondition(pluginId, field, condition);\n }\n }\n\n function checkRow(table: TableDeclaration, row: Record<string, unknown>, context: string) {\n checkFields(table, Object.keys(row), context);\n for (const [field, value] of Object.entries(row)) {\n const spec = table.fields[field];\n if (spec) assertValue(pluginId, field, spec, value);\n }\n }\n\n const qualified = (table: TableDeclaration) => prefix + table.tableName;\n\n // A document store keeps the declared names; a SQL adapter wants columns.\n const column = (field: string) => (storage.naming === \"preserve\" ? field : toSnakeCase(field));\n\n // json must reach postgres-js as text.\n const serialize = (table: TableDeclaration, row: Record<string, unknown>) => {\n if (storage.serializesJson === false) return row;\n\n const out: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(row)) {\n out[field] =\n table.fields[field]?.type === \"json\" && value !== null && value !== undefined\n ? JSON.stringify(value)\n : value;\n }\n return out;\n };\n\n return {\n async find(table, where = {}, options = {}) {\n const declaration = resolve(table);\n checkWhere(declaration, where);\n if (options.orderBy) checkFields(declaration, [options.orderBy.field], \"orderBy\");\n\n const rows = await storage.queryTable(qualified(declaration), where, options);\n\n // SELECT * returns snake_case; plugins read camelCase.\n return rows.map((row) => {\n const mapped: Record<string, unknown> = {};\n for (const field of Object.keys(declaration.fields)) {\n const value = row[column(field)];\n const type = declaration.fields[field]?.type;\n // Drivers differ on jsonb (parsed or text) and timestamptz (Date or text).\n if (type === \"json\" && typeof value === \"string\") mapped[field] = JSON.parse(value);\n else if (type === \"date\" && typeof value === \"string\") mapped[field] = new Date(value);\n // MySQL and SQLite have no boolean column; they hand back 0 and 1.\n else if (type === \"boolean\" && typeof value === \"number\") mapped[field] = value !== 0;\n else mapped[field] = value;\n }\n return mapped;\n }) as never;\n },\n\n async insert(table, rows) {\n const declaration = writable(table);\n for (const row of rows) checkRow(declaration, row, \"insert\");\n return storage.insertRows(\n qualified(declaration),\n rows.map((row) => serialize(declaration, row)),\n );\n },\n\n async upsert(table, rows, options) {\n const declaration = writable(table);\n for (const row of rows) checkRow(declaration, row, \"upsert\");\n checkFields(declaration, options.onConflict, \"onConflict\");\n return storage.insertRows(\n qualified(declaration),\n rows.map((row) => serialize(declaration, row)),\n options.onConflict,\n );\n },\n\n async update(table, where, set) {\n const declaration = writable(table);\n checkWhere(declaration, where);\n notEverything(table, where, \"update\");\n checkRow(declaration, set, \"update\");\n return storage.updateRows(qualified(declaration), where, serialize(declaration, set));\n },\n\n async remove(table, where) {\n const declaration = writable(table);\n checkWhere(declaration, where);\n notEverything(table, where, \"remove\");\n return storage.deleteRows(qualified(declaration), where);\n },\n };\n}\n","export type Placeholder = \"dollar\" | \"question\";\n\nexport type StatementOptions = {\n /** `$1, $2` for Postgres; `?` for MySQL and SQLite. */\n placeholder?: Placeholder;\n /** What the driver is handed for a JS value. Dates become ISO strings by default. */\n bind?: (value: unknown) => unknown;\n};\n\nconst defaultBind = (value: unknown) => (value instanceof Date ? value.toISOString() : value);\n\n/** SQL text plus bound values. Values are never interpolated; identifiers arrive pre-validated. */\nexport class Statement {\n #text = \"\";\n readonly params: unknown[] = [];\n readonly #placeholder: Placeholder;\n readonly #bind: (value: unknown) => unknown;\n\n constructor(options: StatementOptions = {}) {\n this.#placeholder = options.placeholder ?? \"dollar\";\n this.#bind = options.bind ?? defaultBind;\n }\n\n /** Raw SQL. Never user input; use `value`. */\n raw(fragment: string): this {\n this.#text += fragment;\n return this;\n }\n\n value(value: unknown): this {\n this.params.push(this.#bind(value));\n this.#text += this.#placeholder === \"dollar\" ? `$${this.params.length}` : \"?\";\n return this;\n }\n\n list(values: readonly unknown[], separator = \", \"): this {\n values.forEach((value, index) => {\n if (index > 0) this.raw(separator);\n this.value(value);\n });\n return this;\n }\n\n /** `($1::text, $2::timestamptz)`. Casts are Postgres-only and dropped elsewhere. */\n tuple(cells: readonly (readonly [unknown, string])[]): this {\n this.raw(\"(\");\n cells.forEach(([value, cast], index) => {\n if (index > 0) this.raw(\", \");\n this.value(value);\n if (this.#placeholder === \"dollar\") this.raw(`::${cast}`);\n });\n return this.raw(\")\");\n }\n\n get text(): string {\n return this.#text;\n }\n}\n\nexport const quoteWith =\n (quoteChar: '\"' | \"`\") =>\n (identifier: string): string =>\n `${quoteChar}${identifier.split(quoteChar).join(quoteChar + quoteChar)}${quoteChar}`;\n\n/** Double-quoted: Postgres and SQLite. */\nexport const quote = quoteWith('\"');\n","import type {\n ClaimArgs,\n ClaimedDelivery,\n DatabaseAdapter,\n DeliveryRelease,\n FeedPage,\n FeedQuery,\n InsertNotification,\n} from \"../../core/adapter\";\nimport { decodeBase64Url, encodeBase64Url } from \"../../core/base64url\";\nimport { isOperator, type QueryOptions, type WhereClause } from \"../../core/store\";\nimport type { Channel, DeliveryRecord, DeliveryStatus, NotificationRecord } from \"../../core/types\";\nimport { toSnakeCase } from \"../../schema/declaration\";\nimport type { Dialect, Row, SqlExec, SqlResult } from \"./dialect\";\nimport { Statement } from \"./statement\";\n\nexport type SqlAdapterOptions = {\n /** Table-name prefix. Must match the instance's `tablePrefix`. */\n prefix?: string;\n /** Makes createNotifications atomic and, on MySQL, lets a claim use FOR UPDATE SKIP LOCKED. */\n transaction?: <T>(fn: (exec: SqlExec) => Promise<T>) => Promise<T>;\n};\n\nconst str = (value: unknown): string => String(value);\nconst nullableStr = (value: unknown): string | null => (value == null ? null : String(value));\nconst num = (value: unknown): number => Number(value);\n\nconst encodeCursor = (createdAt: Date, id: string) =>\n encodeBase64Url(`${createdAt.toISOString()}|${id}`);\n\nfunction decodeCursor(cursor: string): { createdAt: Date; id: string } | null {\n const decoded = decodeBase64Url(cursor);\n if (!decoded) return null;\n const [iso, id] = decoded.split(\"|\");\n if (!iso || !id) return null;\n const createdAt = new Date(iso);\n return Number.isNaN(createdAt.getTime()) ? null : { createdAt, id };\n}\n\nconst NONE: SqlResult = { rows: [], affectedRows: 0 };\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** InnoDB rolls back the loser of a deadlock and asks for a retry; bounded and jittered. */\nasync function retryingLocks<T>(dialect: Dialect, attempt: () => Promise<T>): Promise<T> {\n for (let tries = 0; ; tries += 1) {\n try {\n return await attempt();\n } catch (error) {\n if (tries >= 5 || !dialect.isRetryableLock(error)) throw error;\n await sleep(5 + Math.random() * 20 * (tries + 1));\n }\n }\n}\n\n/**\n * Every SQL engine that is not Postgres, behind one dialect: the same queries\n * minus RETURNING, casts and IS DISTINCT FROM. RFC 0005.\n */\nexport function createSqlAdapter(\n dialect: Dialect,\n exec: SqlExec,\n options: SqlAdapterOptions = {},\n): DatabaseAdapter {\n const prefix = options.prefix ?? \"\";\n const q = dialect.quote;\n const NOTIFICATION = q(`${prefix}notification`);\n const DELIVERY = q(`${prefix}notification_delivery`);\n\n const stmt = () => new Statement({ placeholder: dialect.placeholder, bind: dialect.bind });\n const run = (statement: Statement, on: SqlExec = exec) => on(statement.text, statement.params);\n const atomically = <T>(fn: (on: SqlExec) => Promise<T>): Promise<T> =>\n options.transaction ? options.transaction(fn) : fn(exec);\n\n const toNotification = (row: Row): NotificationRecord => ({\n id: str(row.id),\n userId: str(row.user_id),\n type: str(row.type),\n payload: dialect.readJson(row.payload),\n actorId: nullableStr(row.actor_id),\n groupKey: nullableStr(row.group_key),\n dedupeKey: nullableStr(row.dedupe_key),\n seenAt: dialect.readNullableDate(row.seen_at),\n readAt: dialect.readNullableDate(row.read_at),\n archivedAt: dialect.readNullableDate(row.archived_at),\n createdAt: dialect.readDate(row.created_at),\n });\n\n const toDelivery = (row: Row): DeliveryRecord => ({\n id: str(row.id),\n notificationId: str(row.notification_id),\n channel: str(row.channel) as Channel,\n status: str(row.status) as DeliveryStatus,\n attempts: num(row.attempts),\n maxAttempts: num(row.max_attempts),\n notBefore: dialect.readDate(row.not_before),\n claimedAt: dialect.readNullableDate(row.claimed_at),\n claimedBy: nullableStr(row.claimed_by),\n lastError: nullableStr(row.last_error),\n updatedAt: dialect.readDate(row.updated_at),\n });\n\n function appendWhere(statement: Statement, where: WhereClause): void {\n const entries = Object.entries(where);\n if (entries.length === 0) return;\n\n statement.raw(\" WHERE \");\n\n entries.forEach(([field, condition], index) => {\n if (index > 0) statement.raw(\" AND \");\n const column = q(toSnakeCase(field));\n\n if (condition === null) {\n statement.raw(`${column} IS NULL`);\n return;\n }\n if (!isOperator(condition)) {\n statement.raw(`${column} = `).value(condition);\n return;\n }\n\n const operator = condition as Record<string, unknown>;\n if (\"in\" in operator) {\n const list = operator.in as readonly (string | number)[];\n if (list.length === 0) statement.raw(\"1 = 0\");\n else statement.raw(`${column} IN (`).list(list).raw(\")\");\n return;\n }\n if (\"lt\" in operator) statement.raw(`${column} < `).value(operator.lt);\n else if (\"lte\" in operator) statement.raw(`${column} <= `).value(operator.lte);\n else if (\"gt\" in operator) statement.raw(`${column} > `).value(operator.gt);\n else if (\"gte\" in operator) statement.raw(`${column} >= `).value(operator.gte);\n else if (\"not\" in operator) {\n if (operator.not === null) statement.raw(`${column} IS NOT NULL`);\n else dialect.distinctFrom(statement, column, operator.not);\n } else statement.raw(\"1 = 1\");\n });\n }\n\n function eligible(statement: Statement, args: ClaimArgs, now: Date, staleBefore: Date): void {\n statement\n .raw(\"(status = 'pending' OR (status = 'claimed' AND claimed_at < \")\n .value(staleBefore)\n .raw(\")) AND not_before <= \")\n .value(now)\n .raw(\" AND attempts < max_attempts\");\n if (args.channels && args.channels.length > 0) {\n statement.raw(\" AND channel IN (\").list(args.channels).raw(\")\");\n }\n if (args.ids && args.ids.length > 0) {\n statement.raw(\" AND id IN (\").list(args.ids).raw(\")\");\n }\n }\n\n /** The token is unique per call, so this is exactly what the call just claimed. */\n const readClaimed = (token: string, on: SqlExec) =>\n run(\n stmt()\n .raw(\n \"SELECT c.id, c.notification_id, c.channel, c.attempts, c.max_attempts,\" +\n ` n.user_id, n.type, n.payload, n.actor_id FROM ${DELIVERY} c` +\n ` JOIN ${NOTIFICATION} n ON n.id = c.notification_id WHERE c.claimed_by = `,\n )\n .value(token)\n .raw(\" AND c.status = 'claimed' ORDER BY c.not_before ASC, c.id ASC\"),\n on,\n );\n\n return {\n name: dialect.name,\n naming: \"snake_case\",\n serializesJson: true,\n\n async createNotifications(input: readonly InsertNotification[]) {\n if (input.length === 0) return { created: [], deduped: [] };\n const now = new Date();\n\n return atomically(async (on) => {\n const created: string[] = [];\n const deduped: string[] = [];\n\n // No RETURNING on MySQL and INSERT IGNORE hides real errors: look, insert, treat a race as dedupe.\n for (const row of input) {\n if (row.dedupeKey) {\n const existing = await run(\n stmt()\n .raw(`SELECT id FROM ${NOTIFICATION} WHERE user_id = `)\n .value(row.userId)\n .raw(\" AND dedupe_key = \")\n .value(row.dedupeKey),\n on,\n );\n if (existing.rows.length > 0) {\n deduped.push(row.id);\n continue;\n }\n }\n\n try {\n await run(\n stmt()\n .raw(\n `INSERT INTO ${NOTIFICATION} ` +\n \"(id, user_id, type, payload, actor_id, group_key, dedupe_key, created_at) VALUES (\",\n )\n .list([\n row.id,\n row.userId,\n row.type,\n JSON.stringify(row.payload ?? null),\n row.actorId ?? null,\n row.groupKey ?? null,\n row.dedupeKey ?? null,\n now,\n ])\n .raw(\")\"),\n on,\n );\n } catch (error) {\n if (row.dedupeKey && dialect.isDuplicateKey(error)) {\n deduped.push(row.id);\n continue;\n }\n throw error;\n }\n created.push(row.id);\n }\n\n const createdSet = new Set(created);\n const deliveries = input\n .filter((row) => createdSet.has(row.id))\n .flatMap((row) => row.deliveries.map((delivery) => ({ row, delivery })));\n\n if (deliveries.length > 0) {\n const insert = stmt().raw(\n `INSERT INTO ${DELIVERY} ` +\n \"(id, notification_id, channel, max_attempts, not_before, updated_at) VALUES \",\n );\n deliveries.forEach(({ row, delivery }, index) => {\n if (index > 0) insert.raw(\", \");\n insert\n .raw(\"(\")\n .list([\n delivery.id,\n row.id,\n delivery.channel,\n delivery.maxAttempts,\n delivery.notBefore,\n now,\n ])\n .raw(\")\");\n });\n await run(insert, on);\n }\n\n return { created, deduped };\n });\n },\n\n async claimPendingDeliveries(args: ClaimArgs): Promise<readonly ClaimedDelivery[]> {\n const now = args.now ?? new Date();\n const staleBefore = new Date(now.getTime() - args.leaseMs);\n const strategy = options.transaction\n ? dialect.claim.withTransaction\n : dialect.claim.withoutTransaction;\n\n const claimSet = (statement: Statement) =>\n statement\n .raw(\"status = 'claimed', claimed_at = \")\n .value(now)\n .raw(\", claimed_by = \")\n .value(args.claimToken);\n\n let result: SqlResult;\n\n if (strategy === \"skip-locked\") {\n result = await atomically(async (on) => {\n const pick = stmt().raw(`SELECT id FROM ${DELIVERY} WHERE `);\n eligible(pick, args, now, staleBefore);\n pick\n .raw(\" ORDER BY not_before ASC, id ASC LIMIT \")\n .value(args.limit)\n .raw(\" FOR UPDATE SKIP LOCKED\");\n const ids = (await run(pick, on)).rows.map((row) => str(row.id));\n if (ids.length === 0) return NONE;\n\n const update = stmt().raw(`UPDATE ${DELIVERY} SET `);\n claimSet(update).raw(\" WHERE id IN (\").list(ids).raw(\")\");\n await run(update, on);\n return readClaimed(args.claimToken, on);\n });\n } else {\n const update = stmt();\n if (strategy === \"derived-update\") {\n // The derived table is materialised, which is what lets MySQL update the table it\n // selects from; the outer predicate is re-evaluated on the locked row.\n update.raw(`UPDATE ${DELIVERY} d JOIN (SELECT id FROM ${DELIVERY} WHERE `);\n eligible(update, args, now, staleBefore);\n update\n .raw(\" ORDER BY not_before ASC, id ASC LIMIT \")\n .value(args.limit)\n .raw(\") s ON s.id = d.id SET d.status = 'claimed', d.claimed_at = \")\n .value(now)\n .raw(\", d.claimed_by = \")\n .value(args.claimToken)\n .raw(\" WHERE d.status = 'pending' OR (d.status = 'claimed' AND d.claimed_at < \")\n .value(staleBefore)\n .raw(\")\");\n } else {\n update.raw(`UPDATE ${DELIVERY} SET `);\n claimSet(update).raw(` WHERE id IN (SELECT id FROM ${DELIVERY} WHERE `);\n eligible(update, args, now, staleBefore);\n update.raw(\" ORDER BY not_before ASC, id ASC LIMIT \").value(args.limit).raw(\")\");\n }\n const updated = await retryingLocks(dialect, () => run(update));\n result = updated.affectedRows > 0 ? await readClaimed(args.claimToken, exec) : NONE;\n }\n\n return result.rows.map((row) => ({\n id: str(row.id),\n notificationId: str(row.notification_id),\n channel: str(row.channel) as Channel,\n attempts: num(row.attempts),\n maxAttempts: num(row.max_attempts),\n notification: {\n userId: str(row.user_id),\n type: str(row.type),\n payload: dialect.readJson(row.payload),\n actorId: nullableStr(row.actor_id),\n },\n }));\n },\n\n async releaseDeliveries(releases: readonly DeliveryRelease[]) {\n if (releases.length === 0) return;\n const now = new Date();\n\n // No claimed_by predicate (RFC 0003 §6). `status` before `attempts`: MySQL evaluates SET\n // left to right with updated values, and the CASE needs the old count.\n await atomically(async (on) => {\n for (const { id, outcome, nextAttemptAt } of releases) {\n const result = outcome.result;\n const retryable = outcome.result === \"failed\" && outcome.retryable;\n const error =\n outcome.result === \"failed\"\n ? outcome.error.slice(0, 2000)\n : outcome.result === \"skipped\"\n ? outcome.reason.slice(0, 2000)\n : null;\n\n await run(\n stmt()\n .raw(`UPDATE ${DELIVERY} SET status = CASE WHEN `)\n .value(result)\n .raw(\" = 'sent' THEN 'sent' WHEN \")\n .value(result)\n .raw(\" = 'skipped' THEN 'skipped' WHEN \")\n .value(retryable)\n .raw(\" = 1 AND attempts + 1 < max_attempts THEN 'pending' ELSE 'failed' END\")\n .raw(\", attempts = CASE WHEN \")\n .value(result)\n .raw(\" IN ('sent', 'skipped') THEN attempts ELSE attempts + 1 END\")\n .raw(\", last_error = \")\n .value(error)\n .raw(\", not_before = COALESCE(\")\n .value(nextAttemptAt ?? null)\n .raw(\", not_before), claimed_at = NULL, claimed_by = NULL, updated_at = \")\n .value(now)\n .raw(\" WHERE id = \")\n .value(id),\n on,\n );\n }\n });\n },\n\n async listNotifications(feed: FeedQuery): Promise<FeedPage> {\n const cursor = feed.cursor ? decodeCursor(feed.cursor) : null;\n\n const statement = stmt()\n .raw(`SELECT * FROM ${NOTIFICATION} WHERE user_id = `)\n .value(feed.userId)\n .raw(\" AND archived_at IS NULL\");\n if (feed.unreadOnly) statement.raw(\" AND read_at IS NULL\");\n if (cursor) {\n statement\n .raw(\" AND (created_at, id) < (\")\n .value(cursor.createdAt)\n .raw(\", \")\n .value(cursor.id)\n .raw(\")\");\n }\n statement.raw(\" ORDER BY created_at DESC, id DESC LIMIT \").value(feed.limit + 1);\n\n const { rows } = await run(statement);\n const page = rows.slice(0, feed.limit).map(toNotification);\n const last = page.at(-1);\n\n return {\n notifications: page,\n nextCursor: rows.length > feed.limit && last ? encodeCursor(last.createdAt, last.id) : null,\n };\n },\n\n async countUnseen(userId: string) {\n const { rows } = await run(\n stmt()\n .raw(`SELECT COUNT(*) AS count FROM ${NOTIFICATION} WHERE user_id = `)\n .value(userId)\n .raw(\" AND seen_at IS NULL AND archived_at IS NULL\"),\n );\n return num(rows[0]?.count ?? 0);\n },\n\n async markSeen(userId: string, before: Date) {\n await run(\n stmt()\n .raw(`UPDATE ${NOTIFICATION} SET seen_at = `)\n .value(new Date())\n .raw(\" WHERE user_id = \")\n .value(userId)\n .raw(\" AND seen_at IS NULL AND created_at <= \")\n .value(before),\n );\n },\n\n async markRead(userId: string, notificationIds: readonly string[]) {\n if (notificationIds.length === 0) return 0;\n\n // Idempotent, so the answer is rows matched; MySQL's affectedRows reports rows changed.\n await run(\n stmt()\n .raw(`UPDATE ${NOTIFICATION} SET read_at = COALESCE(read_at, `)\n .value(new Date())\n .raw(\") WHERE user_id = \")\n .value(userId)\n .raw(\" AND id IN (\")\n .list(notificationIds)\n .raw(\")\"),\n );\n const { rows } = await run(\n stmt()\n .raw(`SELECT COUNT(*) AS count FROM ${NOTIFICATION} WHERE user_id = `)\n .value(userId)\n .raw(\" AND id IN (\")\n .list(notificationIds)\n .raw(\")\"),\n );\n return num(rows[0]?.count ?? 0);\n },\n\n async markAllRead(userId: string) {\n const { affectedRows } = await run(\n stmt()\n .raw(`UPDATE ${NOTIFICATION} SET read_at = `)\n .value(new Date())\n .raw(\" WHERE user_id = \")\n .value(userId)\n .raw(\" AND read_at IS NULL\"),\n );\n return affectedRows;\n },\n\n async getFailedDeliveries(args: { since: Date; limit: number }) {\n const { rows } = await run(\n stmt()\n .raw(`SELECT * FROM ${DELIVERY} WHERE status = 'failed' AND updated_at >= `)\n .value(args.since)\n .raw(\" ORDER BY updated_at DESC LIMIT \")\n .value(args.limit),\n );\n return rows.map(toDelivery);\n },\n\n async queryTable(table: string, where: WhereClause, queryOptions: QueryOptions) {\n const statement = stmt().raw(`SELECT * FROM ${q(table)}`);\n appendWhere(statement, where);\n if (queryOptions.orderBy) {\n const direction = queryOptions.orderBy.direction === \"desc\" ? \"DESC\" : \"ASC\";\n statement.raw(` ORDER BY ${q(toSnakeCase(queryOptions.orderBy.field))} ${direction}`);\n }\n if (queryOptions.limit) statement.raw(\" LIMIT \").value(queryOptions.limit);\n return [...(await run(statement)).rows];\n },\n\n async insertRows(\n table: string,\n rows: readonly Record<string, unknown>[],\n onConflict?: readonly string[],\n ) {\n if (rows.length === 0) return 0;\n const columns = Object.keys(rows[0] ?? {});\n if (columns.length === 0) return 0;\n\n const statement = stmt().raw(\n `INSERT INTO ${q(table)} (${columns.map((c) => q(toSnakeCase(c))).join(\", \")}) VALUES `,\n );\n rows.forEach((row, index) => {\n if (index > 0) statement.raw(\", \");\n statement\n .raw(\"(\")\n .list(columns.map((column) => row[column]))\n .raw(\")\");\n });\n\n if (onConflict && onConflict.length > 0) {\n statement.raw(\n dialect.upsertClause(\n onConflict.map((f) => q(toSnakeCase(f))),\n columns.filter((c) => !onConflict.includes(c)).map((c) => q(toSnakeCase(c))),\n ),\n );\n await run(statement);\n // MySQL reports 2 for an updated row; the rows handed in is the honest count.\n return rows.length;\n }\n\n return (await run(statement)).affectedRows;\n },\n\n async updateRows(table: string, where: WhereClause, set: Record<string, unknown>) {\n const assignments = Object.entries(set);\n if (assignments.length === 0) return 0;\n\n const statement = stmt().raw(`UPDATE ${q(table)} SET `);\n assignments.forEach(([field, value], index) => {\n if (index > 0) statement.raw(\", \");\n statement.raw(`${q(toSnakeCase(field))} = `).value(value);\n });\n appendWhere(statement, where);\n return (await run(statement)).affectedRows;\n },\n\n async deleteRows(table: string, where: WhereClause) {\n const statement = stmt().raw(`DELETE FROM ${q(table)}`);\n appendWhere(statement, where);\n return (await run(statement)).affectedRows;\n },\n };\n}\n","import type { Placeholder, Statement } from \"./statement\";\nimport { quoteWith } from \"./statement\";\n\nexport type Row = Record<string, unknown>;\n\nexport type SqlResult = {\n rows: readonly Row[];\n /** Rows an INSERT/UPDATE/DELETE touched; drivers without RETURNING report through this. */\n affectedRows: number;\n};\n\n/** The whole driver contract for the MySQL and SQLite adapters. */\nexport type SqlExec = (text: string, params: readonly unknown[]) => Promise<SqlResult>;\n\n/** How a claim takes its rows. RFC 0005 §3. */\nexport type ClaimStrategy = \"skip-locked\" | \"derived-update\" | \"subquery-update\";\n\nexport type Dialect = {\n name: string;\n placeholder: Placeholder;\n quote: (identifier: string) => string;\n bind: (value: unknown) => unknown;\n readDate: (value: unknown) => Date;\n readNullableDate: (value: unknown) => Date | null;\n readJson: (value: unknown) => unknown;\n /** Appends `column IS DISTINCT FROM value` in the engine's spelling. */\n distinctFrom: (statement: Statement, column: string, value: unknown) => void;\n /** The clause after a multi-row INSERT that makes it an upsert. Columns arrive quoted. */\n upsertClause: (conflict: readonly string[], update: readonly string[]) => string;\n isDuplicateKey: (error: unknown) => boolean;\n /** A deadlock or busy lock the engine asks the caller to retry; the statement was rolled back. */\n isRetryableLock: (error: unknown) => boolean;\n claim: { withTransaction: ClaimStrategy; withoutTransaction: ClaimStrategy };\n};\n\nconst parseUtc = (value: unknown): Date => {\n if (value instanceof Date) return value;\n const text = String(value).trim();\n // \"2026-09-23 10:11:12.345\" from a dateStrings driver carries no zone; it was written as UTC.\n return new Date(/^\\d{4}-\\d{2}-\\d{2} /.test(text) ? `${text.replace(\" \", \"T\")}Z` : text);\n};\n\nconst readJson = (value: unknown) => (typeof value === \"string\" ? JSON.parse(value) : value);\n\nconst bindCommon = (value: unknown) => {\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value === undefined) return null;\n return value;\n};\n\nconst code = (error: unknown) => (error as { code?: unknown } | null)?.code;\nconst errno = (error: unknown) => (error as { errno?: unknown } | null)?.errno;\n\nexport const mysqlDialect: Dialect = {\n name: \"mysql\",\n placeholder: \"question\",\n quote: quoteWith(\"`\"),\n bind: (value) =>\n value instanceof Date ? value.toISOString().slice(0, 23).replace(\"T\", \" \") : bindCommon(value),\n readDate: parseUtc,\n readNullableDate: (value) => (value == null ? null : parseUtc(value)),\n readJson,\n distinctFrom: (statement, column, value) => {\n statement.raw(`NOT (${column} <=> `).value(value).raw(\")\");\n },\n // VALUES() rather than the 8.0.19 `AS new` alias: it also works on MariaDB.\n upsertClause: (conflict, update) =>\n ` ON DUPLICATE KEY UPDATE ${(\n update.length === 0\n ? [`${conflict[0]} = ${conflict[0]}`]\n : update.map((column) => `${column} = VALUES(${column})`)\n ).join(\", \")}`,\n isDuplicateKey: (error) => code(error) === \"ER_DUP_ENTRY\" || errno(error) === 1062,\n isRetryableLock: (error) =>\n code(error) === \"ER_LOCK_DEADLOCK\" ||\n errno(error) === 1213 ||\n code(error) === \"ER_LOCK_WAIT_TIMEOUT\" ||\n errno(error) === 1205,\n claim: { withTransaction: \"skip-locked\", withoutTransaction: \"derived-update\" },\n};\n\nexport const sqliteDialect: Dialect = {\n name: \"sqlite\",\n placeholder: \"question\",\n quote: quoteWith('\"'),\n bind: (value) => (value instanceof Date ? value.toISOString() : bindCommon(value)),\n readDate: parseUtc,\n readNullableDate: (value) => (value == null ? null : parseUtc(value)),\n readJson,\n distinctFrom: (statement, column, value) => {\n statement.raw(`${column} IS NOT `).value(value);\n },\n upsertClause: (conflict, update) =>\n ` ON CONFLICT (${conflict.join(\", \")}) DO ${\n update.length === 0\n ? \"NOTHING\"\n : `UPDATE SET ${update.map((column) => `${column} = excluded.${column}`).join(\", \")}`\n }`,\n isDuplicateKey: (error) =>\n code(error) === \"SQLITE_CONSTRAINT_UNIQUE\" ||\n /UNIQUE constraint failed/i.test(String((error as Error | null)?.message ?? \"\")),\n isRetryableLock: (error) =>\n code(error) === \"SQLITE_BUSY\" ||\n /database is locked/i.test(String((error as Error | null)?.message ?? \"\")),\n claim: { withTransaction: \"subquery-update\", withoutTransaction: \"subquery-update\" },\n};\n","import type { DatabaseAdapter } from \"../../core/adapter\";\nimport { createSqlAdapter, type SqlAdapterOptions } from \"../sql/adapter\";\nimport { type SqlExec, sqliteDialect } from \"../sql/dialect\";\n\nexport type SqliteAdapterOptions = SqlAdapterOptions;\n\n/**\n * SQLite through any driver. One writer at a time, so the claim is a plain\n * UPDATE … WHERE id IN (SELECT … LIMIT ?). Dates are ISO text, booleans 0/1, JSON text. RFC 0005 §3.\n */\nexport function sqliteAdapter(query: SqlExec, options: SqliteAdapterOptions = {}): DatabaseAdapter {\n return createSqlAdapter(sqliteDialect, query, options);\n}\n","import type { FieldDeclaration, SchemaDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\n\nexport const SQLITE_TYPE: Record<FieldDeclaration[\"type\"], string> = {\n string: \"TEXT\",\n number: \"INTEGER\",\n boolean: \"INTEGER\",\n // ISO-8601 with milliseconds and a trailing Z, the same 24 characters\n // `Date#toISOString` writes, so `<=` on the text is `<=` on the instant.\n date: \"TEXT\",\n json: \"TEXT\",\n};\n\nconst quote = (value: string) => `\"${value.split('\"').join('\"\"')}\"`;\n\nconst defaultClause = (spec: FieldDeclaration): string => {\n if (spec.defaultNow) return \" DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))\";\n if (spec.default === undefined) return \"\";\n if (typeof spec.default === \"string\") return ` DEFAULT '${spec.default.replace(/'/g, \"''\")}'`;\n if (typeof spec.default === \"boolean\") return ` DEFAULT ${spec.default ? 1 : 0}`;\n return ` DEFAULT ${spec.default}`;\n};\n\n/** One column's definition, as CREATE TABLE and ALTER TABLE ... ADD COLUMN both need it. */\nexport function sqliteColumnDefinition(field: string, spec: FieldDeclaration): string {\n const nullability = spec.required ? \" NOT NULL\" : \"\";\n return `${quote(toSnakeCase(field))} ${SQLITE_TYPE[spec.type]}${nullability}${defaultClause(spec)}`;\n}\n\n/** SchemaDeclaration to SQLite DDL. Every statement is `IF NOT EXISTS`. */\nexport function renderSqliteDdl(schema: SchemaDeclaration, prefix = \"\"): string[] {\n const statements: string[] = [];\n\n for (const table of Object.values(schema)) {\n const name = quote(prefix + table.tableName);\n\n const columns = Object.entries(table.fields).map(\n ([field, spec]) => ` ${sqliteColumnDefinition(field, spec)}`,\n );\n\n if (table.primaryKey?.length) {\n columns.push(\n ` PRIMARY KEY (${table.primaryKey.map((f) => quote(toSnakeCase(f))).join(\", \")})`,\n );\n }\n\n statements.push(`CREATE TABLE IF NOT EXISTS ${name} (\\n${columns.join(\",\\n\")}\\n)`);\n\n for (const index of table.indexes ?? []) {\n const indexName = quote(\n prefix + (index.name ?? `${table.tableName}_${index.on.join(\"_\")}_idx`),\n );\n const cols = index.on.map((f) => quote(toSnakeCase(f))).join(\", \");\n statements.push(\n `CREATE ${index.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${indexName} ON ${name} (${cols})`,\n );\n }\n }\n\n return statements;\n}\n","import type { SchemaDeclaration } from \"../../core/plugin\";\nimport { coreSchema } from \"../../schema/declaration\";\nimport { renderSqliteDdl } from \"../../schema/render-sqlite\";\nimport type { Row, SqlExec } from \"../sql/dialect\";\n\n/** node:sqlite's DatabaseSync and better-sqlite3's Database, structurally, so neither is a dependency. */\nexport type SqliteDatabaseLike = {\n prepare(sql: string): {\n all(...params: unknown[]): unknown;\n run(...params: unknown[]): { changes: number | bigint };\n };\n exec(sql: string): unknown;\n};\n\nconst returnsRows = (text: string) =>\n /^\\s*(select|with|pragma)\\b/i.test(text) || /\\breturning\\b/i.test(text);\n\n/** The SqlExec for a synchronous SQLite driver. */\nexport const sqliteQuery =\n (db: SqliteDatabaseLike): SqlExec =>\n async (text, params) => {\n const statement = db.prepare(text);\n if (returnsRows(text)) return { rows: statement.all(...params) as Row[], affectedRows: 0 };\n const { changes } = statement.run(...params);\n return { rows: [], affectedRows: Number(changes) };\n };\n\n/**\n * The `transaction` option for a synchronous driver. Queued one behind another: the adapter\n * awaits between statements, and SQLite refuses a BEGIN inside an open transaction.\n */\nexport function sqliteTransaction(db: SqliteDatabaseLike) {\n const exec = sqliteQuery(db);\n let tail: Promise<unknown> = Promise.resolve();\n\n return <T>(fn: (exec: SqlExec) => Promise<T>): Promise<T> => {\n const run = tail.then(async () => {\n db.exec(\"BEGIN\");\n try {\n const result = await fn(exec);\n db.exec(\"COMMIT\");\n return result;\n } catch (error) {\n db.exec(\"ROLLBACK\");\n throw error;\n }\n });\n tail = run.catch(() => undefined);\n return run;\n };\n}\n\nexport type CreateSqliteTablesOptions = {\n prefix?: string;\n plugins?: readonly SchemaDeclaration[];\n};\n\n/** Creates core and plugin tables, IF NOT EXISTS. Bootstrap, not migration. */\nexport async function createSqliteTables(\n query: SqlExec,\n options: CreateSqliteTablesOptions = {},\n): Promise<number> {\n let count = 0;\n for (const schema of [coreSchema, ...(options.plugins ?? [])]) {\n for (const statement of renderSqliteDdl(schema, options.prefix)) {\n await query(statement, []);\n count += 1;\n }\n }\n return count;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/adapters/sqlite/adapter.ts","../../src/adapters/sqlite/helpers.ts"],"names":[],"mappings":";;;;;;;;AAUO,SAAS,aAAA,CAAc,KAAA,EAAgB,OAAA,GAAgC,EAAC,EAAoB;AACjG,EAAA,OAAO,gBAAA,CAAiB,aAAA,EAAe,KAAA,EAAO,OAAO,CAAA;AACvD;;;ACEA,IAAM,WAAA,GAAc,CAAC,IAAA,KACnB,6BAAA,CAA8B,KAAK,IAAI,CAAA,IAAK,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAGjE,IAAM,WAAA,GACX,CAAC,EAAA,KACD,OAAO,MAAM,MAAA,KAAW;AACtB,EAAA,MAAM,SAAA,GAAY,EAAA,CAAG,OAAA,CAAQ,IAAI,CAAA;AACjC,EAAA,IAAI,WAAA,CAAY,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,SAAA,CAAU,GAAA,CAAI,GAAG,MAAM,CAAA,EAAY,YAAA,EAAc,CAAA,EAAE;AACzF,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,SAAA,CAAU,GAAA,CAAI,GAAG,MAAM,CAAA;AAC3C,EAAA,OAAO,EAAE,IAAA,EAAM,IAAI,YAAA,EAAc,MAAA,CAAO,OAAO,CAAA,EAAE;AACnD;AAMK,SAAS,kBAAkB,EAAA,EAAwB;AACxD,EAAA,MAAM,IAAA,GAAO,YAAY,EAAE,CAAA;AAC3B,EAAA,IAAI,IAAA,GAAyB,QAAQ,OAAA,EAAQ;AAE7C,EAAA,OAAO,CAAI,EAAA,KAAkD;AAC3D,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,YAAY;AAChC,MAAA,EAAA,CAAG,KAAK,OAAO,CAAA;AACf,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,IAAI,CAAA;AAC5B,QAAA,EAAA,CAAG,KAAK,QAAQ,CAAA;AAChB,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,EAAA,CAAG,KAAK,UAAU,CAAA;AAClB,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,MAAM,MAAS,CAAA;AAChC,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AACF;AAQA,eAAsB,kBAAA,CACpB,KAAA,EACA,OAAA,GAAqC,EAAC,EACrB;AACjB,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,MAAA,IAAU,CAAC,UAAA,EAAY,GAAI,QAAQ,OAAA,IAAW,EAAG,CAAA,EAAG;AAC7D,IAAA,KAAA,MAAW,SAAA,IAAa,eAAA,CAAgB,MAAA,EAAQ,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC/D,MAAA,MAAM,KAAA,CAAM,SAAA,EAAW,EAAE,CAAA;AACzB,MAAA,KAAA,IAAS,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT","file":"sqlite.js","sourcesContent":["import type { DatabaseAdapter } from \"../../core/adapter\";\nimport { createSqlAdapter, type SqlAdapterOptions } from \"../sql/adapter\";\nimport { type SqlExec, sqliteDialect } from \"../sql/dialect\";\n\nexport type SqliteAdapterOptions = SqlAdapterOptions;\n\n/**\n * SQLite through any driver. One writer at a time, so the claim is a plain\n * UPDATE … WHERE id IN (SELECT … LIMIT ?). Dates are ISO text, booleans 0/1, JSON text. RFC 0005 §3.\n */\nexport function sqliteAdapter(query: SqlExec, options: SqliteAdapterOptions = {}): DatabaseAdapter {\n return createSqlAdapter(sqliteDialect, query, options);\n}\n","import type { SchemaDeclaration } from \"../../core/plugin\";\nimport { coreSchema } from \"../../schema/declaration\";\nimport { renderSqliteDdl } from \"../../schema/render-sqlite\";\nimport type { Row, SqlExec } from \"../sql/dialect\";\n\n/** node:sqlite's DatabaseSync and better-sqlite3's Database, structurally, so neither is a dependency. */\nexport type SqliteDatabaseLike = {\n prepare(sql: string): {\n all(...params: unknown[]): unknown;\n run(...params: unknown[]): { changes: number | bigint };\n };\n exec(sql: string): unknown;\n};\n\nconst returnsRows = (text: string) =>\n /^\\s*(select|with|pragma)\\b/i.test(text) || /\\breturning\\b/i.test(text);\n\n/** The SqlExec for a synchronous SQLite driver. */\nexport const sqliteQuery =\n (db: SqliteDatabaseLike): SqlExec =>\n async (text, params) => {\n const statement = db.prepare(text);\n if (returnsRows(text)) return { rows: statement.all(...params) as Row[], affectedRows: 0 };\n const { changes } = statement.run(...params);\n return { rows: [], affectedRows: Number(changes) };\n };\n\n/**\n * The `transaction` option for a synchronous driver. Queued one behind another: the adapter\n * awaits between statements, and SQLite refuses a BEGIN inside an open transaction.\n */\nexport function sqliteTransaction(db: SqliteDatabaseLike) {\n const exec = sqliteQuery(db);\n let tail: Promise<unknown> = Promise.resolve();\n\n return <T>(fn: (exec: SqlExec) => Promise<T>): Promise<T> => {\n const run = tail.then(async () => {\n db.exec(\"BEGIN\");\n try {\n const result = await fn(exec);\n db.exec(\"COMMIT\");\n return result;\n } catch (error) {\n db.exec(\"ROLLBACK\");\n throw error;\n }\n });\n tail = run.catch(() => undefined);\n return run;\n };\n}\n\nexport type CreateSqliteTablesOptions = {\n prefix?: string;\n plugins?: readonly SchemaDeclaration[];\n};\n\n/** Creates core and plugin tables, IF NOT EXISTS. Bootstrap, not migration. */\nexport async function createSqliteTables(\n query: SqlExec,\n options: CreateSqliteTablesOptions = {},\n): Promise<number> {\n let count = 0;\n for (const schema of [coreSchema, ...(options.plugins ?? [])]) {\n for (const statement of renderSqliteDdl(schema, options.prefix)) {\n await query(statement, []);\n count += 1;\n }\n }\n return count;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/browser/index.ts"],"names":[],"mappings":"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","file":"browser.cjs","sourcesContent":["// Everything here is injectable so it can be tested in Node.\n\nexport type PushSubscriptionPayload = {\n endpoint: string;\n keys: { p256dh: string; auth: string };\n};\n\nexport type SubscribeOptions = {\n /** VAPID public key, base64url — the same one the server signs with. */\n publicKey: string;\n baseUrl?: string;\n serviceWorkerPath?: string;\n scope?: string;\n fetch?: typeof globalThis.fetch;\n /** Pre-resolved registration, so tests need no service worker. */\n registration?: ServiceWorkerRegistration;\n};\n\nexport class PushUnsupportedError extends Error {\n constructor(reason: string) {\n super(`web push is unavailable: ${reason}`);\n this.name = \"PushUnsupportedError\";\n }\n}\n\nexport class PushPermissionError extends Error {\n constructor(readonly permission: NotificationPermission) {\n super(`notification permission was ${permission}`);\n this.name = \"PushPermissionError\";\n }\n}\n\nexport function isPushSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n typeof PushManager !== \"undefined\" &&\n typeof Notification !== \"undefined\"\n );\n}\n\n/** applicationServerKey must be raw bytes, not the base64url string. */\nexport function decodeVapidKey(publicKey: string): Uint8Array<ArrayBuffer> {\n const padded = publicKey.padEnd(publicKey.length + ((4 - (publicKey.length % 4)) % 4), \"=\");\n\n let binary: string;\n try {\n binary = atob(padded.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n } catch {\n throw new Error(\"VAPID publicKey is not valid base64url\");\n }\n\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n if (bytes.length !== 65 || bytes[0] !== 0x04) {\n throw new Error(\n `VAPID publicKey must be a 65-byte uncompressed EC point, got ${bytes.length} bytes`,\n );\n }\n return bytes;\n}\n\nasync function resolveRegistration(options: SubscribeOptions): Promise<ServiceWorkerRegistration> {\n if (options.registration) return options.registration;\n if (!isPushSupported()) throw new PushUnsupportedError(\"this browser has no PushManager\");\n\n const path = options.serviceWorkerPath ?? \"/sw.js\";\n const registration = await navigator.serviceWorker.register(\n path,\n options.scope ? { scope: options.scope } : undefined,\n );\n\n // subscribe() before the worker is active rejects.\n await navigator.serviceWorker.ready;\n return registration;\n}\n\n/** Registers the worker, asks permission, subscribes, and registers the subscription with the server. */\nexport async function subscribeToPush(options: SubscribeOptions): Promise<PushSubscriptionPayload> {\n const registration = await resolveRegistration(options);\n\n if (typeof Notification !== \"undefined\") {\n const permission =\n Notification.permission === \"default\"\n ? await Notification.requestPermission()\n : Notification.permission;\n\n if (permission !== \"granted\") throw new PushPermissionError(permission);\n }\n\n const existing = await registration.pushManager.getSubscription();\n const subscription =\n existing ??\n (await registration.pushManager.subscribe({\n // Required by Chrome; a silent push is rejected outright.\n userVisibleOnly: true,\n applicationServerKey: decodeVapidKey(options.publicKey),\n }));\n\n const payload = subscription.toJSON() as PushSubscriptionPayload;\n const doFetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"/api/notifications\").replace(/\\/$/, \"\");\n\n const response = await doFetch(`${baseUrl}/push/devices`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n credentials: \"same-origin\",\n body: JSON.stringify({ endpoint: payload.endpoint, keys: payload.keys }),\n });\n\n if (!response.ok) {\n throw new Error(`registering the push device failed: ${response.status}`);\n }\n\n return payload;\n}\n\n/** Tells the server first: a browser-only unsubscribe leaves a dead row behind. */\nexport async function unsubscribeFromPush(\n options: Omit<SubscribeOptions, \"publicKey\">,\n): Promise<boolean> {\n const registration = await resolveRegistration({ ...options, publicKey: \"\" });\n const subscription = await registration.pushManager.getSubscription();\n if (!subscription) return false;\n\n const doFetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"/api/notifications\").replace(/\\/$/, \"\");\n\n await doFetch(`${baseUrl}/push/devices/remove`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n credentials: \"same-origin\",\n body: JSON.stringify({ endpoint: subscription.endpoint }),\n }).catch(() => undefined);\n\n return subscription.unsubscribe();\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/browser/index.ts"],"names":[],"mappings":"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","file":"browser.js","sourcesContent":["// Everything here is injectable so it can be tested in Node.\n\nexport type PushSubscriptionPayload = {\n endpoint: string;\n keys: { p256dh: string; auth: string };\n};\n\nexport type SubscribeOptions = {\n /** VAPID public key, base64url — the same one the server signs with. */\n publicKey: string;\n baseUrl?: string;\n serviceWorkerPath?: string;\n scope?: string;\n fetch?: typeof globalThis.fetch;\n /** Pre-resolved registration, so tests need no service worker. */\n registration?: ServiceWorkerRegistration;\n};\n\nexport class PushUnsupportedError extends Error {\n constructor(reason: string) {\n super(`web push is unavailable: ${reason}`);\n this.name = \"PushUnsupportedError\";\n }\n}\n\nexport class PushPermissionError extends Error {\n constructor(readonly permission: NotificationPermission) {\n super(`notification permission was ${permission}`);\n this.name = \"PushPermissionError\";\n }\n}\n\nexport function isPushSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n typeof PushManager !== \"undefined\" &&\n typeof Notification !== \"undefined\"\n );\n}\n\n/** applicationServerKey must be raw bytes, not the base64url string. */\nexport function decodeVapidKey(publicKey: string): Uint8Array<ArrayBuffer> {\n const padded = publicKey.padEnd(publicKey.length + ((4 - (publicKey.length % 4)) % 4), \"=\");\n\n let binary: string;\n try {\n binary = atob(padded.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n } catch {\n throw new Error(\"VAPID publicKey is not valid base64url\");\n }\n\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n if (bytes.length !== 65 || bytes[0] !== 0x04) {\n throw new Error(\n `VAPID publicKey must be a 65-byte uncompressed EC point, got ${bytes.length} bytes`,\n );\n }\n return bytes;\n}\n\nasync function resolveRegistration(options: SubscribeOptions): Promise<ServiceWorkerRegistration> {\n if (options.registration) return options.registration;\n if (!isPushSupported()) throw new PushUnsupportedError(\"this browser has no PushManager\");\n\n const path = options.serviceWorkerPath ?? \"/sw.js\";\n const registration = await navigator.serviceWorker.register(\n path,\n options.scope ? { scope: options.scope } : undefined,\n );\n\n // subscribe() before the worker is active rejects.\n await navigator.serviceWorker.ready;\n return registration;\n}\n\n/** Registers the worker, asks permission, subscribes, and registers the subscription with the server. */\nexport async function subscribeToPush(options: SubscribeOptions): Promise<PushSubscriptionPayload> {\n const registration = await resolveRegistration(options);\n\n if (typeof Notification !== \"undefined\") {\n const permission =\n Notification.permission === \"default\"\n ? await Notification.requestPermission()\n : Notification.permission;\n\n if (permission !== \"granted\") throw new PushPermissionError(permission);\n }\n\n const existing = await registration.pushManager.getSubscription();\n const subscription =\n existing ??\n (await registration.pushManager.subscribe({\n // Required by Chrome; a silent push is rejected outright.\n userVisibleOnly: true,\n applicationServerKey: decodeVapidKey(options.publicKey),\n }));\n\n const payload = subscription.toJSON() as PushSubscriptionPayload;\n const doFetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"/api/notifications\").replace(/\\/$/, \"\");\n\n const response = await doFetch(`${baseUrl}/push/devices`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n credentials: \"same-origin\",\n body: JSON.stringify({ endpoint: payload.endpoint, keys: payload.keys }),\n });\n\n if (!response.ok) {\n throw new Error(`registering the push device failed: ${response.status}`);\n }\n\n return payload;\n}\n\n/** Tells the server first: a browser-only unsubscribe leaves a dead row behind. */\nexport async function unsubscribeFromPush(\n options: Omit<SubscribeOptions, \"publicKey\">,\n): Promise<boolean> {\n const registration = await resolveRegistration({ ...options, publicKey: \"\" });\n const subscription = await registration.pushManager.getSubscription();\n if (!subscription) return false;\n\n const doFetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"/api/notifications\").replace(/\\/$/, \"\");\n\n await doFetch(`${baseUrl}/push/devices/remove`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n credentials: \"same-origin\",\n body: JSON.stringify({ endpoint: subscription.endpoint }),\n }).catch(() => undefined);\n\n return subscription.unsubscribe();\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/migrate-mysql.ts","../src/schema/render-sql.ts","../src/schema/migrate-sql.ts","../src/schema/migrate-sqlite.ts","../src/schema/render-drizzle.ts"],"names":["quote","indexName","columns","SQL_TYPE","LIVE_TYPE","defaultClause"],"mappings":"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","file":"chunk-A4HX5YTG.js","sourcesContent":["import type { SqlExec } from \"../adapters/sql/dialect\";\nimport type { FieldDeclaration, SchemaDeclaration, TableDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\nimport type { MigrationPlan } from \"./migrate-sql\";\nimport { mysqlColumnDefinition, renderMysqlDdl } from \"./render-mysql\";\n\n/** Columns of every table in the connection's current database. */\nexport const MYSQL_INTROSPECT_COLUMNS_SQL = `\n SELECT TABLE_NAME AS table_name, COLUMN_NAME AS column_name, DATA_TYPE AS data_type\n FROM information_schema.COLUMNS\n WHERE TABLE_SCHEMA = DATABASE()\n`;\n\n/** Index names, because MySQL has no CREATE INDEX IF NOT EXISTS. */\nexport const MYSQL_INTROSPECT_INDEXES_SQL = `\n SELECT DISTINCT TABLE_NAME AS table_name, INDEX_NAME AS index_name\n FROM information_schema.STATISTICS\n WHERE TABLE_SCHEMA = DATABASE()\n`;\n\n/** What information_schema reports for each declared type. MariaDB reports JSON as longtext. */\nconst LIVE_TYPE: Record<FieldDeclaration[\"type\"], readonly string[]> = {\n string: [\"varchar\", \"char\", \"text\", \"tinytext\", \"mediumtext\", \"longtext\"],\n number: [\"int\", \"integer\", \"bigint\", \"smallint\", \"mediumint\", \"tinyint\"],\n boolean: [\"tinyint\", \"bit\", \"boolean\"],\n date: [\"datetime\", \"timestamp\"],\n json: [\"json\", \"longtext\"],\n};\n\nconst quote = (value: string) => `\\`${value.split(\"`\").join(\"``\")}\\``;\n\nconst indexName = (\n table: TableDeclaration,\n declaration: { on: readonly string[]; name?: string },\n) => declaration.name ?? `${table.tableName}_${declaration.on.join(\"_\")}_idx`;\n\nconst lower = (value: unknown) => String(value).toLowerCase();\n\n/**\n * Diffs a live MySQL/MariaDB database against a declaration and emits only what\n * is missing: tables, columns, indexes. Additive only; anything that would need\n * a type change or a drop lands in `unsupported` for a human.\n */\nexport async function planMysqlMigration(\n query: SqlExec,\n schema: SchemaDeclaration,\n prefix = \"\",\n): Promise<MigrationPlan> {\n const [columnRows, indexRows] = await Promise.all([\n query(MYSQL_INTROSPECT_COLUMNS_SQL, []),\n query(MYSQL_INTROSPECT_INDEXES_SQL, []),\n ]);\n\n const columns = new Map<string, Map<string, string>>();\n for (const row of columnRows.rows) {\n const table = lower(row.table_name ?? row.TABLE_NAME);\n const byColumn = columns.get(table) ?? new Map<string, string>();\n byColumn.set(lower(row.column_name ?? row.COLUMN_NAME), lower(row.data_type ?? row.DATA_TYPE));\n columns.set(table, byColumn);\n }\n const indexes = new Set(\n indexRows.rows.map(\n (row) =>\n `${lower(row.table_name ?? row.TABLE_NAME)}.${lower(row.index_name ?? row.INDEX_NAME)}`,\n ),\n );\n\n const statements: string[] = [];\n const unsupported: string[] = [];\n const createdTables: string[] = [];\n\n for (const table of Object.values(schema)) {\n const qualified = prefix + table.tableName;\n const existing = columns.get(qualified.toLowerCase());\n\n if (!existing || existing.size === 0) {\n createdTables.push(qualified);\n statements.push(...renderMysqlDdl({ [table.tableName]: table }, prefix));\n continue;\n }\n\n for (const [field, spec] of Object.entries(table.fields)) {\n const column = toSnakeCase(field);\n const found = existing.get(column.toLowerCase());\n\n if (found === undefined) {\n const canFill = spec.defaultNow || spec.default !== undefined;\n const definition = mysqlColumnDefinition(field, table, {\n ...spec,\n // A required column with nothing to fill existing rows with is added nullable.\n required: Boolean(spec.required && canFill),\n });\n statements.push(`ALTER TABLE ${quote(qualified)} ADD COLUMN ${definition}`);\n if (spec.required && !canFill) {\n unsupported.push(\n `${qualified}.${column} is declared required but has no default; it was added ` +\n \"nullable. Backfill it, then ALTER TABLE ... MODIFY ... NOT NULL yourself.\",\n );\n }\n continue;\n }\n\n if (!LIVE_TYPE[spec.type].includes(found)) {\n unsupported.push(\n `${qualified}.${column} is ${found} but ${spec.type} is declared. ` +\n \"Changing a column type can lose data — do it yourself.\",\n );\n }\n }\n\n for (const declaration of table.indexes ?? []) {\n const name = prefix + indexName(table, declaration);\n if (indexes.has(`${qualified.toLowerCase()}.${name.toLowerCase()}`)) continue;\n\n const textColumn = declaration.on.find((field) => {\n const live = existing.get(toSnakeCase(field).toLowerCase());\n return live?.endsWith(\"text\") ?? false;\n });\n if (textColumn) {\n unsupported.push(\n `${qualified}: index ${name} needs ${toSnakeCase(textColumn)} as VARCHAR, but it is TEXT, ` +\n \"which MySQL cannot index without a prefix length. Change the column type, then rerun.\",\n );\n continue;\n }\n\n const cols = declaration.on.map((field) => quote(toSnakeCase(field))).join(\", \");\n statements.push(\n `CREATE ${declaration.unique ? \"UNIQUE \" : \"\"}INDEX ${quote(name)} ON ${quote(qualified)} (${cols})`,\n );\n }\n\n for (const column of existing.keys()) {\n const declared = Object.keys(table.fields).some(\n (field) => toSnakeCase(field).toLowerCase() === column,\n );\n if (!declared) {\n unsupported.push(\n `${qualified}.${column} exists but is not declared. Left alone — ` +\n \"drop it yourself if it is ours and no longer needed.\",\n );\n }\n }\n }\n\n return { statements, unsupported, createdTables };\n}\n","import type { FieldDeclaration, SchemaDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\n\nconst SQL_TYPE: Record<FieldDeclaration[\"type\"], string> = {\n string: \"text\",\n number: \"integer\",\n boolean: \"boolean\",\n date: \"timestamptz\",\n json: \"jsonb\",\n};\n\nconst quote = (value: string) => `\"${value.replace(/\"/g, '\"\"')}\"`;\n\nconst defaultClause = (field: FieldDeclaration): string => {\n if (field.defaultNow) return \" DEFAULT now()\";\n if (field.default === undefined) return \"\";\n if (typeof field.default === \"string\") return ` DEFAULT '${field.default.replace(/'/g, \"''\")}'`;\n return ` DEFAULT ${field.default}`;\n};\n\n/** SchemaDeclaration to Postgres DDL, from the same source as the Drizzle renderer. */\nexport function renderPostgresDdl(schema: SchemaDeclaration, prefix = \"\"): string[] {\n const statements: string[] = [];\n\n for (const table of Object.values(schema)) {\n const name = quote(prefix + table.tableName);\n\n const columns = Object.entries(table.fields).map(([field, spec]) => {\n const nullability = spec.required ? \" NOT NULL\" : \"\";\n return ` ${quote(toSnakeCase(field))} ${SQL_TYPE[spec.type]}${nullability}${defaultClause(spec)}`;\n });\n\n if (table.primaryKey?.length) {\n const key = table.primaryKey.map((field) => quote(toSnakeCase(field))).join(\", \");\n columns.push(` PRIMARY KEY (${key})`);\n }\n\n statements.push(`CREATE TABLE IF NOT EXISTS ${name} (\\n${columns.join(\",\\n\")}\\n)`);\n\n for (const declaration of table.indexes ?? []) {\n const indexName = quote(\n prefix + (declaration.name ?? `${table.tableName}_${declaration.on.join(\"_\")}_idx`),\n );\n const columns = declaration.on.map((field) => quote(toSnakeCase(field))).join(\", \");\n const unique = declaration.unique ? \"UNIQUE \" : \"\";\n statements.push(`CREATE ${unique}INDEX IF NOT EXISTS ${indexName} ON ${name} (${columns})`);\n }\n }\n\n return statements;\n}\n","import type { FieldDeclaration, SchemaDeclaration, TableDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\nimport { renderPostgresDdl } from \"./render-sql\";\n\n/** Introspects a live Postgres schema and emits only what is missing. Additive only: drops and type changes land in `unsupported`. */\n\nconst SQL_TYPE: Record<FieldDeclaration[\"type\"], string> = {\n string: \"text\",\n number: \"integer\",\n boolean: \"boolean\",\n date: \"timestamptz\",\n json: \"jsonb\",\n};\n\n/** What information_schema reports for each of our declared types. */\nconst LIVE_TYPE: Record<FieldDeclaration[\"type\"], readonly string[]> = {\n string: [\"text\", \"character varying\", \"character\"],\n number: [\"integer\", \"bigint\", \"smallint\"],\n boolean: [\"boolean\"],\n date: [\"timestamp with time zone\", \"timestamp without time zone\"],\n json: [\"jsonb\", \"json\"],\n};\n\nconst quote = (value: string) => `\"${value.replace(/\"/g, '\"\"')}\"`;\n\nconst defaultClause = (field: FieldDeclaration): string => {\n if (field.defaultNow) return \" DEFAULT now()\";\n if (field.default === undefined) return \"\";\n if (typeof field.default === \"string\") return ` DEFAULT '${field.default.replace(/'/g, \"''\")}'`;\n return ` DEFAULT ${field.default}`;\n};\n\nconst indexName = (\n table: TableDeclaration,\n declaration: { on: readonly string[]; name?: string },\n) => declaration.name ?? `${table.tableName}_${declaration.on.join(\"_\")}_idx`;\n\nexport type LiveColumn = { table: string; column: string; type: string; nullable: boolean };\n\n/** A row as INTROSPECT_SQL returns it; `LiveColumn` uses the short forms and both are accepted. */\nexport type LiveColumnRow =\n | LiveColumn\n | {\n table_name: string;\n column_name: string;\n data_type: string;\n is_nullable: string | boolean;\n };\n\n/** Accepts either shape, so raw rows and hand-mapped rows both work. */\nfunction normaliseColumn(row: LiveColumnRow): LiveColumn {\n if (\"table\" in row) return row;\n return {\n table: String(row.table_name),\n column: String(row.column_name),\n type: String(row.data_type),\n nullable: typeof row.is_nullable === \"boolean\" ? row.is_nullable : row.is_nullable === \"YES\",\n };\n}\n\nexport type MigrationPlan = {\n /** Run in order. Empty means the live schema already matches. */\n statements: readonly string[];\n /** Differences this cannot express safely. Read them; they need a human. */\n unsupported: readonly string[];\n /** Tables that do not exist yet — these get a full CREATE TABLE. */\n createdTables: readonly string[];\n requiresTransaction?: boolean;\n};\n\n/** Reads the live column list; a function, so this module stays driver-agnostic. */\nexport type Introspector = () => Promise<readonly LiveColumnRow[]>;\n\n/** The query an Introspector should run; raw rows are accepted as they come back. */\nexport const INTROSPECT_SQL = `\n SELECT table_name, column_name, data_type, is_nullable\n FROM information_schema.columns\n WHERE table_schema = current_schema()\n`;\n\nexport async function planPostgresMigration(\n introspect: Introspector,\n schema: SchemaDeclaration,\n prefix = \"\",\n): Promise<MigrationPlan> {\n const live = await introspect();\n\n const byTable = new Map<string, Map<string, LiveColumn>>();\n for (const row of live) {\n const column = normaliseColumn(row);\n const columns = byTable.get(column.table) ?? new Map<string, LiveColumn>();\n columns.set(column.column, column);\n byTable.set(column.table, columns);\n }\n\n const statements: string[] = [];\n const unsupported: string[] = [];\n const createdTables: string[] = [];\n\n for (const table of Object.values(schema)) {\n const qualified = prefix + table.tableName;\n const existing = byTable.get(qualified);\n\n // Absent entirely: the ordinary bootstrap path still applies.\n if (!existing || existing.size === 0) {\n createdTables.push(qualified);\n statements.push(...renderPostgresDdl({ [table.tableName]: table }, prefix));\n continue;\n }\n\n for (const [field, spec] of Object.entries(table.fields)) {\n const column = toSnakeCase(field);\n const found = existing.get(column);\n\n if (!found) {\n // NOT NULL fails on a populated table without a default: added nullable and flagged.\n const canFill = spec.defaultNow || spec.default !== undefined;\n const nullability = spec.required && canFill ? \" NOT NULL\" : \"\";\n\n statements.push(\n `ALTER TABLE ${quote(qualified)} ADD COLUMN IF NOT EXISTS ` +\n `${quote(column)} ${SQL_TYPE[spec.type]}${nullability}${defaultClause(spec)}`,\n );\n\n if (spec.required && !canFill) {\n unsupported.push(\n `${qualified}.${column} is declared required but has no default; ` +\n \"it was added nullable. Backfill it, then ALTER ... SET NOT NULL yourself.\",\n );\n }\n continue;\n }\n\n if (!LIVE_TYPE[spec.type].includes(found.type)) {\n unsupported.push(\n `${qualified}.${column} is ${found.type} but ${spec.type} is declared ` +\n `(${SQL_TYPE[spec.type]}). Changing a column type can lose data — do it yourself.`,\n );\n }\n }\n\n // Indexes are cheap and idempotent, so they are re-issued unconditionally.\n for (const declaration of table.indexes ?? []) {\n const name = quote(prefix + indexName(table, declaration));\n const columns = declaration.on.map((field) => quote(toSnakeCase(field))).join(\", \");\n statements.push(\n `CREATE ${declaration.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${name} ` +\n `ON ${quote(qualified)} (${columns})`,\n );\n }\n\n for (const column of existing.keys()) {\n const declared = Object.keys(table.fields).some((field) => toSnakeCase(field) === column);\n if (!declared) {\n unsupported.push(\n `${qualified}.${column} exists but is not declared. Left alone — ` +\n \"drop it yourself if it is ours and no longer needed.\",\n );\n }\n }\n }\n\n return { statements, unsupported, createdTables };\n}\n","import type { SqlExec } from \"../adapters/sql/dialect\";\nimport type { SchemaDeclaration, TableDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\nimport type { MigrationPlan } from \"./migrate-sql\";\nimport { renderSqliteDdl, SQLITE_TYPE, sqliteColumnDefinition } from \"./render-sqlite\";\n\n/** Every column of every table. pragma_table_info needs SQLite 3.16+; node:sqlite and better-sqlite3 ship newer. */\nexport const SQLITE_INTROSPECT_SQL = `\n SELECT m.name AS table_name, p.name AS column_name, p.type AS data_type\n FROM sqlite_master AS m\n JOIN pragma_table_info(m.name) AS p\n WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%'\n`;\n\nconst quote = (value: string) => `\"${value.split('\"').join('\"\"')}\"`;\n\nconst REBUILD_SUFFIX = \"__easy_ping_rebuild\";\n\n/**\n * Diffs a live SQLite database against a declaration and emits only what is\n * missing. Run the statements inside one transaction.\n *\n * SQLite cannot ALTER TABLE ... ADD COLUMN with a non-constant default, which\n * every timestamp column has, so a table missing such a column is rebuilt: a\n * copy with the new shape, the rows moved across, the copy swapped in, the\n * indexes recreated. Everything else is a plain ADD COLUMN.\n */\nexport async function planSqliteMigration(\n query: SqlExec,\n schema: SchemaDeclaration,\n prefix = \"\",\n): Promise<MigrationPlan> {\n const { rows } = await query(SQLITE_INTROSPECT_SQL, []);\n\n const live = new Map<string, Map<string, string>>();\n for (const row of rows) {\n const table = String(row.table_name);\n const columns = live.get(table) ?? new Map<string, string>();\n columns.set(String(row.column_name), String(row.data_type).toUpperCase());\n live.set(table, columns);\n }\n\n const statements: string[] = [];\n const unsupported: string[] = [];\n const createdTables: string[] = [];\n let requiresTransaction = false;\n\n for (const table of Object.values(schema)) {\n const qualified = prefix + table.tableName;\n const existing = live.get(qualified);\n\n if (!existing || existing.size === 0) {\n createdTables.push(qualified);\n statements.push(...renderSqliteDdl({ [table.tableName]: table }, prefix));\n continue;\n }\n\n const missing = Object.entries(table.fields).filter(\n ([field]) => !existing.has(toSnakeCase(field)),\n );\n\n // Nothing can fill a required column with no default on existing rows: it goes in nullable.\n const relaxed: TableDeclaration = {\n ...table,\n fields: Object.fromEntries(\n Object.entries(table.fields).map(([field, spec]) => {\n const unfillable =\n !existing.has(toSnakeCase(field)) &&\n spec.required &&\n !spec.defaultNow &&\n spec.default === undefined;\n if (unfillable) {\n unsupported.push(\n `${qualified}.${toSnakeCase(field)} is declared required but has no default; it was ` +\n \"added nullable. Backfill it; SQLite cannot add NOT NULL afterwards without a rebuild.\",\n );\n }\n return [field, unfillable ? { ...spec, required: false } : spec];\n }),\n ),\n };\n\n if (missing.some(([, spec]) => spec.defaultNow)) {\n requiresTransaction = true;\n statements.push(...rebuild(relaxed, prefix, existing));\n } else {\n for (const [field] of missing) {\n const spec = relaxed.fields[field];\n if (!spec) continue;\n statements.push(\n `ALTER TABLE ${quote(qualified)} ADD COLUMN ${sqliteColumnDefinition(field, spec)}`,\n );\n }\n // CREATE INDEX IF NOT EXISTS makes re-issuing every index safe.\n statements.push(...renderSqliteDdl({ [table.tableName]: table }, prefix).slice(1));\n }\n\n for (const [field, spec] of Object.entries(table.fields)) {\n const found = existing.get(toSnakeCase(field));\n if (found !== undefined && found !== SQLITE_TYPE[spec.type]) {\n unsupported.push(\n `${qualified}.${toSnakeCase(field)} is ${found || \"untyped\"} but ${SQLITE_TYPE[spec.type]} ` +\n \"is declared. Changing a column type needs a table rebuild — do it yourself.\",\n );\n }\n }\n\n for (const column of existing.keys()) {\n const declared = Object.keys(table.fields).some((field) => toSnakeCase(field) === column);\n if (!declared) {\n unsupported.push(\n `${qualified}.${column} exists but is not declared. Left alone — ` +\n \"drop it yourself if it is ours and no longer needed.\",\n );\n }\n }\n }\n\n return requiresTransaction\n ? { statements, unsupported, createdTables, requiresTransaction }\n : { statements, unsupported, createdTables };\n}\n\n/** The documented SQLite way to change a table's shape: new table, copy, drop, rename, reindex. */\nfunction rebuild(table: TableDeclaration, prefix: string, existing: Map<string, string>): string[] {\n const qualified = prefix + table.tableName;\n const temp = qualified + REBUILD_SUFFIX;\n\n // Only the CREATE TABLE: its indexes are created after the swap, under their real names.\n const [createTemp = \"\"] = renderSqliteDdl(\n { [table.tableName]: { ...table, tableName: table.tableName + REBUILD_SUFFIX, indexes: [] } },\n prefix,\n );\n const shared = Object.keys(table.fields)\n .map(toSnakeCase)\n .filter((column) => existing.has(column))\n .map(quote)\n .join(\", \");\n\n return [\n `DROP TABLE IF EXISTS ${quote(temp)}`,\n createTemp,\n `INSERT INTO ${quote(temp)} (${shared}) SELECT ${shared} FROM ${quote(qualified)}`,\n `DROP TABLE ${quote(qualified)}`,\n `ALTER TABLE ${quote(temp)} RENAME TO ${quote(qualified)}`,\n ...renderSqliteDdl({ [table.tableName]: table }, prefix).slice(1),\n ];\n}\n","import type { FieldDeclaration, SchemaDeclaration, TableDeclaration } from \"../core/plugin\";\nimport { toSnakeCase } from \"./declaration\";\n\nconst COLUMN_BUILDER: Record<FieldDeclaration[\"type\"], string> = {\n string: \"text\",\n number: \"integer\",\n boolean: \"boolean\",\n date: \"timestamp\",\n json: \"jsonb\",\n};\n\nconst literal = (value: string | number | boolean) =>\n typeof value === \"string\" ? JSON.stringify(value) : String(value);\n\nfunction renderColumn(name: string, field: FieldDeclaration, isSinglePk: boolean): string {\n const builder = COLUMN_BUILDER[field.type];\n const column = toSnakeCase(name);\n\n let expression =\n field.type === \"date\"\n ? `${builder}(${JSON.stringify(column)}, { withTimezone: true })`\n : `${builder}(${JSON.stringify(column)})`;\n\n if (isSinglePk) return ` ${name}: ${expression}.primaryKey(),`;\n\n if (field.required) expression += \".notNull()\";\n if (field.defaultNow) expression += \".defaultNow()\";\n else if (field.default !== undefined) expression += `.default(${literal(field.default)})`;\n\n return ` ${name}: ${expression},`;\n}\n\nfunction renderTable(key: string, table: TableDeclaration, prefix: string): string {\n const compositePk = (table.primaryKey?.length ?? 0) > 1;\n const singlePk = !compositePk ? table.primaryKey?.[0] : undefined;\n\n const columns = Object.entries(table.fields)\n .map(([name, field]) => renderColumn(name, field, name === singlePk))\n .join(\"\\n\");\n\n const extras: string[] = [];\n\n for (const declaration of table.indexes ?? []) {\n const builder = declaration.unique ? \"uniqueIndex\" : \"index\";\n const name = declaration.name ?? `${table.tableName}_${declaration.on.join(\"_\")}_idx`;\n const columns = declaration.on.map((field) => `table.${field}`).join(\", \");\n extras.push(` ${builder}(${JSON.stringify(prefix + name)}).on(${columns}),`);\n }\n\n if (compositePk) {\n const columns = (table.primaryKey ?? []).map((field) => `table.${field}`).join(\", \");\n extras.push(` primaryKey({ columns: [${columns}] }),`);\n }\n\n const third = extras.length ? `,\\n (table) => [\\n${extras.join(\"\\n\")}\\n ]` : \"\";\n\n return `export const ${key} = pgTable(\\n ${JSON.stringify(prefix + table.tableName)},\\n {\\n${columns}\\n }${third},\\n);`;\n}\n\n/** Renders a SchemaDeclaration to Drizzle pg-core source. */\nexport function renderDrizzleSchema(schema: SchemaDeclaration, prefix = \"\"): string {\n const tables = Object.entries(schema);\n\n const used = new Set<string>([\"pgTable\"]);\n for (const [, table] of tables) {\n for (const field of Object.values(table.fields)) used.add(COLUMN_BUILDER[field.type]);\n for (const declaration of table.indexes ?? []) {\n used.add(declaration.unique ? \"uniqueIndex\" : \"index\");\n }\n if ((table.primaryKey?.length ?? 0) > 1) used.add(\"primaryKey\");\n }\n\n const imports = [...used].sort().join(\", \");\n const body = tables.map(([key, table]) => renderTable(key, table, prefix)).join(\"\\n\\n\");\n\n return `// Generated by easy-ping. Do not edit by hand.\\nimport { ${imports} } from \"drizzle-orm/pg-core\";\\n\\n${body}\\n`;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/declaration.ts"],"names":[],"mappings":"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","file":"chunk-AEYYTE5I.js","sourcesContent":["import type { SchemaDeclaration } from \"../core/plugin\";\n\nexport const toSnakeCase = (value: string) => value.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n\n/** Core tables in the plugin format. A drift test asserts it agrees with the Drizzle schema. */\nexport const coreSchema = {\n notification: {\n tableName: \"notification\",\n fields: {\n id: { type: \"string\", required: true },\n userId: { type: \"string\", required: true },\n type: { type: \"string\", required: true },\n payload: { type: \"json\", required: true },\n actorId: { type: \"string\" },\n groupKey: { type: \"string\" },\n dedupeKey: { type: \"string\" },\n seenAt: { type: \"date\" },\n readAt: { type: \"date\" },\n archivedAt: { type: \"date\" },\n createdAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"id\"],\n indexes: [\n { on: [\"userId\", \"createdAt\"], name: \"notification_feed_idx\" },\n { on: [\"userId\", \"groupKey\"], name: \"notification_group_idx\" },\n { on: [\"userId\", \"dedupeKey\"], unique: true, name: \"notification_dedupe_idx\" },\n ],\n },\n\n notificationDelivery: {\n tableName: \"notification_delivery\",\n fields: {\n id: { type: \"string\", required: true },\n notificationId: { type: \"string\", required: true },\n channel: { type: \"string\", required: true },\n status: { type: \"string\", required: true, default: \"pending\" },\n attempts: { type: \"number\", required: true, default: 0 },\n maxAttempts: { type: \"number\", required: true, default: 5 },\n notBefore: { type: \"date\", required: true, defaultNow: true },\n claimedAt: { type: \"date\" },\n claimedBy: { type: \"string\" },\n lastError: { type: \"string\" },\n updatedAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"id\"],\n indexes: [\n { on: [\"status\", \"notBefore\"], name: \"delivery_claim_idx\" },\n { on: [\"notificationId\"], name: \"delivery_notification_idx\" },\n ],\n },\n\n notificationPreference: {\n tableName: \"notification_preference\",\n fields: {\n userId: { type: \"string\", required: true },\n type: { type: \"string\", required: true },\n channel: { type: \"string\", required: true },\n enabled: { type: \"boolean\", required: true, default: true },\n frequency: { type: \"string\", required: true, default: \"instant\" },\n updatedAt: { type: \"date\", required: true, defaultNow: true },\n },\n primaryKey: [\"userId\", \"type\", \"channel\"],\n },\n} satisfies SchemaDeclaration;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/tokens.ts","../src/core/handler.ts"],"names":["encoder","route"],"mappings":"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","file":"chunk-CFLVAF2R.js","sourcesContent":["import { decodeBase64Url, decodeBase64UrlBytes, encodeBase64Url } from \"./base64url\";\n\nexport type TokenClaims = {\n /** Subject — the user the token acts for. */\n uid: string;\n /** What the token is allowed to do. Verification requires an exact match. */\n purpose: string;\n /** Expiry, epoch seconds. */\n exp: number;\n /** Issued at, epoch seconds. Set by signToken; lets a route refuse a token older than a later change. */\n iat?: number;\n /** Free-form, purpose-specific. */\n data?: Record<string, string>;\n};\n\nconst encoder = new TextEncoder();\n\n// Changing this invalidates every outstanding token. Bump it on purpose only.\nconst KEY_SALT = encoder.encode(\"easy-ping/tokens/v1\");\n\n/** One HMAC key per purpose, derived with HKDF, so an unsubscribe key signs nothing else. */\nasync function hmacKey(secret: string, purpose: string): Promise<CryptoKey> {\n const master = await crypto.subtle.importKey(\"raw\", encoder.encode(secret), \"HKDF\", false, [\n \"deriveKey\",\n ]);\n return crypto.subtle.deriveKey(\n { name: \"HKDF\", hash: \"SHA-256\", salt: KEY_SALT, info: encoder.encode(purpose) },\n master,\n { name: \"HMAC\", hash: \"SHA-256\", length: 256 },\n false,\n [\"sign\", \"verify\"],\n );\n}\n\nexport async function signToken(\n secret: string,\n claims: TokenClaims,\n now: Date = new Date(),\n): Promise<string> {\n const stamped: TokenClaims = { ...claims, iat: claims.iat ?? Math.floor(now.getTime() / 1000) };\n const body = encodeBase64Url(JSON.stringify(stamped));\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n await hmacKey(secret, claims.purpose),\n encoder.encode(body),\n );\n return `${body}.${encodeBase64Url(new Uint8Array(signature))}`;\n}\n\n/** null for every failure mode. Distinguishing them tells an attacker which part to fix. */\nexport async function verifyToken(\n secret: string,\n token: string,\n purpose: string,\n now: Date = new Date(),\n): Promise<TokenClaims | null> {\n const separator = token.lastIndexOf(\".\");\n if (separator <= 0) return null;\n\n const body = token.slice(0, separator);\n const signature = decodeBase64UrlBytes(token.slice(separator + 1));\n if (!signature) return null;\n\n // Verified under the expected purpose's key before the body is parsed. subtle.verify is constant-time.\n const valid = await crypto.subtle.verify(\n \"HMAC\",\n await hmacKey(secret, purpose),\n signature,\n encoder.encode(body),\n );\n if (!valid) return null;\n\n const decoded = decodeBase64Url(body);\n if (!decoded) return null;\n\n let claims: TokenClaims;\n try {\n claims = JSON.parse(decoded) as TokenClaims;\n } catch {\n return null;\n }\n\n if (typeof claims?.uid !== \"string\" || typeof claims.exp !== \"number\") return null;\n if (claims.purpose !== purpose) return null;\n if (claims.exp * 1000 <= now.getTime()) return null;\n if (claims.iat !== undefined && typeof claims.iat !== \"number\") return null;\n\n if (claims.data !== undefined) {\n if (typeof claims.data !== \"object\" || claims.data === null || Array.isArray(claims.data)) {\n return null;\n }\n for (const value of Object.values(claims.data)) {\n if (typeof value !== \"string\") return null;\n }\n }\n\n return claims;\n}\n\nexport const DEFAULT_TOKEN_TTL_SECONDS = 30 * 24 * 60 * 60;\n/** Ninety days. A link that must outlive this should be re-issued, not made immortal. */\nexport const MAX_TOKEN_TTL_SECONDS = 90 * 24 * 60 * 60;\n\nexport const expiresIn = (seconds: number, now: Date = new Date()): number =>\n Math.floor(now.getTime() / 1000) + Math.min(Math.max(seconds, 0), MAX_TOKEN_TTL_SECONDS);\n\nexport type SignRequest = {\n uid: string;\n purpose: string;\n data?: Record<string, string>;\n /** Defaults to 30 days, capped at 90. */\n ttlSeconds?: number;\n};\n\n/** What a plugin gets instead of the secret: signs only its own declared purposes. */\nexport function createScopedSigner(\n secret: string,\n pluginId: string,\n purposes: ReadonlySet<string>,\n onViolation: (message: string) => Error,\n): (request: SignRequest) => Promise<string> {\n return (request) => {\n if (!purposes.has(request.purpose)) {\n throw onViolation(\n `plugin \"${pluginId}\" tried to sign a token for purpose \"${request.purpose}\", ` +\n \"which none of its signed routes declare.\",\n );\n }\n return signToken(secret, {\n uid: request.uid,\n purpose: request.purpose,\n exp: expiresIn(request.ttlSeconds ?? DEFAULT_TOKEN_TTL_SECONDS),\n ...(request.data ? { data: request.data } : {}),\n });\n };\n}\n","import type { DatabaseAdapter } from \"./adapter\";\nimport type { SessionConfig } from \"./config\";\nimport type { Logger } from \"./errors\";\nimport type { Promisable, RouteDefinition } from \"./plugin\";\nimport type { Runner } from \"./runner\";\nimport { inboxChannel, type Signals } from \"./signals\";\nimport { verifyToken } from \"./tokens\";\n\nexport type EventsSettings = {\n heartbeatMs: number;\n probeIntervalMs: number;\n maxDurationMs: number;\n maxStreamsPerUser: number;\n maxStreams: number;\n};\n\n/** Unread chunks a stream may hold before it is closed on a consumer that stopped reading. */\nconst STREAM_HIGH_WATER_MARK = 256;\n\nexport type HandlerDeps = {\n adapter: DatabaseAdapter;\n session: SessionConfig;\n runner: Runner;\n logger: Logger;\n basePath: string;\n secret: string;\n signals: Signals;\n /** `false` unmounts GET /events. */\n events: EventsSettings | false;\n /** Fire-and-forget delivery pass after a request. Rate-limited by the instance. */\n sweepOnRequest?: (() => void) | undefined;\n cronSecret?: string | undefined;\n /** Guards plugin machine routes. The instance defaults it to cronSecret. */\n machineSecret?: string | undefined;\n cronMaxSweeps?: number | undefined;\n pluginRoutes?: readonly RouteDefinition[] | undefined;\n /** Returns a 429 to send, or null to proceed. Runs after onRequest, before routing. */\n rateLimit?: ((request: Request) => Response | null) | undefined;\n /** Origins other than the request's own host that may POST. `*.example.com` allowed. */\n trustedOrigins?: readonly string[] | undefined;\n /** Runs before routing. Returning a Response short-circuits; use it for rate limiting. */\n // biome-ignore lint/suspicious/noConfusingVoidType: a hook that returns nothing is the common case\n onRequest?: ((request: Request) => Promisable<Response | undefined | void>) | undefined;\n maxBodyBytes?: number | undefined;\n};\n\n/** Every JSON body is capped here. Nothing legitimate the routes accept is bigger. */\nexport const MAX_BODY_BYTES = 64 * 1024;\n\nconst MAX_READ_IDS = 200;\n\nconst SESSION_ERROR: unique symbol = Symbol(\"session-error\");\n\n// Per-user data: no shared caching, no sniffing.\nconst PRIVATE_HEADERS: Record<string, string> = {\n \"cache-control\": \"private, no-store\",\n \"x-content-type-options\": \"nosniff\",\n};\n\nconst json = (body: unknown, status = 200, headers: Record<string, string> = {}) =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json\", ...PRIVATE_HEADERS, ...headers },\n });\n\nconst empty = (status: number) => new Response(null, { status, headers: PRIVATE_HEADERS });\n\n/** Plugin responses get the same headers, without touching their body. */\nfunction harden(response: Response): Response {\n const headers = new Headers(response.headers);\n for (const [name, value] of Object.entries(PRIVATE_HEADERS)) {\n if (!headers.has(name)) headers.set(name, value);\n }\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nconst encoder = new TextEncoder();\n\n/** Constant time over SHA-256 digests, so neither content nor length leaks. Works on edge runtimes. */\nasync function timingSafeEqual(a: string, b: string): Promise<boolean> {\n const [left, right] = await Promise.all(\n [a, b].map(\n async (value) => new Uint8Array(await crypto.subtle.digest(\"SHA-256\", encoder.encode(value))),\n ),\n );\n let diff = 0;\n for (let i = 0; i < 32; i += 1) diff |= (left?.[i] ?? 0) ^ (right?.[i] ?? 0);\n return diff === 0;\n}\n\n/** Anchored at a segment boundary: `/foo/api/notifications/cron` is not a cron request. */\nfunction routePath(url: URL, basePath: string): string {\n const { pathname } = url;\n if (pathname === basePath) return \"/\";\n if (pathname.startsWith(`${basePath}/`)) return pathname.slice(basePath.length);\n return pathname;\n}\n\nexport type JsonBody = { body: Record<string, unknown> } | { error: Response };\n\n/** Reads a JSON object body with a streaming byte cap. Malformed JSON is 400; an empty body is `{}`. */\nexport async function readJsonBody(\n request: Request,\n maxBytes: number = MAX_BODY_BYTES,\n): Promise<JsonBody> {\n const tooLarge = () => ({ error: json({ error: `body exceeds ${maxBytes} bytes` }, 413) });\n\n const declared = Number(request.headers.get(\"content-length\"));\n if (Number.isFinite(declared) && declared > maxBytes) return tooLarge();\n if (!request.body) return { body: {} };\n\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n return tooLarge();\n }\n chunks.push(value);\n }\n\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n const text = new TextDecoder().decode(bytes);\n if (text.trim() === \"\") return { body: {} };\n\n try {\n const parsed: unknown = JSON.parse(text);\n return {\n body:\n parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {},\n };\n } catch {\n return { error: json({ error: \"body must be a JSON object\" }, 400) };\n }\n}\n\nconst isJsonContentType = (request: Request) =>\n /^application\\/json\\s*(;|$)/i.test((request.headers.get(\"content-type\") ?? \"\").trim());\n\nfunction originAllowed(origin: string, url: URL, request: Request, trusted: readonly string[]) {\n let host: string;\n try {\n host = new URL(origin).host;\n } catch {\n return false;\n }\n\n if (host === url.host) return true;\n // Behind a proxy that rewrites Host, the public host arrives here instead.\n const forwarded = request.headers.get(\"x-forwarded-host\")?.split(\",\")[0]?.trim();\n if (forwarded && host === forwarded) return true;\n\n return trusted.some((entry) =>\n entry.startsWith(\"*.\") ? host.endsWith(entry.slice(1)) : entry === origin,\n );\n}\n\n/** CSRF: a cross-site form can neither send `application/json` without a preflight nor forge `Origin`. */\nfunction csrfCheck(request: Request, url: URL, trusted: readonly string[]): Response | null {\n if (!isJsonContentType(request)) {\n return json({ error: \"content-type must be application/json\" }, 415);\n }\n\n const origin = request.headers.get(\"origin\");\n if (origin === null) return null;\n if (origin === \"null\" || !originAllowed(origin, url, request, trusted)) return empty(403);\n\n return null;\n}\n\nexport function createHandler(deps: HandlerDeps) {\n const trustedOrigins = deps.trustedOrigins ?? [];\n const maxBodyBytes = deps.maxBodyBytes ?? MAX_BODY_BYTES;\n\n let warnedBadUserId = false;\n\n async function resolveUserId(request: Request): Promise<string | null | typeof SESSION_ERROR> {\n let id: unknown;\n try {\n id = await deps.session.getUserId(request);\n } catch (error) {\n // A broken session lookup is a 500, never a 401. RFC 0002 §1.\n deps.logger.error(\"session.getUserId threw\", { error });\n return SESSION_ERROR;\n }\n if (id === null || id === undefined) return null;\n if (typeof id !== \"string\" || id === \"\") {\n if (!warnedBadUserId) {\n warnedBadUserId = true;\n deps.logger.warn(\n `session.getUserId returned ${id === \"\" ? \"an empty string\" : typeof id}; treating the ` +\n \"request as unauthenticated. Return a non-empty string or null.\",\n );\n }\n return null;\n }\n return id;\n }\n\n async function bearerMatches(request: Request, secret: string | undefined): Promise<boolean> {\n if (!secret) return false;\n const header = request.headers.get(\"authorization\") ?? \"\";\n const presented = header.startsWith(\"Bearer \") ? header.slice(7) : header;\n return timingSafeEqual(presented, secret);\n }\n\n async function handleCron(request: Request): Promise<Response> {\n if (!deps.cronSecret) return empty(404);\n if (!(await bearerMatches(request, deps.cronSecret))) return empty(401);\n\n // Bounded so an overlapping scheduler does not hold a request open for the whole backlog.\n const result = await deps.runner.drain(\n deps.cronMaxSweeps === undefined ? {} : { maxSweeps: deps.cronMaxSweeps },\n );\n return json(result);\n }\n\n /** Plugin routes first; auth is enforced here so a plugin cannot forget it. */\n async function handlePluginRoute(\n route: RouteDefinition,\n request: Request,\n url: URL,\n ): Promise<Response> {\n if (route.scope.type === \"user\") {\n if (request.method === \"POST\") {\n const rejected = csrfCheck(request, url, trustedOrigins);\n if (rejected) return rejected;\n }\n\n const userId = await resolveUserId(request);\n if (userId === SESSION_ERROR) return empty(500);\n if (userId === null) return empty(401);\n return harden(await route.handler({ request, userId, claims: null, params: {} }));\n }\n\n if (route.scope.type === \"machine\") {\n if (!deps.machineSecret) return empty(404);\n if (!(await bearerMatches(request, deps.machineSecret))) return empty(401);\n return harden(await route.handler({ request, userId: null, claims: null, params: {} }));\n }\n\n if (route.scope.type === \"signed\") {\n const token =\n url.searchParams.get(\"token\") ??\n (request.headers.get(\"authorization\") ?? \"\").replace(/^Bearer /, \"\");\n\n const claims = await verifyToken(deps.secret, token, route.scope.purpose);\n // One response for every failure mode. RFC 0002 §5.\n if (!claims) return empty(400);\n\n return harden(await route.handler({ request, userId: claims.uid, claims, params: {} }));\n }\n\n return harden(await route.handler({ request, userId: null, claims: null, params: {} }));\n }\n\n async function route(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const path = routePath(url, deps.basePath);\n\n if (deps.onRequest) {\n const early = await deps.onRequest(request);\n if (early instanceof Response) return early;\n }\n\n if (deps.rateLimit) {\n const limited = deps.rateLimit(request);\n if (limited) return limited;\n }\n\n if (path === \"/cron\") {\n if (request.method !== \"POST\") return empty(405);\n return handleCron(request);\n }\n\n const pluginRoute = deps.pluginRoutes?.find(\n (candidate) => candidate.path === path && candidate.method === request.method,\n );\n if (pluginRoute) return handlePluginRoute(pluginRoute, request, url);\n\n if (request.method === \"POST\") {\n const rejected = csrfCheck(request, url, trustedOrigins);\n if (rejected) return rejected;\n }\n\n const userId = await resolveUserId(request);\n if (userId === SESSION_ERROR) return empty(500);\n if (userId === null) return empty(401);\n\n if (request.method === \"GET\" && path === \"/events\") {\n if (!deps.events) return empty(404);\n // A session can open streams for free; without a cap one account can hold every socket.\n if ((openStreams.get(userId) ?? 0) >= deps.events.maxStreamsPerUser) {\n return json({ error: \"too many open event streams\" }, 429, { \"retry-after\": \"30\" });\n }\n if (totalStreams >= deps.events.maxStreams) {\n return json({ error: \"event streams unavailable\" }, 503, { \"retry-after\": \"30\" });\n }\n return events(request, userId, deps.events);\n }\n\n if (request.method === \"GET\" && path === \"/\") {\n const limitParam = Number(url.searchParams.get(\"limit\") ?? 20);\n const limit = Number.isFinite(limitParam) ? Math.min(Math.max(limitParam, 1), 100) : 20;\n const cursor = url.searchParams.get(\"cursor\");\n\n // unseenCount rides on the first page only: a cursor request is scrollback, not a poll.\n const [page, unseenCount] = await Promise.all([\n deps.adapter.listNotifications({\n userId,\n limit,\n ...(cursor ? { cursor } : {}),\n ...(url.searchParams.get(\"unreadOnly\") === \"true\" ? { unreadOnly: true } : {}),\n }),\n cursor ? Promise.resolve(null) : deps.adapter.countUnseen(userId),\n ]);\n\n return json(unseenCount === null ? page : { ...page, unseenCount });\n }\n\n if (request.method === \"GET\" && path === \"/count\") {\n return json({ unseen: await deps.adapter.countUnseen(userId) });\n }\n\n if (request.method === \"POST\" && path === \"/seen\") {\n const parsed = await readJsonBody(request, maxBodyBytes);\n if (\"error\" in parsed) return parsed.error;\n const before = typeof parsed.body.before === \"string\" ? new Date(parsed.body.before) : null;\n\n // +1ms: Postgres keeps microseconds, an ISO string milliseconds; without it markSeen misses the newest row.\n const cutoff =\n before && !Number.isNaN(before.getTime()) ? new Date(before.getTime() + 1) : new Date();\n\n await deps.adapter.markSeen(userId, cutoff);\n deps.signals.publish(inboxChannel(userId));\n return json({ ok: true });\n }\n\n if (request.method === \"POST\" && path === \"/read\") {\n const parsed = await readJsonBody(request, maxBodyBytes);\n if (\"error\" in parsed) return parsed.error;\n const ids = Array.isArray(parsed.body.ids)\n ? parsed.body.ids.filter((id): id is string => typeof id === \"string\")\n : [];\n if (ids.length === 0) return json({ error: \"ids must be a non-empty string array\" }, 400);\n\n if (ids.length > MAX_READ_IDS) {\n return json({ error: `at most ${MAX_READ_IDS} ids per request` }, 400);\n }\n\n // 404, not 403: a 403 confirms the row exists. RFC 0002 §2.\n const updated = await deps.adapter.markRead(userId, ids);\n if (updated > 0) deps.signals.publish(inboxChannel(userId));\n return updated === 0 ? empty(404) : json({ updated });\n }\n\n if (request.method === \"POST\" && path === \"/read-all\") {\n const updated = await deps.adapter.markAllRead(userId);\n if (updated > 0) deps.signals.publish(inboxChannel(userId));\n return json({ updated });\n }\n\n return empty(404);\n }\n\n const openStreams = new Map<string, number>();\n let totalStreams = 0;\n\n const trackStream = (userId: string) => {\n openStreams.set(userId, (openStreams.get(userId) ?? 0) + 1);\n totalStreams += 1;\n return () => {\n const remaining = (openStreams.get(userId) ?? 1) - 1;\n if (remaining > 0) openStreams.set(userId, remaining);\n else openStreams.delete(userId);\n totalStreams -= 1;\n };\n };\n\n /** A change fingerprint cheap enough to take every probe interval. */\n async function fingerprint(userId: string): Promise<string> {\n const [page, unseen] = await Promise.all([\n deps.adapter.listNotifications({ userId, limit: 1 }),\n deps.adapter.countUnseen(userId),\n ]);\n const newest = page.notifications[0];\n return `${newest?.id ?? \"\"}|${newest?.readAt ? 1 : 0}|${unseen}`;\n }\n\n // One probe per user, however many streams that user holds: N tabs must not mean N queries.\n type Probe = { listeners: Set<() => void>; timer: ReturnType<typeof setInterval>; last?: string };\n const probes = new Map<string, Probe>();\n\n function subscribeProbe(userId: string, onChanged: () => void, intervalMs: number) {\n let probe = probes.get(userId);\n if (!probe) {\n const created: Probe = {\n listeners: new Set(),\n timer: setInterval(() => {\n fingerprint(userId)\n .then((value) => {\n if (created.last !== undefined && value !== created.last) {\n for (const listener of created.listeners) listener();\n }\n created.last = value;\n })\n .catch((error) => deps.logger.error(\"events probe failed\", { error }));\n }, intervalMs),\n };\n probe = created;\n probes.set(userId, created);\n fingerprint(userId)\n .then((value) => {\n if (created.last === undefined) created.last = value;\n })\n .catch(() => {});\n }\n probe.listeners.add(onChanged);\n return () => {\n const current = probes.get(userId);\n if (!current) return;\n current.listeners.delete(onChanged);\n if (current.listeners.size === 0) {\n clearInterval(current.timer);\n probes.delete(userId);\n }\n };\n }\n\n /**\n * Server-Sent Events: `ready` once, `changed` whenever this user's inbox\n * moves, comments as keepalive. No payload ever travels on the stream; the\n * client fetches the feed on `changed`. RFC 0006 §4D.\n */\n function events(request: Request, userId: string, settings: EventsSettings): Response {\n const encoder = new TextEncoder();\n const timers: ReturnType<typeof setInterval>[] = [];\n const unsubscribes: (() => void)[] = [];\n let closed = false;\n let cleanup = () => {};\n\n const stream = new ReadableStream<Uint8Array>(\n {\n start(controller) {\n const write = (text: string) => {\n if (closed) return;\n // A consumer that stopped reading would make this queue grow without bound.\n if (controller.desiredSize !== null && controller.desiredSize <= 0) {\n cleanup();\n return;\n }\n try {\n controller.enqueue(encoder.encode(text));\n } catch {\n cleanup();\n }\n };\n cleanup = () => {\n if (closed) return;\n closed = true;\n for (const unsubscribe of unsubscribes) unsubscribe();\n for (const timer of timers) clearInterval(timer);\n try {\n controller.close();\n } catch {\n // already closed by the consumer\n }\n };\n const changed = () => write(\"event: changed\\ndata: {}\\n\\n\");\n\n unsubscribes.push(trackStream(userId));\n write(\"retry: 3000\\n\\nevent: ready\\ndata: {}\\n\\n\");\n unsubscribes.push(deps.signals.subscribe(inboxChannel(userId), changed));\n timers.push(setInterval(() => write(\": keepalive\\n\\n\"), settings.heartbeatMs));\n\n if (!deps.signals.crossProcess && settings.probeIntervalMs > 0) {\n unsubscribes.push(subscribeProbe(userId, changed, settings.probeIntervalMs));\n }\n\n if (settings.maxDurationMs > 0) {\n timers.push(\n setTimeout(cleanup, settings.maxDurationMs) as ReturnType<typeof setInterval>,\n );\n }\n request.signal?.addEventListener(\"abort\", cleanup, { once: true });\n },\n cancel() {\n cleanup();\n },\n },\n { highWaterMark: STREAM_HIGH_WATER_MARK },\n );\n\n return new Response(stream, {\n headers: {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache, no-store\",\n connection: \"keep-alive\",\n \"x-accel-buffering\": \"no\",\n \"x-content-type-options\": \"nosniff\",\n },\n });\n }\n\n async function handle(request: Request): Promise<Response> {\n let response: Response | undefined;\n try {\n response = await route(request);\n return response;\n } catch (error) {\n // A thrown driver error must not escape: unhandled rejection on Node, stack trace elsewhere.\n deps.logger.error(\"request failed\", { url: request.url, error });\n return empty(500);\n } finally {\n // Only a served request earns a sweep; anonymous 401s must not drive database work.\n if (response && response.status < 400) deps.sweepOnRequest?.();\n }\n }\n\n return {\n handle,\n GET: handle,\n POST: handle,\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/sql/statement.ts"],"names":[],"mappings":";AASA,IAAM,cAAc,CAAC,KAAA,KAAoB,iBAAiB,IAAA,GAAO,KAAA,CAAM,aAAY,GAAI,KAAA;AAGhF,IAAM,YAAN,MAAgB;AAAA,EACrB,KAAA,GAAQ,EAAA;AAAA,EACC,SAAoB,EAAC;AAAA,EACrB,YAAA;AAAA,EACA,KAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAA4B,EAAC,EAAG;AAC1C,IAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,WAAA,IAAe,QAAA;AAC3C,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,IAAA,IAAQ,WAAA;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAI,QAAA,EAAwB;AAC1B,IAAA,IAAA,CAAK,KAAA,IAAS,QAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAA,EAAsB;AAC1B,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,KAAA,IAAS,KAAK,YAAA,KAAiB,QAAA,GAAW,IAAI,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,GAAA;AAC1E,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAA,CAAK,MAAA,EAA4B,SAAA,GAAY,IAAA,EAAY;AACvD,IAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,EAAO,KAAA,KAAU;AAC/B,MAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AACjC,MAAA,IAAA,CAAK,MAAM,KAAK,CAAA;AAAA,IAClB,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAA,EAAsD;AAC1D,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,KAAA,CAAM,QAAQ,CAAC,CAAC,KAAA,EAAO,IAAI,GAAG,KAAA,KAAU;AACtC,MAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AAC5B,MAAA,IAAA,CAAK,MAAM,KAAK,CAAA;AAChB,MAAA,IAAI,KAAK,YAAA,KAAiB,QAAA,OAAe,GAAA,CAAI,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IAC1D,CAAC,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,EACrB;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AACF;AAEO,IAAM,YACX,CAAC,SAAA,KACD,CAAC,UAAA,KACC,GAAG,SAAS,CAAA,EAAG,UAAA,CAAW,KAAA,CAAM,SAAS,CAAA,CAAE,IAAA,CAAK,YAAY,SAAS,CAAC,GAAG,SAAS,CAAA;AAG/E,IAAM,KAAA,GAAQ,UAAU,GAAG","file":"chunk-CK5UPVYP.js","sourcesContent":["export type Placeholder = \"dollar\" | \"question\";\n\nexport type StatementOptions = {\n /** `$1, $2` for Postgres; `?` for MySQL and SQLite. */\n placeholder?: Placeholder;\n /** What the driver is handed for a JS value. Dates become ISO strings by default. */\n bind?: (value: unknown) => unknown;\n};\n\nconst defaultBind = (value: unknown) => (value instanceof Date ? value.toISOString() : value);\n\n/** SQL text plus bound values. Values are never interpolated; identifiers arrive pre-validated. */\nexport class Statement {\n #text = \"\";\n readonly params: unknown[] = [];\n readonly #placeholder: Placeholder;\n readonly #bind: (value: unknown) => unknown;\n\n constructor(options: StatementOptions = {}) {\n this.#placeholder = options.placeholder ?? \"dollar\";\n this.#bind = options.bind ?? defaultBind;\n }\n\n /** Raw SQL. Never user input; use `value`. */\n raw(fragment: string): this {\n this.#text += fragment;\n return this;\n }\n\n value(value: unknown): this {\n this.params.push(this.#bind(value));\n this.#text += this.#placeholder === \"dollar\" ? `$${this.params.length}` : \"?\";\n return this;\n }\n\n list(values: readonly unknown[], separator = \", \"): this {\n values.forEach((value, index) => {\n if (index > 0) this.raw(separator);\n this.value(value);\n });\n return this;\n }\n\n /** `($1::text, $2::timestamptz)`. Casts are Postgres-only and dropped elsewhere. */\n tuple(cells: readonly (readonly [unknown, string])[]): this {\n this.raw(\"(\");\n cells.forEach(([value, cast], index) => {\n if (index > 0) this.raw(\", \");\n this.value(value);\n if (this.#placeholder === \"dollar\") this.raw(`::${cast}`);\n });\n return this.raw(\")\");\n }\n\n get text(): string {\n return this.#text;\n }\n}\n\nexport const quoteWith =\n (quoteChar: '\"' | \"`\") =>\n (identifier: string): string =>\n `${quoteChar}${identifier.split(quoteChar).join(quoteChar + quoteChar)}${quoteChar}`;\n\n/** Double-quoted: Postgres and SQLite. */\nexport const quote = quoteWith('\"');\n"]}