bunderstack 0.17.0-beta.2 → 0.17.0-beta.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 (336) hide show
  1. package/CHANGELOG.md +227 -0
  2. package/README.md +11 -1
  3. package/dist/access.d.ts +116 -0
  4. package/dist/access.d.ts.map +1 -0
  5. package/dist/access.js +325 -0
  6. package/dist/access.js.map +1 -0
  7. package/dist/api/builder.d.ts +145 -0
  8. package/dist/api/builder.d.ts.map +1 -0
  9. package/dist/api/builder.js +28 -0
  10. package/dist/api/builder.js.map +1 -0
  11. package/dist/api/context.d.ts +34 -0
  12. package/dist/api/context.d.ts.map +1 -0
  13. package/dist/api/context.js +32 -0
  14. package/dist/api/context.js.map +1 -0
  15. package/dist/api/crud-router.d.ts +290 -0
  16. package/dist/api/crud-router.d.ts.map +1 -0
  17. package/dist/api/crud-router.js +249 -0
  18. package/dist/api/crud-router.js.map +1 -0
  19. package/dist/api/openapi.d.ts +6 -0
  20. package/dist/api/openapi.d.ts.map +1 -0
  21. package/dist/api/openapi.js +146 -0
  22. package/dist/api/openapi.js.map +1 -0
  23. package/dist/api/realtime-router.d.ts +76 -0
  24. package/dist/api/realtime-router.d.ts.map +1 -0
  25. package/dist/api/realtime-router.js +41 -0
  26. package/dist/api/realtime-router.js.map +1 -0
  27. package/dist/api/registry.d.ts +30 -0
  28. package/dist/api/registry.d.ts.map +1 -0
  29. package/dist/api/registry.js +239 -0
  30. package/dist/api/registry.js.map +1 -0
  31. package/dist/api/router.d.ts +9 -0
  32. package/dist/api/router.d.ts.map +1 -0
  33. package/dist/api/router.js +19 -0
  34. package/dist/api/router.js.map +1 -0
  35. package/dist/api/storage-router.d.ts +279 -0
  36. package/dist/api/storage-router.d.ts.map +1 -0
  37. package/dist/api/storage-router.js +155 -0
  38. package/dist/api/storage-router.js.map +1 -0
  39. package/dist/api/types.d.ts +55 -0
  40. package/dist/api/types.d.ts.map +1 -0
  41. package/dist/api/types.js +2 -0
  42. package/dist/api/types.js.map +1 -0
  43. package/dist/auth.d.ts +31 -0
  44. package/dist/auth.d.ts.map +1 -0
  45. package/dist/auth.js +102 -0
  46. package/dist/auth.js.map +1 -0
  47. package/dist/blueprint-generator.d.ts +18 -0
  48. package/dist/blueprint-generator.d.ts.map +1 -0
  49. package/dist/blueprint-generator.js +125 -0
  50. package/dist/blueprint-generator.js.map +1 -0
  51. package/dist/blueprint.d.ts +46 -0
  52. package/dist/blueprint.d.ts.map +1 -0
  53. package/dist/blueprint.js +162 -0
  54. package/dist/blueprint.js.map +1 -0
  55. package/dist/cli.d.ts +8 -0
  56. package/dist/cli.d.ts.map +1 -0
  57. package/dist/cli.js +68 -0
  58. package/dist/cli.js.map +1 -0
  59. package/dist/config.d.ts +76 -0
  60. package/dist/config.d.ts.map +1 -0
  61. package/dist/config.js +81 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/cron.d.ts +4 -0
  64. package/dist/cron.d.ts.map +1 -0
  65. package/dist/cron.js +3 -0
  66. package/dist/cron.js.map +1 -0
  67. package/dist/crud-operations.d.ts +43 -0
  68. package/dist/crud-operations.d.ts.map +1 -0
  69. package/dist/crud-operations.js +238 -0
  70. package/dist/crud-operations.js.map +1 -0
  71. package/dist/database/adapter.d.ts +20 -0
  72. package/dist/database/adapter.d.ts.map +1 -0
  73. package/dist/database/adapter.js +2 -0
  74. package/dist/database/adapter.js.map +1 -0
  75. package/dist/database/bun-sql.d.ts +3 -0
  76. package/dist/database/bun-sql.d.ts.map +1 -0
  77. package/dist/database/bun-sql.js +21 -0
  78. package/dist/database/bun-sql.js.map +1 -0
  79. package/dist/database/libsql.d.ts +3 -0
  80. package/dist/database/libsql.d.ts.map +1 -0
  81. package/dist/database/libsql.js +22 -0
  82. package/dist/database/libsql.js.map +1 -0
  83. package/dist/database/pglite.d.ts +3 -0
  84. package/dist/database/pglite.d.ts.map +1 -0
  85. package/dist/database/pglite.js +27 -0
  86. package/dist/database/pglite.js.map +1 -0
  87. package/dist/database/postgres-js.d.ts +3 -0
  88. package/dist/database/postgres-js.d.ts.map +1 -0
  89. package/dist/database/postgres-js.js +21 -0
  90. package/dist/database/postgres-js.js.map +1 -0
  91. package/dist/db.d.ts +18 -0
  92. package/dist/db.d.ts.map +1 -0
  93. package/dist/db.js +26 -0
  94. package/dist/db.js.map +1 -0
  95. package/dist/dialect.d.ts +17 -0
  96. package/dist/dialect.d.ts.map +1 -0
  97. package/dist/dialect.js +22 -0
  98. package/dist/dialect.js.map +1 -0
  99. package/dist/email/smtp.d.ts +14 -0
  100. package/dist/email/smtp.d.ts.map +1 -0
  101. package/dist/email/smtp.js +27 -0
  102. package/dist/email/smtp.js.map +1 -0
  103. package/dist/email.d.ts +39 -0
  104. package/dist/email.d.ts.map +1 -0
  105. package/dist/email.js +97 -0
  106. package/dist/email.js.map +1 -0
  107. package/dist/env.d.ts +47 -0
  108. package/dist/env.d.ts.map +1 -0
  109. package/dist/env.js +99 -0
  110. package/dist/env.js.map +1 -0
  111. package/dist/errors.d.ts +125 -0
  112. package/dist/errors.d.ts.map +1 -0
  113. package/dist/errors.js +92 -0
  114. package/dist/errors.js.map +1 -0
  115. package/dist/handler.d.ts +9 -0
  116. package/dist/handler.d.ts.map +1 -0
  117. package/dist/handler.js +22 -0
  118. package/dist/handler.js.map +1 -0
  119. package/dist/idempotency.d.ts +17 -0
  120. package/dist/idempotency.d.ts.map +1 -0
  121. package/dist/idempotency.js +65 -0
  122. package/dist/idempotency.js.map +1 -0
  123. package/dist/index.d.ts +134 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +477 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/internal-tables-pg.d.ts +481 -0
  128. package/dist/internal-tables-pg.d.ts.map +1 -0
  129. package/{src/internal-tables-pg.ts → dist/internal-tables-pg.js} +10 -34
  130. package/dist/internal-tables-pg.js.map +1 -0
  131. package/dist/internal-tables.d.ts +2509 -0
  132. package/dist/internal-tables.d.ts.map +1 -0
  133. package/dist/internal-tables.js +108 -0
  134. package/dist/internal-tables.js.map +1 -0
  135. package/dist/jobs/cron.d.ts +15 -0
  136. package/dist/jobs/cron.d.ts.map +1 -0
  137. package/dist/jobs/cron.js +74 -0
  138. package/dist/jobs/cron.js.map +1 -0
  139. package/dist/jobs/define.d.ts +133 -0
  140. package/dist/jobs/define.d.ts.map +1 -0
  141. package/dist/jobs/define.js +74 -0
  142. package/dist/jobs/define.js.map +1 -0
  143. package/dist/jobs/index.d.ts +11 -0
  144. package/dist/jobs/index.d.ts.map +1 -0
  145. package/dist/jobs/index.js +8 -0
  146. package/dist/jobs/index.js.map +1 -0
  147. package/dist/jobs/queue.d.ts +6 -0
  148. package/dist/jobs/queue.d.ts.map +1 -0
  149. package/dist/jobs/queue.js +55 -0
  150. package/dist/jobs/queue.js.map +1 -0
  151. package/dist/jobs/runtime.d.ts +13 -0
  152. package/dist/jobs/runtime.d.ts.map +1 -0
  153. package/dist/jobs/runtime.js +46 -0
  154. package/dist/jobs/runtime.js.map +1 -0
  155. package/dist/jobs/slots.d.ts +25 -0
  156. package/dist/jobs/slots.d.ts.map +1 -0
  157. package/dist/jobs/slots.js +41 -0
  158. package/dist/jobs/slots.js.map +1 -0
  159. package/dist/jobs/worker.d.ts +12 -0
  160. package/dist/jobs/worker.d.ts.map +1 -0
  161. package/dist/jobs/worker.js +311 -0
  162. package/dist/jobs/worker.js.map +1 -0
  163. package/dist/lifecycle.d.ts +10 -0
  164. package/dist/lifecycle.d.ts.map +1 -0
  165. package/dist/lifecycle.js +37 -0
  166. package/dist/lifecycle.js.map +1 -0
  167. package/dist/list-query.d.ts +62 -0
  168. package/dist/list-query.d.ts.map +1 -0
  169. package/dist/list-query.js +194 -0
  170. package/dist/list-query.js.map +1 -0
  171. package/dist/manifest.d.ts +59 -0
  172. package/dist/manifest.d.ts.map +1 -0
  173. package/dist/manifest.js +167 -0
  174. package/dist/manifest.js.map +1 -0
  175. package/dist/provision-internals.d.ts +24 -0
  176. package/dist/provision-internals.d.ts.map +1 -0
  177. package/dist/provision-internals.js +7 -0
  178. package/dist/provision-internals.js.map +1 -0
  179. package/dist/provision.d.ts +23 -0
  180. package/dist/provision.d.ts.map +1 -0
  181. package/dist/provision.js +96 -0
  182. package/dist/provision.js.map +1 -0
  183. package/dist/rate-limit.d.ts +7 -0
  184. package/dist/rate-limit.d.ts.map +1 -0
  185. package/dist/rate-limit.js +49 -0
  186. package/dist/rate-limit.js.map +1 -0
  187. package/dist/realtime/facade.d.ts +18 -0
  188. package/dist/realtime/facade.d.ts.map +1 -0
  189. package/dist/realtime/facade.js +36 -0
  190. package/dist/realtime/facade.js.map +1 -0
  191. package/dist/realtime/filter.d.ts +13 -0
  192. package/dist/realtime/filter.d.ts.map +1 -0
  193. package/dist/realtime/filter.js +48 -0
  194. package/dist/realtime/filter.js.map +1 -0
  195. package/dist/realtime/heartbeat.d.ts +14 -0
  196. package/dist/realtime/heartbeat.d.ts.map +1 -0
  197. package/dist/realtime/heartbeat.js +64 -0
  198. package/dist/realtime/heartbeat.js.map +1 -0
  199. package/dist/realtime/publisher.d.ts +21 -0
  200. package/dist/realtime/publisher.d.ts.map +1 -0
  201. package/dist/realtime/publisher.js +17 -0
  202. package/dist/realtime/publisher.js.map +1 -0
  203. package/dist/schema-export-pg.d.ts +2 -0
  204. package/dist/schema-export-pg.d.ts.map +1 -0
  205. package/dist/schema-export-pg.js +4 -0
  206. package/dist/schema-export-pg.js.map +1 -0
  207. package/dist/schema-export.d.ts +2 -0
  208. package/dist/schema-export.d.ts.map +1 -0
  209. package/dist/schema-export.js +2 -0
  210. package/dist/schema-export.js.map +1 -0
  211. package/dist/scope.d.ts +4 -0
  212. package/dist/scope.d.ts.map +1 -0
  213. package/dist/scope.js +13 -0
  214. package/dist/scope.js.map +1 -0
  215. package/dist/standard-schema.d.ts +13 -0
  216. package/dist/standard-schema.d.ts.map +1 -0
  217. package/dist/standard-schema.js +34 -0
  218. package/dist/standard-schema.js.map +1 -0
  219. package/dist/storage/buckets.d.ts +80 -0
  220. package/dist/storage/buckets.d.ts.map +1 -0
  221. package/dist/storage/buckets.js +178 -0
  222. package/dist/storage/buckets.js.map +1 -0
  223. package/dist/storage/delete.d.ts +11 -0
  224. package/dist/storage/delete.d.ts.map +1 -0
  225. package/dist/storage/delete.js +18 -0
  226. package/dist/storage/delete.js.map +1 -0
  227. package/dist/storage/file-meta.d.ts +37 -0
  228. package/dist/storage/file-meta.d.ts.map +1 -0
  229. package/dist/storage/file-meta.js +166 -0
  230. package/dist/storage/file-meta.js.map +1 -0
  231. package/dist/storage/index.d.ts +28 -0
  232. package/dist/storage/index.d.ts.map +1 -0
  233. package/dist/storage/index.js +5 -0
  234. package/dist/storage/index.js.map +1 -0
  235. package/dist/storage/local.d.ts +15 -0
  236. package/dist/storage/local.d.ts.map +1 -0
  237. package/dist/storage/local.js +56 -0
  238. package/dist/storage/local.js.map +1 -0
  239. package/dist/storage/operations.d.ts +54 -0
  240. package/dist/storage/operations.d.ts.map +1 -0
  241. package/dist/storage/operations.js +250 -0
  242. package/dist/storage/operations.js.map +1 -0
  243. package/dist/storage/registry.d.ts +10 -0
  244. package/dist/storage/registry.d.ts.map +1 -0
  245. package/dist/storage/registry.js +23 -0
  246. package/dist/storage/registry.js.map +1 -0
  247. package/dist/storage/s3.d.ts +28 -0
  248. package/dist/storage/s3.d.ts.map +1 -0
  249. package/dist/storage/s3.js +71 -0
  250. package/dist/storage/s3.js.map +1 -0
  251. package/dist/storage/sweep.d.ts +9 -0
  252. package/dist/storage/sweep.d.ts.map +1 -0
  253. package/dist/storage/sweep.js +17 -0
  254. package/dist/storage/sweep.js.map +1 -0
  255. package/dist/storage/thumbnails.d.ts +11 -0
  256. package/dist/storage/thumbnails.d.ts.map +1 -0
  257. package/dist/storage/thumbnails.js +60 -0
  258. package/dist/storage/thumbnails.js.map +1 -0
  259. package/dist/testing.d.ts +27 -0
  260. package/dist/testing.d.ts.map +1 -0
  261. package/dist/testing.js +11 -0
  262. package/dist/testing.js.map +1 -0
  263. package/dist/typeid-pg.d.ts +19 -0
  264. package/dist/typeid-pg.d.ts.map +1 -0
  265. package/{src/typeid-pg.ts → dist/typeid-pg.js} +10 -13
  266. package/dist/typeid-pg.js.map +1 -0
  267. package/dist/typeid.d.ts +45 -0
  268. package/dist/typeid.d.ts.map +1 -0
  269. package/dist/typeid.js +100 -0
  270. package/dist/typeid.js.map +1 -0
  271. package/package.json +77 -28
  272. package/src/access.ts +0 -532
  273. package/src/api/builder.ts +0 -52
  274. package/src/api/context.ts +0 -83
  275. package/src/api/crud-router.ts +0 -386
  276. package/src/api/openapi.ts +0 -184
  277. package/src/api/realtime-router.ts +0 -75
  278. package/src/api/registry.ts +0 -338
  279. package/src/api/router.ts +0 -34
  280. package/src/api/storage-router.ts +0 -224
  281. package/src/api/types.ts +0 -105
  282. package/src/auth.ts +0 -117
  283. package/src/blueprint-generator.ts +0 -203
  284. package/src/blueprint.ts +0 -264
  285. package/src/cli.ts +0 -90
  286. package/src/config.ts +0 -215
  287. package/src/cron.ts +0 -3
  288. package/src/crud-operations.ts +0 -478
  289. package/src/database/adapter.ts +0 -26
  290. package/src/database/bun-sql.ts +0 -23
  291. package/src/database/libsql.ts +0 -28
  292. package/src/database/pglite.ts +0 -33
  293. package/src/database/postgres-js.ts +0 -33
  294. package/src/db.ts +0 -61
  295. package/src/dialect.ts +0 -38
  296. package/src/email/smtp.ts +0 -45
  297. package/src/email.ts +0 -154
  298. package/src/env.ts +0 -180
  299. package/src/errors.ts +0 -123
  300. package/src/handler.ts +0 -30
  301. package/src/idempotency.ts +0 -97
  302. package/src/index.ts +0 -834
  303. package/src/internal-tables.ts +0 -149
  304. package/src/jobs/cron.ts +0 -87
  305. package/src/jobs/define.ts +0 -283
  306. package/src/jobs/index.ts +0 -37
  307. package/src/jobs/queue.ts +0 -67
  308. package/src/jobs/runtime.ts +0 -58
  309. package/src/jobs/slots.ts +0 -52
  310. package/src/jobs/worker.ts +0 -369
  311. package/src/lifecycle.ts +0 -49
  312. package/src/list-query.ts +0 -333
  313. package/src/manifest.ts +0 -297
  314. package/src/provision-internals.ts +0 -29
  315. package/src/provision.ts +0 -128
  316. package/src/rate-limit.ts +0 -71
  317. package/src/realtime/facade.ts +0 -74
  318. package/src/realtime/filter.ts +0 -81
  319. package/src/realtime/heartbeat.ts +0 -80
  320. package/src/realtime/publisher.ts +0 -46
  321. package/src/schema-export-pg.ts +0 -7
  322. package/src/schema-export.ts +0 -5
  323. package/src/scope.ts +0 -17
  324. package/src/standard-schema.ts +0 -59
  325. package/src/storage/buckets.ts +0 -308
  326. package/src/storage/delete.ts +0 -26
  327. package/src/storage/file-meta.ts +0 -222
  328. package/src/storage/index.ts +0 -39
  329. package/src/storage/local.ts +0 -69
  330. package/src/storage/operations.ts +0 -398
  331. package/src/storage/registry.ts +0 -40
  332. package/src/storage/s3.ts +0 -99
  333. package/src/storage/sweep.ts +0 -25
  334. package/src/storage/thumbnails.ts +0 -65
  335. package/src/testing.ts +0 -31
  336. package/src/typeid.ts +0 -116
