@framers/sql-storage-adapter 0.7.2 → 0.7.4

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 (194) hide show
  1. package/README.md +41 -0
  2. package/dist/adapters/electron/preload.cjs +289 -0
  3. package/dist/adapters/electron/renderer.d.ts +9 -0
  4. package/dist/adapters/electron/renderer.d.ts.map +1 -0
  5. package/dist/adapters/electron/renderer.js +8 -0
  6. package/dist/adapters/electron/renderer.js.map +1 -0
  7. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
  8. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
  9. package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
  10. package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
  11. package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
  12. package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
  13. package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
  14. package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
  15. package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
  16. package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
  17. package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
  18. package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
  19. package/dist/cjs/adapters/electron/index.d.ts +74 -0
  20. package/dist/cjs/adapters/electron/index.js +86 -0
  21. package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
  22. package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
  23. package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
  24. package/dist/cjs/adapters/electron/ipc/index.js +38 -0
  25. package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
  26. package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
  27. package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
  28. package/dist/cjs/adapters/electron/ipc/types.js +15 -0
  29. package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
  30. package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
  31. package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
  32. package/dist/cjs/adapters/electron/migration/index.js +29 -0
  33. package/dist/cjs/adapters/electron/preload.d.ts +126 -0
  34. package/dist/cjs/adapters/electron/preload.js +233 -0
  35. package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
  36. package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
  37. package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
  38. package/dist/cjs/adapters/electron/recovery/index.js +34 -0
  39. package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
  40. package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
  41. package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
  42. package/dist/cjs/adapters/electron/renderer.js +33 -0
  43. package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
  44. package/dist/cjs/adapters/electron/window/index.js +29 -0
  45. package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
  46. package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
  47. package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
  48. package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
  49. package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
  50. package/dist/cjs/adapters/postgresAdapter.js +889 -0
  51. package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
  52. package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
  53. package/dist/cjs/adapters/supabase.d.ts +58 -0
  54. package/dist/cjs/adapters/supabase.js +401 -0
  55. package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
  56. package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
  57. package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
  58. package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
  59. package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
  60. package/dist/cjs/core/contracts/blobCodec.js +15 -0
  61. package/dist/cjs/core/contracts/context.d.ts +221 -0
  62. package/dist/cjs/core/contracts/context.js +15 -0
  63. package/dist/cjs/core/contracts/dialect.d.ts +154 -0
  64. package/dist/cjs/core/contracts/dialect.js +15 -0
  65. package/dist/cjs/core/contracts/events.d.ts +225 -0
  66. package/dist/cjs/core/contracts/events.js +15 -0
  67. package/dist/cjs/core/contracts/exporter.d.ts +13 -0
  68. package/dist/cjs/core/contracts/exporter.js +15 -0
  69. package/dist/cjs/core/contracts/extensions.d.ts +73 -0
  70. package/dist/cjs/core/contracts/extensions.js +15 -0
  71. package/dist/cjs/core/contracts/features.d.ts +25 -0
  72. package/dist/cjs/core/contracts/features.js +61 -0
  73. package/dist/cjs/core/contracts/fts.d.ts +66 -0
  74. package/dist/cjs/core/contracts/fts.js +15 -0
  75. package/dist/cjs/core/contracts/hooks.d.ts +481 -0
  76. package/dist/cjs/core/contracts/hooks.js +140 -0
  77. package/dist/cjs/core/contracts/index.d.ts +260 -0
  78. package/dist/cjs/core/contracts/index.js +41 -0
  79. package/dist/cjs/core/contracts/limitations.d.ts +46 -0
  80. package/dist/cjs/core/contracts/limitations.js +218 -0
  81. package/dist/cjs/core/contracts/performance.d.ts +308 -0
  82. package/dist/cjs/core/contracts/performance.js +144 -0
  83. package/dist/cjs/core/database.d.ts +220 -0
  84. package/dist/cjs/core/database.js +136 -0
  85. package/dist/cjs/core/portable.d.ts +24 -0
  86. package/dist/cjs/core/portable.js +68 -0
  87. package/dist/cjs/core/resolver.d.ts +77 -0
  88. package/dist/cjs/core/resolver.js +235 -0
  89. package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
  90. package/dist/cjs/dialects/PostgresDialect.js +143 -0
  91. package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
  92. package/dist/cjs/dialects/SqliteDialect.js +142 -0
  93. package/dist/cjs/dialects/shared.d.ts +17 -0
  94. package/dist/cjs/dialects/shared.js +90 -0
  95. package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
  96. package/dist/cjs/exporters/PostgresExporter.js +61 -0
  97. package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
  98. package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
  99. package/dist/cjs/features/auth/authJsAdapter.d.ts +110 -0
  100. package/dist/cjs/features/auth/authJsAdapter.js +251 -0
  101. package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
  102. package/dist/cjs/features/backup/cloudBackup.js +209 -0
  103. package/dist/cjs/features/kv/idb.d.ts +79 -0
  104. package/dist/cjs/features/kv/idb.js +32 -0
  105. package/dist/cjs/features/kv/index.d.ts +14 -0
  106. package/dist/cjs/features/kv/index.js +40 -0
  107. package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
  108. package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
  109. package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
  110. package/dist/cjs/features/kv/keyValueStore.js +67 -0
  111. package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
  112. package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
  113. package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
  114. package/dist/cjs/features/kv/valueCodec.js +426 -0
  115. package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
  116. package/dist/cjs/features/migrations/dataExport.js +194 -0
  117. package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
  118. package/dist/cjs/features/migrations/dataImport.js +300 -0
  119. package/dist/cjs/features/migrations/migration.d.ts +89 -0
  120. package/dist/cjs/features/migrations/migration.js +187 -0
  121. package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
  122. package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
  123. package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
  124. package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
  125. package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
  126. package/dist/cjs/features/sync/conflicts/index.js +21 -0
  127. package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
  128. package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
  129. package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
  130. package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
  131. package/dist/cjs/features/sync/devices/index.d.ts +10 -0
  132. package/dist/cjs/features/sync/devices/index.js +21 -0
  133. package/dist/cjs/features/sync/index.d.ts +37 -0
  134. package/dist/cjs/features/sync/index.js +111 -0
  135. package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
  136. package/dist/cjs/features/sync/protocol/index.js +23 -0
  137. package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
  138. package/dist/cjs/features/sync/protocol/messages.js +215 -0
  139. package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
  140. package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
  141. package/dist/cjs/features/sync/syncManager.d.ts +348 -0
  142. package/dist/cjs/features/sync/syncManager.js +455 -0
  143. package/dist/cjs/features/sync/tables/index.d.ts +10 -0
  144. package/dist/cjs/features/sync/tables/index.js +21 -0
  145. package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
  146. package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
  147. package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
  148. package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
  149. package/dist/cjs/features/sync/transport/index.d.ts +12 -0
  150. package/dist/cjs/features/sync/transport/index.js +25 -0
  151. package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
  152. package/dist/cjs/features/sync/transport/transport.js +163 -0
  153. package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
  154. package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
  155. package/dist/cjs/fts/PostgresFts.d.ts +29 -0
  156. package/dist/cjs/fts/PostgresFts.js +77 -0
  157. package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
  158. package/dist/cjs/fts/SqliteFts5.js +58 -0
  159. package/dist/cjs/index.d.ts +31 -0
  160. package/dist/cjs/index.js +103 -0
  161. package/dist/cjs/package.json +3 -0
  162. package/dist/cjs/shared/connectionGate.d.ts +94 -0
  163. package/dist/cjs/shared/connectionGate.js +77 -0
  164. package/dist/cjs/shared/errors.d.ts +23 -0
  165. package/dist/cjs/shared/errors.js +45 -0
  166. package/dist/cjs/shared/logger.d.ts +26 -0
  167. package/dist/cjs/shared/logger.js +40 -0
  168. package/dist/cjs/shared/parameterUtils.d.ts +16 -0
  169. package/dist/cjs/shared/parameterUtils.js +59 -0
  170. package/dist/cjs/shared/postgresTarget.d.ts +11 -0
  171. package/dist/cjs/shared/postgresTarget.js +30 -0
  172. package/dist/cjs/shared/segment.d.ts +43 -0
  173. package/dist/cjs/shared/segment.js +63 -0
  174. package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
  175. package/dist/cjs/shared/serializedTransaction.js +74 -0
  176. package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
  177. package/dist/cjs/shared/splitSqlStatements.js +163 -0
  178. package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
  179. package/dist/cjs/shared/sqlPlaceholders.js +263 -0
  180. package/dist/cjs/types/index.d.ts +29 -0
  181. package/dist/cjs/types/index.js +33 -0
  182. package/dist/core/portable.d.ts +24 -0
  183. package/dist/core/portable.d.ts.map +1 -0
  184. package/dist/core/portable.js +24 -0
  185. package/dist/core/portable.js.map +1 -0
  186. package/dist/features/auth/authJsAdapter.d.ts +110 -0
  187. package/dist/features/auth/authJsAdapter.d.ts.map +1 -0
  188. package/dist/features/auth/authJsAdapter.js +248 -0
  189. package/dist/features/auth/authJsAdapter.js.map +1 -0
  190. package/dist/index.d.ts +1 -0
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.js +1 -0
  193. package/dist/index.js.map +1 -1
  194. package/package.json +149 -24