@@ -0,0 +1,76 @@
1
+ import { betterAuth } from 'better-auth';
2
+ import type { AnyRouter } from '@orpc/server';
3
+ import type { AuthSessionResolver, TableAccessInput } from './access.js';
4
+ import type { BunderstackApiBuilder } from './api/builder.js';
5
+ import type { DatabaseAdapter } from './database/adapter.js';
6
+ import type { EmailConfigInput } from './email.js';
7
+ import type { IdempotencyConfig } from './idempotency.js';
8
+ import type { RateLimitConfig } from './rate-limit.js';
9
+ import { type BaseEnv, type EnvConfigInput, type ValidatedEnv } from './env.js';
10
+ import { type ResolvedStorageBuckets, type StorageConfigInput } from './storage/buckets.js';
11
+ export type BetterAuthConfig = Omit<NonNullable<Parameters<typeof betterAuth>[0]>, 'database'>;
12
+ export type BunderstackConfig<TSchema extends Record<string, unknown>, TAccess extends Record<string, TableAccessInput> | undefined = Record<string, TableAccessInput> | undefined, TStorage extends StorageConfigInput | undefined = StorageConfigInput | undefined, TEnv extends EnvConfigInput | undefined = EnvConfigInput | undefined, TCustomApiRouter extends AnyRouter | undefined = AnyRouter | undefined> = {
13
+ schema: TSchema;
14
+ access?: TAccess;
15
+ database: {
16
+ adapter: DatabaseAdapter;
17
+ url?: string;
18
+ authToken?: string;
19
+ migrations?: string;
20
+ };
21
+ auth?: BetterAuthConfig;
22
+ /**
23
+ * Reuse an application-owned session reader for the unified API while
24
+ * keeping Bunderstack's auth handler available.
25
+ */
26
+ authResolver?: AuthSessionResolver;
27
+ storage?: TStorage;
28
+ env?: TEnv;
29
+ /**
30
+ * Stand-in for `process.env`. Feeds both env validation and platform
31
+ * overrides, so tests and embedders have one injection point instead of
32
+ * three.
33
+ */
34
+ processEnv?: Record<string, string | undefined>;
35
+ background?: {
36
+ autoStart?: boolean;
37
+ };
38
+ email?: EmailConfigInput;
39
+ /**
40
+ * Unified oRPC API builder callback.
41
+ */
42
+ api?: (builder: BunderstackApiBuilder<TSchema, ValidatedEnv<TEnv>>) => TCustomApiRouter;
43
+ rateLimit?: boolean | RateLimitConfig;
44
+ idempotency?: boolean | IdempotencyConfig;
45
+ /** Generate and serve `/api/openapi.json`. Disabled by default. */
46
+ openapi?: boolean;
47
+ realtime?: boolean | {
48
+ bufferSize?: number;
49
+ resumeSeconds?: number;
50
+ redis?: string | {
51
+ url: string;
52
+ token?: string;
53
+ };
54
+ };
55
+ };
56
+ export type ResolvedConfig = {
57
+ database: {
58
+ adapter: DatabaseAdapter;
59
+ url: string;
60
+ authToken?: string;
61
+ migrations: string;
62
+ };
63
+ auth: BetterAuthConfig;
64
+ storage: ResolvedStorageBuckets;
65
+ realtime?: boolean | {
66
+ bufferSize?: number;
67
+ resumeSeconds?: number;
68
+ redis?: string | {
69
+ url: string;
70
+ token?: string;
71
+ };
72
+ };
73
+ };
74
+ export declare function resolveConfig<TSchema extends Record<string, unknown>, TAccess extends Record<string, TableAccessInput> | undefined = undefined, TStorage extends StorageConfigInput | undefined = undefined, TEnv extends EnvConfigInput | undefined = undefined, TCustomApiRouter extends AnyRouter | undefined = undefined>(options: BunderstackConfig<TSchema, TAccess, TStorage, TEnv, TCustomApiRouter>, env?: BaseEnv, platformSource?: Record<string, string | undefined>): ResolvedConfig;
75
+ export declare function resolveRealtimeRedisUrl(realtime: ResolvedConfig['realtime'], env?: BaseEnv, platformSource?: Record<string, string | undefined>): string | undefined;
76
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,81 @@
1
+ // src/config.ts
2
+ import { betterAuth } from 'better-auth';
3
+ import * as v from 'valibot';
4
+ import { validateEnv } from './env.js';
5
+ import { resolveBuckets, } from './storage/buckets.js';
6
+ // Only the union-shaped options need runtime validation: they are the ones a
7
+ // JavaScript caller can plausibly get wrong in a way that fails confusingly
8
+ // downstream. Everything else is either typed-only or read raw from `options`.
9
+ const RuntimeOptionsSchema = v.object({
10
+ rateLimit: v.optional(v.union([
11
+ v.boolean(),
12
+ v.object({
13
+ windowMs: v.optional(v.number()),
14
+ max: v.optional(v.number()),
15
+ }),
16
+ ])),
17
+ idempotency: v.optional(v.union([v.boolean(), v.object({ ttlMs: v.optional(v.number()) })])),
18
+ realtime: v.optional(v.union([
19
+ v.boolean(),
20
+ v.object({
21
+ bufferSize: v.optional(v.number()),
22
+ resumeSeconds: v.optional(v.number()),
23
+ redis: v.optional(v.union([
24
+ v.string(),
25
+ v.object({ url: v.string(), token: v.optional(v.string()) }),
26
+ ])),
27
+ }),
28
+ ])),
29
+ openapi: v.optional(v.boolean()),
30
+ });
31
+ export function resolveConfig(options, env,
32
+ // Platform-injected overrides (Bunderhost & co.) beat code-level config so
33
+ // apps with hardcoded local urls deploy unchanged.
34
+ platformSource = process.env) {
35
+ const parsed = v.parse(RuntimeOptionsSchema, options);
36
+ // Self-validate when the caller didn't pass a pre-validated env, so
37
+ // resolveConfig stays usable standalone.
38
+ const resolvedEnv = env ?? validateEnv(options.env);
39
+ const adapter = options.database?.adapter;
40
+ if (!adapter) {
41
+ throw new Error('[bunderstack] database.adapter is required');
42
+ }
43
+ const defaultUrl = adapter.dialect === 'sqlite' ? 'file:./data.db' : 'file:./data.pglite';
44
+ return {
45
+ database: {
46
+ adapter,
47
+ url: platformSource['BUNDERSTACK_DATABASE_URL'] ??
48
+ options.database?.url ??
49
+ resolvedEnv.DATABASE_URL ??
50
+ defaultUrl,
51
+ authToken: platformSource['BUNDERSTACK_DATABASE_AUTH_TOKEN'] ??
52
+ options.database?.authToken ??
53
+ resolvedEnv.DATABASE_AUTH_TOKEN,
54
+ migrations: options.database?.migrations ?? './migrations',
55
+ },
56
+ auth: (() => {
57
+ const authInput = options.auth ?? {};
58
+ return {
59
+ ...authInput,
60
+ secret: authInput.secret ?? resolvedEnv.AUTH_SECRET,
61
+ };
62
+ })(),
63
+ storage: resolveBuckets(options.storage, platformSource),
64
+ realtime: parsed.realtime,
65
+ };
66
+ }
67
+ export function resolveRealtimeRedisUrl(realtime, env, platformSource = process.env) {
68
+ const platformRedis = platformSource['REDIS_URL'];
69
+ if (platformRedis)
70
+ return platformRedis;
71
+ const envRedis = env?.REDIS_URL;
72
+ if (envRedis)
73
+ return envRedis;
74
+ const fromConfig = typeof realtime === 'object' && realtime.redis
75
+ ? typeof realtime.redis === 'string'
76
+ ? realtime.redis
77
+ : realtime.redis.url
78
+ : undefined;
79
+ return fromConfig ?? undefined;
80
+ }
81
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/cron.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { cronMatches, parseCron } from './jobs/cron.js';
2
+ export { floorSlot, slotsDue, CRON_PREFIX, SLOT_MS } from './jobs/slots.js';
3
+ export type { CatchUp } from './jobs/slots.js';
4
+ //# sourceMappingURL=cron.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACxE,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
package/dist/cron.js ADDED
@@ -0,0 +1,3 @@
1
+ export { cronMatches, parseCron } from './jobs/cron.js';
2
+ export { floorSlot, slotsDue, CRON_PREFIX, SLOT_MS } from './jobs/slots.js';
3
+ //# sourceMappingURL=cron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,43 @@
1
+ import type { AnyDb } from './dialect.js';
2
+ import type { RealtimeFacade } from './realtime/facade.js';
3
+ import { type AccessUser, type ResolvedAccess } from './access.js';
4
+ import { BunderstackError, type ErrorCodeValue } from './errors.js';
5
+ import { type IdempotencyConfig } from './idempotency.js';
6
+ import { type ListParamsInput, type ListResult } from './list-query.js';
7
+ export interface CrudExecutionContext {
8
+ request: Request;
9
+ user: AccessUser | null;
10
+ session: {
11
+ activeOrganizationId: string | null;
12
+ };
13
+ }
14
+ export declare class CrudOperationError extends BunderstackError {
15
+ readonly legacyCode: ErrorCodeValue;
16
+ constructor(status: number, legacyCode: ErrorCodeValue, message: string, details?: unknown);
17
+ }
18
+ export type CrudOperationsDeps<TSchema extends Record<string, unknown> = Record<string, unknown>> = {
19
+ schema: TSchema;
20
+ db: AnyDb;
21
+ access: ResolvedAccess;
22
+ idempotency?: boolean | IdempotencyConfig;
23
+ realtime?: RealtimeFacade<TSchema>;
24
+ };
25
+ export type CreateResult = {
26
+ type: 'created';
27
+ status: 201;
28
+ record: Record<string, unknown>;
29
+ } | {
30
+ type: 'replay';
31
+ status: number;
32
+ body: string;
33
+ record: Record<string, unknown>;
34
+ };
35
+ export declare function createCrudOperations<TSchema extends Record<string, unknown> = Record<string, unknown>>(deps: CrudOperationsDeps<TSchema>): {
36
+ list(tableName: string, params: ListParamsInput | undefined, ctx: CrudExecutionContext): Promise<ListResult<Record<string, unknown>>>;
37
+ get(tableName: string, rawId: string | number, ctx: CrudExecutionContext): Promise<Record<string, unknown>>;
38
+ create(tableName: string, body: unknown, rawBody: string | undefined, idempotencyKey: string | undefined, ctx: CrudExecutionContext): Promise<CreateResult>;
39
+ update(tableName: string, rawId: string | number, body: unknown, ctx: CrudExecutionContext): Promise<Record<string, unknown>>;
40
+ delete(tableName: string, rawId: string | number, ctx: CrudExecutionContext): Promise<void>;
41
+ };
42
+ export type CrudOperations = ReturnType<typeof createCrudOperations>;
43
+ //# sourceMappingURL=crud-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud-operations.d.ts","sourceRoot":"","sources":["../src/crud-operations.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,EAML,KAAK,UAAU,EACf,KAAK,cAAc,EAGpB,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,gBAAgB,EAIhB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAA;AACtB,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAGrB,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE;QAAE,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CACjD;AAYD,qBAAa,kBAAmB,SAAQ,gBAAgB;IAGpD,QAAQ,CAAC,UAAU,EAAE,cAAc;gBADnC,MAAM,EAAE,MAAM,EACL,UAAU,EAAE,cAAc,EACnC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,OAAO;CAepB;AAED,MAAM,MAAM,kBAAkB,CAC5B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC/D;IACF,MAAM,EAAE,OAAO,CAAA;IACf,EAAE,EAAE,KAAK,CAAA;IACT,MAAM,EAAE,cAAc,CAAA;IACtB,WAAW,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAA;IACzC,QAAQ,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACjE;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC,CAAA;AAyCL,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC;oBAuClB,MAAM,UACT,eAAe,GAAG,SAAS,OAC9B,oBAAoB,GACxB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;mBAqClC,MAAM,SACV,MAAM,GAAG,MAAM,OACjB,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;sBAmCtB,MAAM,QACX,OAAO,WACJ,MAAM,GAAG,SAAS,kBACX,MAAM,GAAG,SAAS,OAC7B,oBAAoB,GACxB,OAAO,CAAC,YAAY,CAAC;sBAiGX,MAAM,SACV,MAAM,GAAG,MAAM,QAChB,OAAO,OACR,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;sBAwEtB,MAAM,SACV,MAAM,GAAG,MAAM,OACjB,oBAAoB,GACxB,OAAO,CAAC,IAAI,CAAC;EAmCnB;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
@@ -0,0 +1,238 @@
1
+ import { eq, getTableColumns, getTableName, isTable, } from 'drizzle-orm';
2
+ import { checkAccess, rowMatchesScope, sanitizeWriteBody, stampScope, tableEntryForName, } from './access.js';
3
+ import { BunderstackError, ErrorCode, ListQueryError, } from './errors.js';
4
+ import { lookupIdempotency, resolveIdempotencyConfig, storeIdempotency, } from './idempotency.js';
5
+ import { executeList, resolveListParams, } from './list-query.js';
6
+ import { buildScopeWhere } from './scope.js';
7
+ function errorCodeForStatus(status) {
8
+ if (status === 401)
9
+ return 'UNAUTHORIZED';
10
+ if (status === 403)
11
+ return 'FORBIDDEN';
12
+ if (status === 404)
13
+ return 'NOT_FOUND';
14
+ if (status === 409)
15
+ return 'CONFLICT';
16
+ if (status === 413)
17
+ return 'PAYLOAD_TOO_LARGE';
18
+ if (status === 429)
19
+ return 'TOO_MANY_REQUESTS';
20
+ return 'BAD_REQUEST';
21
+ }
22
+ export class CrudOperationError extends BunderstackError {
23
+ legacyCode;
24
+ constructor(status, legacyCode, message, details) {
25
+ const code = errorCodeForStatus(status);
26
+ super(code, message, legacyCode === code
27
+ ? details
28
+ : {
29
+ code: legacyCode,
30
+ ...(details === undefined ? {} : { details }),
31
+ });
32
+ this.legacyCode = legacyCode;
33
+ this.name = 'CrudOperationError';
34
+ }
35
+ }
36
+ function isRecord(value) {
37
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
38
+ }
39
+ function isUniqueConstraintError(error) {
40
+ const seen = new Set();
41
+ let current = error;
42
+ while (isRecord(current) && !seen.has(current)) {
43
+ seen.add(current);
44
+ const code = current['code'];
45
+ if (code === '23505' ||
46
+ code === 'SQLITE_CONSTRAINT_UNIQUE' ||
47
+ code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {
48
+ return true;
49
+ }
50
+ const message = current['message'];
51
+ if (typeof message === 'string' &&
52
+ (/duplicate key value violates unique constraint/i.test(message) ||
53
+ /unique constraint failed/i.test(message))) {
54
+ return true;
55
+ }
56
+ current = current['cause'];
57
+ }
58
+ return false;
59
+ }
60
+ function coerceId(rawId) {
61
+ if (typeof rawId === 'number')
62
+ return rawId;
63
+ return isNaN(Number(rawId)) ? rawId : Number(rawId);
64
+ }
65
+ export function createCrudOperations(deps) {
66
+ const { schema, db, access, realtime } = deps;
67
+ const idempotency = resolveIdempotencyConfig(deps.idempotency);
68
+ const scopeFor = (resolver, ctx) => (resolver ? resolver(ctx) : undefined);
69
+ function resolveTable(tableName) {
70
+ const table = Object.values(schema).find((t) => isTable(t) && getTableName(t) === tableName);
71
+ if (!table) {
72
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
73
+ }
74
+ const tableAccess = tableEntryForName(access, tableName);
75
+ if (!tableAccess || !tableAccess.enabled) {
76
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
77
+ }
78
+ const idCol = getTableColumns(table)['id'];
79
+ if (!idCol) {
80
+ throw new CrudOperationError(400, ErrorCode.BAD_REQUEST, `Table ${tableName} has no id column`);
81
+ }
82
+ return { table, tableAccess, idCol };
83
+ }
84
+ return {
85
+ async list(tableName, params, ctx) {
86
+ const { table, tableAccess, idCol } = resolveTable(tableName);
87
+ const denied = await checkAccess(tableAccess.list, ctx, tableAccess.ownerColumn);
88
+ if (!denied.allowed) {
89
+ throw new CrudOperationError(denied.status === 401 ? 401 : 403, ErrorCode.FORBIDDEN, 'Forbidden');
90
+ }
91
+ try {
92
+ const resolved = resolveListParams(params ?? {}, tableAccess);
93
+ const scope = scopeFor(tableAccess.readScope, ctx);
94
+ const scopeWhere = scope ? buildScopeWhere(table, scope) : undefined;
95
+ return await executeList(db, table, tableAccess, resolved, idCol, scopeWhere);
96
+ }
97
+ catch (err) {
98
+ if (err instanceof ListQueryError) {
99
+ throw new CrudOperationError(400, err.code, err.message, err.details);
100
+ }
101
+ throw err;
102
+ }
103
+ },
104
+ async get(tableName, rawId, ctx) {
105
+ const { table, tableAccess, idCol } = resolveTable(tableName);
106
+ const id = coerceId(rawId);
107
+ const rows = await db
108
+ .select()
109
+ .from(table)
110
+ .where(eq(idCol, id));
111
+ if (!rows[0]) {
112
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
113
+ }
114
+ const row = rows[0];
115
+ const denied = await checkAccess(tableAccess.get, { ...ctx, row }, tableAccess.ownerColumn);
116
+ if (!denied.allowed) {
117
+ throw new CrudOperationError(denied.status === 401 ? 401 : 403, ErrorCode.FORBIDDEN, 'Forbidden');
118
+ }
119
+ const scope = scopeFor(tableAccess.readScope, ctx);
120
+ if (scope && !rowMatchesScope(row, scope)) {
121
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
122
+ }
123
+ return row;
124
+ },
125
+ async create(tableName, body, rawBody, idempotencyKey, ctx) {
126
+ const { table, tableAccess } = resolveTable(tableName);
127
+ const denied = await checkAccess(tableAccess.create, ctx, tableAccess.ownerColumn);
128
+ if (!denied.allowed) {
129
+ throw new CrudOperationError(denied.status === 401 ? 401 : 403, ErrorCode.FORBIDDEN, 'Forbidden');
130
+ }
131
+ if (!isRecord(body)) {
132
+ throw new CrudOperationError(400, ErrorCode.BAD_REQUEST, 'Invalid JSON body');
133
+ }
134
+ const trimmedKey = idempotencyKey?.trim();
135
+ const effectiveRawBody = rawBody ?? JSON.stringify(body);
136
+ if (idempotency && trimmedKey) {
137
+ const lookup = await lookupIdempotency(db, tableName, trimmedKey, effectiveRawBody);
138
+ if (lookup.type === 'conflict') {
139
+ throw new CrudOperationError(409, ErrorCode.IDEMPOTENCY_CONFLICT, 'Idempotency key reused with different body');
140
+ }
141
+ if (lookup.type === 'replay') {
142
+ return {
143
+ type: 'replay',
144
+ status: lookup.status,
145
+ body: lookup.response,
146
+ record: JSON.parse(lookup.response),
147
+ };
148
+ }
149
+ }
150
+ const values = sanitizeWriteBody(body, tableAccess, 'create', ctx.user?.id ?? null);
151
+ const scope = scopeFor(tableAccess.writeScope, { ...ctx, body });
152
+ const stamped = scope ? stampScope(values, scope) : values;
153
+ let rows;
154
+ try {
155
+ rows = await db.insert(table).values(stamped).returning();
156
+ }
157
+ catch (error) {
158
+ if (isUniqueConstraintError(error)) {
159
+ throw new CrudOperationError(409, ErrorCode.CONFLICT, 'Record already exists');
160
+ }
161
+ throw error;
162
+ }
163
+ const created = rows[0];
164
+ void realtime?.publish(table, 'create', created);
165
+ if (idempotency && trimmedKey) {
166
+ await storeIdempotency(db, tableName, trimmedKey, effectiveRawBody, 201, created, idempotency);
167
+ }
168
+ return {
169
+ type: 'created',
170
+ status: 201,
171
+ record: created,
172
+ };
173
+ },
174
+ async update(tableName, rawId, body, ctx) {
175
+ const { table, tableAccess, idCol } = resolveTable(tableName);
176
+ const id = coerceId(rawId);
177
+ const existing = await db
178
+ .select()
179
+ .from(table)
180
+ .where(eq(idCol, id));
181
+ if (!existing[0]) {
182
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
183
+ }
184
+ const existingRow = existing[0];
185
+ const readScope = scopeFor(tableAccess.readScope, ctx);
186
+ if (readScope && !rowMatchesScope(existingRow, readScope)) {
187
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
188
+ }
189
+ const denied = await checkAccess(tableAccess.update, { ...ctx, row: existingRow }, tableAccess.ownerColumn);
190
+ if (!denied.allowed) {
191
+ throw new CrudOperationError(denied.status === 401 ? 401 : 403, ErrorCode.FORBIDDEN, 'Forbidden');
192
+ }
193
+ if (!isRecord(body)) {
194
+ throw new CrudOperationError(400, ErrorCode.BAD_REQUEST, 'Invalid JSON body');
195
+ }
196
+ const values = sanitizeWriteBody(body, tableAccess, 'update', ctx.user?.id ?? null);
197
+ if (Object.keys(values).length === 0) {
198
+ throw new CrudOperationError(400, ErrorCode.BAD_REQUEST, 'No writable fields to update');
199
+ }
200
+ const writeScope = scopeFor(tableAccess.writeScope, { ...ctx, body });
201
+ const stamped = writeScope ? stampScope(values, writeScope) : values;
202
+ const rows = await db
203
+ .update(table)
204
+ .set(stamped)
205
+ .where(eq(idCol, id))
206
+ .returning();
207
+ if (!rows[0]) {
208
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
209
+ }
210
+ const updated = rows[0];
211
+ void realtime?.publish(table, 'update', updated);
212
+ return updated;
213
+ },
214
+ async delete(tableName, rawId, ctx) {
215
+ const { table, tableAccess, idCol } = resolveTable(tableName);
216
+ const id = coerceId(rawId);
217
+ const existing = await db
218
+ .select()
219
+ .from(table)
220
+ .where(eq(idCol, id));
221
+ if (!existing[0]) {
222
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
223
+ }
224
+ const existingRow = existing[0];
225
+ const readScope = scopeFor(tableAccess.readScope, ctx);
226
+ if (readScope && !rowMatchesScope(existingRow, readScope)) {
227
+ throw new CrudOperationError(404, ErrorCode.NOT_FOUND, 'Not found');
228
+ }
229
+ const denied = await checkAccess(tableAccess.delete, { ...ctx, row: existingRow }, tableAccess.ownerColumn);
230
+ if (!denied.allowed) {
231
+ throw new CrudOperationError(denied.status === 401 ? 401 : 403, ErrorCode.FORBIDDEN, 'Forbidden');
232
+ }
233
+ await db.delete(table).where(eq(idCol, id));
234
+ void realtime?.publish(table, 'delete', existingRow);
235
+ },
236
+ };
237
+ }
238
+ //# sourceMappingURL=crud-operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud-operations.js","sourceRoot":"","sources":["../src/crud-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,EAAE,EACF,eAAe,EACf,YAAY,EACZ,OAAO,GAER,MAAM,aAAa,CAAA;AAKpB,OAAO,EACL,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAKlB,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,cAAc,GAGf,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,GAEjB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,WAAW,EACX,iBAAiB,GAGlB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAQzC,SAAS,kBAAkB,CAAC,MAAc;IACxC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,cAAc,CAAA;IACzC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,WAAW,CAAA;IACtC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,WAAW,CAAA;IACtC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,UAAU,CAAA;IACrC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,mBAAmB,CAAA;IAC9C,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,mBAAmB,CAAA;IAC9C,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,gBAAgB;IAG3C;IAFX,YACE,MAAc,EACL,UAA0B,EACnC,OAAe,EACf,OAAiB;QAEjB,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACvC,KAAK,CACH,IAAI,EACJ,OAAO,EACP,UAAU,KAAK,IAAI;YACjB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC;gBACE,IAAI,EAAE,UAAU;gBAChB,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;aAC9C,CACN,CAAA;QAdQ,eAAU,GAAV,UAAU,CAAgB;QAenC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAqBD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAA;IAC/B,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAC5B,IACE,IAAI,KAAK,OAAO;YAChB,IAAI,KAAK,0BAA0B;YACnC,IAAI,KAAK,8BAA8B,EACvC,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;QAClC,IACE,OAAO,OAAO,KAAK,QAAQ;YAC3B,CAAC,iDAAiD,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC9D,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAC5C,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,KAAsB;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAElC,IAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;IAC7C,MAAM,WAAW,GAAG,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAE9D,MAAM,QAAQ,GAAG,CACf,QAAmC,EACnC,GAMC,EACqB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAEjE,SAAS,YAAY,CAAC,SAAiB;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,SAAS,CAC9B,CAAA;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;QACrE,CAAC;QACD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACxD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;QACrE,CAAC;QACD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAA;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,WAAW,EACrB,SAAS,SAAS,mBAAmB,CACtC,CAAA;QACH,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;IACtC,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI,CACR,SAAiB,EACjB,MAAmC,EACnC,GAAyB;YAEzB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;YAE7D,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,CAAC,IAAI,EAChB,GAAG,EACH,WAAW,CAAC,WAAW,CACxB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACjC,SAAS,CAAC,SAAS,EACnB,WAAW,CACZ,CAAA;YACH,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,IAAI,EAAE,EAAE,WAAW,CAAC,CAAA;gBAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;gBAClD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBACpE,OAAO,MAAM,WAAW,CACtB,EAAE,EACF,KAAK,EACL,WAAW,EACX,QAAQ,EACR,KAAK,EACL,UAAU,CACX,CAAA;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;oBAClC,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;gBACvE,CAAC;gBACD,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QAED,KAAK,CAAC,GAAG,CACP,SAAiB,EACjB,KAAsB,EACtB,GAAyB;YAEzB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;YAC7D,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;YAE1B,MAAM,IAAI,GAAG,MAAM,EAAE;iBAClB,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;YACvB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACb,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAA;YAE9C,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,CAAC,GAAG,EACf,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,EACf,WAAW,CAAC,WAAW,CACxB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACjC,SAAS,CAAC,SAAS,EACnB,WAAW,CACZ,CAAA;YACH,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YAClD,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YAED,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,IAAa,EACb,OAA2B,EAC3B,cAAkC,EAClC,GAAyB;YAEzB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;YAEtD,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,CAAC,MAAM,EAClB,GAAG,EACH,WAAW,CAAC,WAAW,CACxB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACjC,SAAS,CAAC,SAAS,EACnB,WAAW,CACZ,CAAA;YACH,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,WAAW,EACrB,mBAAmB,CACpB,CAAA;YACH,CAAC;YAED,MAAM,UAAU,GAAG,cAAc,EAAE,IAAI,EAAE,CAAA;YACzC,MAAM,gBAAgB,GAAG,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAExD,IAAI,WAAW,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,EAAE,EACF,SAAS,EACT,UAAU,EACV,gBAAgB,CACjB,CAAA;gBACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC/B,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,oBAAoB,EAC9B,4CAA4C,CAC7C,CAAA;gBACH,CAAC;gBACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC7B,OAAO;wBACL,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,IAAI,EAAE,MAAM,CAAC,QAAQ;wBACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAA4B;qBAC/D,CAAA;gBACH,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,iBAAiB,CAC9B,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI,CACrB,CAAA;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;YAChE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YAE1D,IAAI,IAA+B,CAAA;YACnC,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAA;YAC3D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnC,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,QAAQ,EAClB,uBAAuB,CACxB,CAAA;gBACH,CAAC;gBACD,MAAM,KAAK,CAAA;YACb,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAA;YAClD,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAc,EAAE,QAAQ,EAAE,OAAgB,CAAC,CAAA;YAElE,IAAI,WAAW,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,gBAAgB,CACpB,EAAE,EACF,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,GAAG,EACH,OAAO,EACP,WAAW,CACZ,CAAA;YACH,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,OAAO;aAChB,CAAA;QACH,CAAC;QAED,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAsB,EACtB,IAAa,EACb,GAAyB;YAEzB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;YAC7D,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;YAE1B,MAAM,QAAQ,GAAG,MAAM,EAAE;iBACtB,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;YACvB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAA4B,CAAA;YAE1D,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACtD,IAAI,SAAS,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC1D,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,CAAC,MAAM,EAClB,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,EAC5B,WAAW,CAAC,WAAW,CACxB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACjC,SAAS,CAAC,SAAS,EACnB,WAAW,CACZ,CAAA;YACH,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,WAAW,EACrB,mBAAmB,CACpB,CAAA;YACH,CAAC;YAED,MAAM,MAAM,GAAG,iBAAiB,CAC9B,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI,CACrB,CAAA;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EACH,SAAS,CAAC,WAAW,EACrB,8BAA8B,CAC/B,CAAA;YACH,CAAC;YAED,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;YACrE,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YAEpE,MAAM,IAAI,GAAG,MAAM,EAAE;iBAClB,MAAM,CAAC,KAAK,CAAC;iBACb,GAAG,CAAC,OAAO,CAAC;iBACZ,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;iBACpB,SAAS,EAAE,CAAA;YAEd,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACb,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAA;YAClD,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAc,EAAE,QAAQ,EAAE,OAAgB,CAAC,CAAA;YAClE,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAsB,EACtB,GAAyB;YAEzB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;YAC7D,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;YAE1B,MAAM,QAAQ,GAAG,MAAM,EAAE;iBACtB,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;YACvB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAA4B,CAAA;YAE1D,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACtD,IAAI,SAAS,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC1D,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrE,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,CAAC,MAAM,EAClB,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,EAC5B,WAAW,CAAC,WAAW,CACxB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,kBAAkB,CAC1B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EACjC,SAAS,CAAC,SAAS,EACnB,WAAW,CACZ,CAAA;YACH,CAAC;YAED,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;YAC3C,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAc,EAAE,QAAQ,EAAE,WAAoB,CAAC,CAAA;QACxE,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { DbFor, Driver } from '../db.js';
2
+ import type { AnyDb, Dialect } from '../dialect.js';
3
+ export type DatabaseConnection = {
4
+ url: string;
5
+ authToken?: string;
6
+ };
7
+ export type DatabaseConnectOptions = {
8
+ introspect: boolean;
9
+ };
10
+ export type DatabaseConnectionResult<TSchema extends Record<string, unknown>> = {
11
+ db: DbFor<TSchema>;
12
+ close?: () => void | Promise<void>;
13
+ };
14
+ export type DatabaseAdapter = {
15
+ readonly dialect: Dialect;
16
+ readonly driver: Driver;
17
+ connect<TSchema extends Record<string, unknown>>(schema: TSchema, connection: DatabaseConnection, options: DatabaseConnectOptions): Promise<DatabaseConnectionResult<TSchema>>;
18
+ migrate(db: AnyDb, migrationsFolder: string): Promise<void>;
19
+ };
20
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/database/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEhD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5D,MAAM,MAAM,wBAAwB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC1E;IACE,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC,CAAA;AAEH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,OAAO,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,kBAAkB,EAC9B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC7C,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5D,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/database/adapter.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { DatabaseAdapter } from './adapter.js';
2
+ export declare function bunSql(): DatabaseAdapter;
3
+ //# sourceMappingURL=bun-sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sql.d.ts","sourceRoot":"","sources":["../../src/database/bun-sql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAEhD,wBAAgB,MAAM,IAAI,eAAe,CAiBxC"}
@@ -0,0 +1,21 @@
1
+ import { drizzle } from 'drizzle-orm/bun-sql';
2
+ import { migrate } from 'drizzle-orm/bun-sql/migrator';
3
+ export function bunSql() {
4
+ return {
5
+ dialect: 'pg',
6
+ driver: 'bun-sql',
7
+ async connect(schema, { url }, { introspect }) {
8
+ if (introspect)
9
+ return { db: drizzle.mock({ schema }) };
10
+ if (!url.startsWith('postgres://') && !url.startsWith('postgresql://')) {
11
+ throw new Error('[bunderstack] bunSql adapter requires a Postgres URL');
12
+ }
13
+ const db = drizzle(url, { schema });
14
+ return { db: db, close: () => db.$client.close() };
15
+ },
16
+ async migrate(db, migrationsFolder) {
17
+ await migrate(db, { migrationsFolder });
18
+ },
19
+ };
20
+ }
21
+ //# sourceMappingURL=bun-sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sql.js","sourceRoot":"","sources":["../../src/database/bun-sql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAItD,MAAM,UAAU,MAAM;IACpB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,SAAS;QACjB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE;YAC3C,IAAI,UAAU;gBAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAU,EAAE,CAAA;YAEhE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;YACzE,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YACnC,OAAO,EAAE,EAAE,EAAE,EAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAA;QAC7D,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,gBAAgB;YAChC,MAAM,OAAO,CAAC,EAAW,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAClD,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DatabaseAdapter } from './adapter.js';
2
+ export declare function libsql(): DatabaseAdapter;
3
+ //# sourceMappingURL=libsql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"libsql.d.ts","sourceRoot":"","sources":["../../src/database/libsql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAEhD,wBAAgB,MAAM,IAAI,eAAe,CAsBxC"}
@@ -0,0 +1,22 @@
1
+ import { drizzle } from 'drizzle-orm/libsql';
2
+ import { migrate } from 'drizzle-orm/libsql/migrator';
3
+ export function libsql() {
4
+ return {
5
+ dialect: 'sqlite',
6
+ driver: 'libsql',
7
+ async connect(schema, connection, { introspect }) {
8
+ if (introspect)
9
+ return { db: drizzle.mock({ schema }) };
10
+ if (connection.url.startsWith('postgres://') ||
11
+ connection.url.startsWith('postgresql://')) {
12
+ throw new Error('[bunderstack] libsql adapter cannot connect to a Postgres URL');
13
+ }
14
+ const db = drizzle({ connection, schema });
15
+ return { db: db, close: () => db.$client.close() };
16
+ },
17
+ async migrate(db, migrationsFolder) {
18
+ await migrate(db, { migrationsFolder });
19
+ },
20
+ };
21
+ }
22
+ //# sourceMappingURL=libsql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"libsql.js","sourceRoot":"","sources":["../../src/database/libsql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAIrD,MAAM,UAAU,MAAM;IACpB,OAAO;QACL,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,QAAQ;QAChB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE;YAC9C,IAAI,UAAU;gBAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAU,EAAE,CAAA;YAEhE,IACE,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;gBACxC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAC1C,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAA;YACH,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;YAC1C,OAAO,EAAE,EAAE,EAAE,EAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAA;QAC7D,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,gBAAgB;YAChC,MAAM,OAAO,CAAC,EAAW,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAClD,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DatabaseAdapter } from './adapter.js';
2
+ export declare function pglite(): DatabaseAdapter;
3
+ //# sourceMappingURL=pglite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pglite.d.ts","sourceRoot":"","sources":["../../src/database/pglite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAKhD,wBAAgB,MAAM,IAAI,eAAe,CAuBxC"}