@@ -0,0 +1,251 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var authJsAdapter_exports = {};
19
+ __export(authJsAdapter_exports, {
20
+ authJsTablesSql: () => authJsTablesSql,
21
+ createAuthJsAdapter: () => createAuthJsAdapter,
22
+ ensureAuthJsTables: () => ensureAuthJsTables
23
+ });
24
+ module.exports = __toCommonJS(authJsAdapter_exports);
25
+ var import_features = require("../../core/contracts/features.js");
26
+ const PREFIX = /^[A-Za-z_][A-Za-z0-9_]*$/;
27
+ const tablesFor = (options) => {
28
+ const prefix = options.tablePrefix ?? "auth_";
29
+ if (!PREFIX.test(prefix)) {
30
+ throw new Error(`tablePrefix must be letters, digits and underscores, starting with a letter or an underscore; got ${JSON.stringify(prefix)}.`);
31
+ }
32
+ return {
33
+ users: `${prefix}users`,
34
+ accounts: `${prefix}accounts`,
35
+ sessions: `${prefix}sessions`,
36
+ verificationTokens: `${prefix}verification_tokens`
37
+ };
38
+ };
39
+ function authJsTablesSql(db, options = {}) {
40
+ const t = tablesFor(options);
41
+ const d = (0, import_features.createStorageFeatures)(db).dialect;
42
+ const timestamp = d.columnType("timestamp");
43
+ return [
44
+ `CREATE TABLE IF NOT EXISTS ${t.users} (id TEXT PRIMARY KEY, name TEXT, email TEXT UNIQUE, email_verified ${timestamp}, image TEXT)`,
45
+ `CREATE TABLE IF NOT EXISTS ${t.accounts} (
46
+ id TEXT PRIMARY KEY,
47
+ user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE,
48
+ type TEXT NOT NULL,
49
+ provider TEXT NOT NULL,
50
+ provider_account_id TEXT NOT NULL,
51
+ refresh_token TEXT,
52
+ access_token TEXT,
53
+ expires_at ${d.columnType("bigint")},
54
+ token_type TEXT,
55
+ scope TEXT,
56
+ id_token TEXT,
57
+ session_state TEXT,
58
+ UNIQUE (provider, provider_account_id)
59
+ )`,
60
+ `CREATE TABLE IF NOT EXISTS ${t.sessions} (session_token TEXT PRIMARY KEY, user_id TEXT NOT NULL REFERENCES ${t.users} (id) ON DELETE CASCADE, expires ${timestamp} NOT NULL)`,
61
+ `CREATE TABLE IF NOT EXISTS ${t.verificationTokens} (identifier TEXT NOT NULL, token TEXT NOT NULL, expires ${timestamp} NOT NULL, PRIMARY KEY (identifier, token))`,
62
+ `CREATE INDEX IF NOT EXISTS ${t.accounts}_user_id ON ${t.accounts} (user_id)`,
63
+ `CREATE INDEX IF NOT EXISTS ${t.sessions}_user_id ON ${t.sessions} (user_id)`
64
+ ];
65
+ }
66
+ async function ensureAuthJsTables(db, options = {}) {
67
+ for (const statement of authJsTablesSql(db, options)) {
68
+ await db.exec(statement);
69
+ }
70
+ }
71
+ const toDate = (value) => value == null ? null : value instanceof Date ? value : new Date(String(value));
72
+ const toUser = (row) => ({
73
+ id: String(row.id),
74
+ name: row.name ?? null,
75
+ email: row.email,
76
+ emailVerified: toDate(row.email_verified),
77
+ image: row.image ?? null
78
+ });
79
+ const toAccount = (row) => {
80
+ const account = {
81
+ userId: String(row.user_id),
82
+ type: row.type,
83
+ provider: row.provider,
84
+ providerAccountId: row.provider_account_id
85
+ };
86
+ for (const field of ["refresh_token", "access_token", "token_type", "scope", "id_token", "session_state"]) {
87
+ if (row[field] != null)
88
+ account[field] = String(row[field]);
89
+ }
90
+ if (row.expires_at != null)
91
+ account.expires_at = Number(row.expires_at);
92
+ return account;
93
+ };
94
+ const toSession = (row) => ({
95
+ sessionToken: row.session_token,
96
+ userId: String(row.user_id),
97
+ expires: toDate(row.expires)
98
+ });
99
+ const toVerificationToken = (row) => ({
100
+ identifier: row.identifier,
101
+ token: row.token,
102
+ expires: toDate(row.expires)
103
+ });
104
+ const defaultId = () => {
105
+ const random = globalThis.crypto?.randomUUID;
106
+ if (!random)
107
+ throw new Error("crypto.randomUUID() is not available; pass generateId.");
108
+ return random.call(globalThis.crypto);
109
+ };
110
+ function createAuthJsAdapter(db, options = {}) {
111
+ const t = tablesFor(options);
112
+ const generateId = options.generateId ?? defaultId;
113
+ const getUser = async (id) => {
114
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE id = ?`, [id]);
115
+ return row ? toUser(row) : null;
116
+ };
117
+ const getSession = async (sessionToken) => {
118
+ const row = await db.get(`SELECT * FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
119
+ return row ? toSession(row) : null;
120
+ };
121
+ return {
122
+ async createUser(user) {
123
+ const id = user.id ?? generateId();
124
+ await db.run(`INSERT INTO ${t.users} (id, name, email, email_verified, image) VALUES (?, ?, ?, ?, ?)`, [
125
+ id,
126
+ user.name ?? null,
127
+ user.email,
128
+ user.emailVerified ?? null,
129
+ user.image ?? null
130
+ ]);
131
+ return await getUser(id);
132
+ },
133
+ getUser,
134
+ async getUserByEmail(email) {
135
+ const row = await db.get(`SELECT * FROM ${t.users} WHERE email = ?`, [email]);
136
+ return row ? toUser(row) : null;
137
+ },
138
+ async getUserByAccount({ provider, providerAccountId }) {
139
+ const row = await db.get(`SELECT u.* FROM ${t.users} u JOIN ${t.accounts} a ON a.user_id = u.id WHERE a.provider = ? AND a.provider_account_id = ?`, [provider, providerAccountId]);
140
+ return row ? toUser(row) : null;
141
+ },
142
+ async updateUser(user) {
143
+ const fields = [];
144
+ if ("name" in user)
145
+ fields.push(["name", user.name ?? null]);
146
+ if ("email" in user)
147
+ fields.push(["email", user.email]);
148
+ if ("emailVerified" in user)
149
+ fields.push(["email_verified", user.emailVerified ?? null]);
150
+ if ("image" in user)
151
+ fields.push(["image", user.image ?? null]);
152
+ if (fields.length) {
153
+ await db.run(`UPDATE ${t.users} SET ${fields.map(([column]) => `${column} = ?`).join(", ")} WHERE id = ?`, [
154
+ ...fields.map(([, value]) => value),
155
+ user.id
156
+ ]);
157
+ }
158
+ const updated = await getUser(user.id);
159
+ if (!updated)
160
+ throw new Error(`No user with id ${JSON.stringify(user.id)} to update.`);
161
+ return updated;
162
+ },
163
+ async deleteUser(userId) {
164
+ return db.transaction(async (trx) => {
165
+ const row = await trx.get(`SELECT * FROM ${t.users} WHERE id = ?`, [userId]);
166
+ await trx.run(`DELETE FROM ${t.sessions} WHERE user_id = ?`, [userId]);
167
+ await trx.run(`DELETE FROM ${t.accounts} WHERE user_id = ?`, [userId]);
168
+ await trx.run(`DELETE FROM ${t.users} WHERE id = ?`, [userId]);
169
+ return row ? toUser(row) : null;
170
+ });
171
+ },
172
+ async linkAccount(account) {
173
+ await db.run(`INSERT INTO ${t.accounts} (id, user_id, type, provider, provider_account_id, refresh_token, access_token, expires_at, token_type, scope, id_token, session_state)
174
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
175
+ generateId(),
176
+ account.userId,
177
+ account.type,
178
+ account.provider,
179
+ account.providerAccountId,
180
+ account.refresh_token ?? null,
181
+ account.access_token ?? null,
182
+ account.expires_at ?? null,
183
+ account.token_type ?? null,
184
+ account.scope ?? null,
185
+ account.id_token ?? null,
186
+ account.session_state ?? null
187
+ ]);
188
+ return account;
189
+ },
190
+ async unlinkAccount({ provider, providerAccountId }) {
191
+ await db.run(`DELETE FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [provider, providerAccountId]);
192
+ },
193
+ async getAccount(providerAccountId, provider) {
194
+ const row = await db.get(`SELECT * FROM ${t.accounts} WHERE provider = ? AND provider_account_id = ?`, [
195
+ provider,
196
+ providerAccountId
197
+ ]);
198
+ return row ? toAccount(row) : null;
199
+ },
200
+ async createSession(session) {
201
+ await db.run(`INSERT INTO ${t.sessions} (session_token, user_id, expires) VALUES (?, ?, ?)`, [
202
+ session.sessionToken,
203
+ session.userId,
204
+ session.expires
205
+ ]);
206
+ return { sessionToken: session.sessionToken, userId: session.userId, expires: session.expires };
207
+ },
208
+ async getSessionAndUser(sessionToken) {
209
+ const session = await getSession(sessionToken);
210
+ if (!session)
211
+ return null;
212
+ const user = await getUser(session.userId);
213
+ return user ? { session, user } : null;
214
+ },
215
+ async updateSession(session) {
216
+ const fields = [];
217
+ if (session.expires !== void 0)
218
+ fields.push(["expires", session.expires]);
219
+ if (session.userId !== void 0)
220
+ fields.push(["user_id", session.userId]);
221
+ if (fields.length) {
222
+ await db.run(`UPDATE ${t.sessions} SET ${fields.map(([column]) => `${column} = ?`).join(", ")} WHERE session_token = ?`, [
223
+ ...fields.map(([, value]) => value),
224
+ session.sessionToken
225
+ ]);
226
+ }
227
+ return getSession(session.sessionToken);
228
+ },
229
+ async deleteSession(sessionToken) {
230
+ await db.run(`DELETE FROM ${t.sessions} WHERE session_token = ?`, [sessionToken]);
231
+ },
232
+ async createVerificationToken(token) {
233
+ await db.run(`INSERT INTO ${t.verificationTokens} (identifier, token, expires) VALUES (?, ?, ?)`, [
234
+ token.identifier,
235
+ token.token,
236
+ token.expires
237
+ ]);
238
+ return { identifier: token.identifier, token: token.token, expires: token.expires };
239
+ },
240
+ async useVerificationToken({ identifier, token }) {
241
+ const row = await db.get(`DELETE FROM ${t.verificationTokens} WHERE identifier = ? AND token = ? RETURNING identifier, token, expires`, [identifier, token]);
242
+ return row ? toVerificationToken(row) : null;
243
+ }
244
+ };
245
+ }
246
+ // Annotate the CommonJS export names for ESM import in node:
247
+ 0 && (module.exports = {
248
+ authJsTablesSql,
249
+ createAuthJsAdapter,
250
+ ensureAuthJsTables
251
+ });
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Cloud backup utilities for S3, R2, and other object storage providers.
3
+ *
4
+ * This module provides automatic scheduled backups and restore functionality
5
+ * for SQL databases using S3-compatible storage (AWS S3, Cloudflare R2, MinIO, etc.).
6
+ *
7
+ * Features:
8
+ * - Automatic scheduled backups with configurable intervals
9
+ * - Gzip compression to reduce storage costs
10
+ * - Retention policies (automatic cleanup of old backups)
11
+ * - JSON and SQL export formats
12
+ * - Manual backup/restore on demand
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { S3Client } from '@aws-sdk/client-s3';
17
+ * import { createCloudBackupManager } from '@framers/sql-storage-adapter';
18
+ *
19
+ * const s3Client = new S3Client({ region: 'us-east-1' });
20
+ * const manager = createCloudBackupManager(db, s3Client, 'my-backups', {
21
+ * interval: 3600000, // 1 hour
22
+ * maxBackups: 24,
23
+ * options: { compression: 'gzip', format: 'json' }
24
+ * });
25
+ *
26
+ * manager.start(); // Auto-schedule backups
27
+ * await manager.backupNow(); // Manual backup
28
+ * await manager.restore('backups/db-2024-01-15.json.gz');
29
+ * ```
30
+ *
31
+ * @module cloudBackup
32
+ */
33
+ import type { StorageAdapter } from '../../core/contracts/index.js';
34
+ /** Supported backup export formats */
35
+ export type BackupFormat = 'json' | 'sql';
36
+ /** Supported compression algorithms */
37
+ export type CompressionType = 'gzip' | 'none';
38
+ /**
39
+ * Generic interface for cloud storage providers.
40
+ *
41
+ * Implement this interface to support custom storage backends
42
+ * beyond S3-compatible services.
43
+ */
44
+ export interface CloudStorageProvider {
45
+ /**
46
+ * Upload data to cloud storage
47
+ * @param key - The storage key/path for the backup
48
+ * @param data - The backup data (string or Buffer)
49
+ */
50
+ upload(key: string, data: string | Buffer): Promise<void>;
51
+ /**
52
+ * Download data from cloud storage
53
+ * @param key - The storage key/path to download
54
+ * @returns The backup data
55
+ */
56
+ download(key: string): Promise<string | Buffer>;
57
+ /**
58
+ * List available backups in cloud storage
59
+ * @param prefix - Optional prefix to filter backups
60
+ * @returns Array of backup keys
61
+ */
62
+ list(prefix?: string): Promise<string[]>;
63
+ /**
64
+ * Delete a backup from cloud storage
65
+ * @param key - The storage key/path to delete
66
+ */
67
+ delete(key: string): Promise<void>;
68
+ }
69
+ /**
70
+ * Configuration options for backup creation
71
+ */
72
+ export interface BackupOptions {
73
+ /** Backup format (json or sql) - default: 'json' */
74
+ format?: BackupFormat;
75
+ /** Compression type - default: 'gzip' */
76
+ compression?: CompressionType;
77
+ /** Tables to include (undefined = all tables) */
78
+ tables?: string[];
79
+ /** Prefix for backup keys - default: 'backups/' */
80
+ prefix?: string;
81
+ /** Include timestamp in backup key - default: true */
82
+ includeTimestamp?: boolean;
83
+ }
84
+ /**
85
+ * Configuration for automatic scheduled backups
86
+ */
87
+ export interface ScheduledBackupConfig {
88
+ /** Backup interval in milliseconds (e.g., 3600000 = 1 hour) */
89
+ interval: number;
90
+ /** Maximum number of backups to keep (older backups auto-deleted) */
91
+ maxBackups?: number;
92
+ /** Backup creation options */
93
+ options?: BackupOptions;
94
+ /** Callback invoked on successful backup */
95
+ onSuccess?: (key: string) => void;
96
+ /** Callback invoked on backup error */
97
+ onError?: (error: Error) => void;
98
+ }
99
+ /**
100
+ * S3-compatible cloud storage provider.
101
+ *
102
+ * Works with AWS S3, Cloudflare R2, MinIO, and other S3-compatible services.
103
+ * Uses the AWS SDK v3 for S3 operations.
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * import { S3Client } from '@aws-sdk/client-s3';
108
+ *
109
+ * const s3Client = new S3Client({ region: 'us-east-1' });
110
+ * const provider = new S3StorageProvider(s3Client, 'my-bucket');
111
+ *
112
+ * await provider.upload('backups/test.json', JSON.stringify(data));
113
+ * const backups = await provider.list('backups/');
114
+ * ```
115
+ */
116
+ export declare class S3StorageProvider implements CloudStorageProvider {
117
+ private client;
118
+ private bucket;
119
+ /**
120
+ * @param client - AWS SDK S3Client instance
121
+ * @param bucket - S3 bucket name
122
+ */
123
+ constructor(client: {
124
+ send: (command: unknown) => Promise<unknown>;
125
+ }, bucket: string);
126
+ upload(key: string, data: string | Buffer): Promise<void>;
127
+ download(key: string): Promise<string>;
128
+ list(prefix?: string): Promise<string[]>;
129
+ delete(key: string): Promise<void>;
130
+ }
131
+ /**
132
+ * Cloud backup manager for automatic scheduled backups.
133
+ */
134
+ export declare class CloudBackupManager {
135
+ private adapter;
136
+ private storage;
137
+ private config;
138
+ private intervalId?;
139
+ constructor(adapter: StorageAdapter, storage: CloudStorageProvider, config: ScheduledBackupConfig);
140
+ /**
141
+ * Create a backup and upload to cloud storage.
142
+ */
143
+ backup(options?: BackupOptions): Promise<string>;
144
+ /**
145
+ * Restore from a cloud backup.
146
+ */
147
+ restore(key: string): Promise<void>;
148
+ /**
149
+ * List all backups in cloud storage.
150
+ */
151
+ listBackups(prefix?: string): Promise<string[]>;
152
+ /**
153
+ * Delete old backups exceeding maxBackups limit.
154
+ */
155
+ private cleanupOldBackups;
156
+ /**
157
+ * Start automatic scheduled backups.
158
+ */
159
+ start(): void;
160
+ /**
161
+ * Stop automatic scheduled backups.
162
+ */
163
+ stop(): void;
164
+ /**
165
+ * Perform a backup immediately (manual trigger).
166
+ */
167
+ backupNow(options?: BackupOptions): Promise<string>;
168
+ }
169
+ /**
170
+ * Create a cloud backup manager with S3-compatible storage.
171
+ *
172
+ * This is the main factory function for setting up cloud backups.
173
+ * It creates an S3StorageProvider and CloudBackupManager configured
174
+ * with your database and S3-compatible storage.
175
+ *
176
+ * @param adapter - The StorageAdapter instance to backup
177
+ * @param s3Client - AWS SDK S3Client (works with S3, R2, MinIO, etc.)
178
+ * @param bucket - The S3 bucket name
179
+ * @param config - Scheduled backup configuration
180
+ * @returns CloudBackupManager instance ready to start
181
+ *
182
+ * @example AWS S3
183
+ * ```typescript
184
+ * import { S3Client } from '@aws-sdk/client-s3';
185
+ * import { createCloudBackupManager } from '@framers/sql-storage-adapter';
186
+ *
187
+ * const s3 = new S3Client({ region: 'us-east-1' });
188
+ * const manager = createCloudBackupManager(db, s3, 'my-bucket', {
189
+ * interval: 60 * 60 * 1000, // 1 hour
190
+ * maxBackups: 24,
191
+ * options: { compression: 'gzip' }
192
+ * });
193
+ *
194
+ * manager.start();
195
+ * ```
196
+ *
197
+ * @example Cloudflare R2
198
+ * ```typescript
199
+ * import { S3Client } from '@aws-sdk/client-s3';
200
+ *
201
+ * const r2 = new S3Client({
202
+ * region: 'auto',
203
+ * endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
204
+ * credentials: {
205
+ * accessKeyId: process.env.R2_ACCESS_KEY_ID,
206
+ * secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
207
+ * },
208
+ * });
209
+ *
210
+ * const manager = createCloudBackupManager(db, r2, 'backups', {
211
+ * interval: 24 * 60 * 60 * 1000, // Daily
212
+ * maxBackups: 7
213
+ * });
214
+ * ```
215
+ */
216
+ export declare function createCloudBackupManager(adapter: StorageAdapter, s3Client: {
217
+ send: (command: unknown) => Promise<unknown>;
218
+ }, bucket: string, config: ScheduledBackupConfig): CloudBackupManager;
219
+ //# sourceMappingURL=cloudBackup.d.ts.map
@@ -0,0 +1,209 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var cloudBackup_exports = {};
29
+ __export(cloudBackup_exports, {
30
+ CloudBackupManager: () => CloudBackupManager,
31
+ S3StorageProvider: () => S3StorageProvider,
32
+ createCloudBackupManager: () => createCloudBackupManager
33
+ });
34
+ module.exports = __toCommonJS(cloudBackup_exports);
35
+ var import_dataExport = require("../migrations/dataExport.js");
36
+ var import_dataImport = require("../migrations/dataImport.js");
37
+ class S3StorageProvider {
38
+ /**
39
+ * @param client - AWS SDK S3Client instance
40
+ * @param bucket - S3 bucket name
41
+ */
42
+ constructor(client, bucket) {
43
+ this.client = client;
44
+ this.bucket = bucket;
45
+ }
46
+ async upload(key, data) {
47
+ const { PutObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
48
+ await this.client.send(new PutObjectCommand({
49
+ Bucket: this.bucket,
50
+ Key: key,
51
+ Body: data
52
+ }));
53
+ }
54
+ async download(key) {
55
+ const { GetObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
56
+ const response = await this.client.send(new GetObjectCommand({
57
+ Bucket: this.bucket,
58
+ Key: key
59
+ }));
60
+ if (response.Body.transformToString) {
61
+ return await response.Body.transformToString();
62
+ }
63
+ return response.Body.toString("utf-8");
64
+ }
65
+ async list(prefix) {
66
+ const { ListObjectsV2Command } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
67
+ const response = await this.client.send(new ListObjectsV2Command({
68
+ Bucket: this.bucket,
69
+ Prefix: prefix
70
+ }));
71
+ return response.Contents?.map((obj) => obj.Key).filter((key) => !!key) ?? [];
72
+ }
73
+ async delete(key) {
74
+ const { DeleteObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
75
+ await this.client.send(new DeleteObjectCommand({
76
+ Bucket: this.bucket,
77
+ Key: key
78
+ }));
79
+ }
80
+ }
81
+ async function compress(data) {
82
+ const { gzip } = await Promise.resolve().then(() => __toESM(require("zlib")));
83
+ const { promisify } = await Promise.resolve().then(() => __toESM(require("util")));
84
+ const gzipAsync = promisify(gzip);
85
+ return await gzipAsync(Buffer.from(data));
86
+ }
87
+ async function decompress(data) {
88
+ const { gunzip } = await Promise.resolve().then(() => __toESM(require("zlib")));
89
+ const { promisify } = await Promise.resolve().then(() => __toESM(require("util")));
90
+ const gunzipAsync = promisify(gunzip);
91
+ const decompressed = await gunzipAsync(data);
92
+ return decompressed.toString("utf-8");
93
+ }
94
+ class CloudBackupManager {
95
+ constructor(adapter, storage, config) {
96
+ this.adapter = adapter;
97
+ this.storage = storage;
98
+ this.config = config;
99
+ }
100
+ /**
101
+ * Create a backup and upload to cloud storage.
102
+ */
103
+ async backup(options = {}) {
104
+ const format = options.format ?? this.config.options?.format ?? "json";
105
+ const compression = options.compression ?? this.config.options?.compression ?? "none";
106
+ const tables = options.tables ?? this.config.options?.tables;
107
+ const prefix = options.prefix ?? this.config.options?.prefix ?? "backups/";
108
+ const includeTimestamp = options.includeTimestamp ?? this.config.options?.includeTimestamp ?? true;
109
+ let data;
110
+ if (format === "json") {
111
+ data = await (0, import_dataExport.exportAsJSON)(this.adapter, { tables });
112
+ } else {
113
+ data = await (0, import_dataExport.exportAsSQL)(this.adapter, { tables });
114
+ }
115
+ let uploadData = data;
116
+ if (compression === "gzip") {
117
+ uploadData = await compress(data);
118
+ }
119
+ const timestamp = includeTimestamp ? `-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}` : "";
120
+ const ext = format === "json" ? "json" : "sql";
121
+ const compExt = compression === "gzip" ? ".gz" : "";
122
+ const key = `${prefix}backup${timestamp}.${ext}${compExt}`;
123
+ await this.storage.upload(key, uploadData);
124
+ if (this.config.maxBackups) {
125
+ await this.cleanupOldBackups(prefix);
126
+ }
127
+ return key;
128
+ }
129
+ /**
130
+ * Restore from a cloud backup.
131
+ */
132
+ async restore(key) {
133
+ const data = await this.storage.download(key);
134
+ let restored;
135
+ if (key.endsWith(".gz")) {
136
+ restored = await decompress(Buffer.from(data));
137
+ } else {
138
+ restored = typeof data === "string" ? data : data.toString("utf-8");
139
+ }
140
+ if (key.includes(".json")) {
141
+ await (0, import_dataImport.importFromJSON)(this.adapter, restored);
142
+ } else {
143
+ await (0, import_dataImport.importFromSQL)(this.adapter, restored);
144
+ }
145
+ }
146
+ /**
147
+ * List all backups in cloud storage.
148
+ */
149
+ async listBackups(prefix) {
150
+ const searchPrefix = prefix ?? this.config.options?.prefix ?? "backups/";
151
+ return await this.storage.list(searchPrefix);
152
+ }
153
+ /**
154
+ * Delete old backups exceeding maxBackups limit.
155
+ */
156
+ async cleanupOldBackups(prefix) {
157
+ if (!this.config.maxBackups)
158
+ return;
159
+ const backups = await this.storage.list(prefix);
160
+ if (backups.length <= this.config.maxBackups)
161
+ return;
162
+ const sorted = backups.sort();
163
+ const toDelete = sorted.slice(0, backups.length - this.config.maxBackups);
164
+ for (const key of toDelete) {
165
+ await this.storage.delete(key);
166
+ }
167
+ }
168
+ /**
169
+ * Start automatic scheduled backups.
170
+ */
171
+ start() {
172
+ if (this.intervalId) {
173
+ throw new Error("Scheduled backups already started");
174
+ }
175
+ this.intervalId = setInterval(async () => {
176
+ try {
177
+ const key = await this.backup();
178
+ this.config.onSuccess?.(key);
179
+ } catch (error) {
180
+ this.config.onError?.(error);
181
+ }
182
+ }, this.config.interval);
183
+ }
184
+ /**
185
+ * Stop automatic scheduled backups.
186
+ */
187
+ stop() {
188
+ if (this.intervalId) {
189
+ clearInterval(this.intervalId);
190
+ this.intervalId = void 0;
191
+ }
192
+ }
193
+ /**
194
+ * Perform a backup immediately (manual trigger).
195
+ */
196
+ async backupNow(options) {
197
+ return await this.backup(options);
198
+ }
199
+ }
200
+ function createCloudBackupManager(adapter, s3Client, bucket, config) {
201
+ const storage = new S3StorageProvider(s3Client, bucket);
202
+ return new CloudBackupManager(adapter, storage, config);
203
+ }
204
+ // Annotate the CommonJS export names for ESM import in node:
205
+ 0 && (module.exports = {
206
+ CloudBackupManager,
207
+ S3StorageProvider,
208
+ createCloudBackupManager
209
+ });