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,27 @@
1
+ import { drizzle } from 'drizzle-orm/pglite';
2
+ import { migrate } from 'drizzle-orm/pglite/migrator';
3
+ import { mkdir } from 'node:fs/promises';
4
+ const rawPath = (url) => url.startsWith('file:') ? url.slice('file:'.length) : url;
5
+ export function pglite() {
6
+ return {
7
+ dialect: 'pg',
8
+ driver: 'pglite',
9
+ async connect(schema, { url }, { introspect }) {
10
+ if (introspect)
11
+ return { db: drizzle.mock({ schema }) };
12
+ if (url.startsWith('postgres://') || url.startsWith('postgresql://')) {
13
+ throw new Error('[bunderstack] pglite adapter cannot connect to a Postgres URL');
14
+ }
15
+ const raw = rawPath(url);
16
+ const dataDir = raw === ':memory:' ? 'memory://' : raw;
17
+ if (!dataDir.startsWith('memory://'))
18
+ await mkdir(dataDir, { recursive: true });
19
+ const db = drizzle(dataDir, { schema });
20
+ return { db: db, close: () => db.$client.close() };
21
+ },
22
+ async migrate(db, migrationsFolder) {
23
+ await migrate(db, { migrationsFolder });
24
+ },
25
+ };
26
+ }
27
+ //# sourceMappingURL=pglite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pglite.js","sourceRoot":"","sources":["../../src/database/pglite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAIxC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAC9B,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAE3D,MAAM,UAAU,MAAM;IACpB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,QAAQ;QAChB,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,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrE,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAA;YACH,CAAC;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;YACxB,MAAM,OAAO,GAAG,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAA;YACtD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;gBAClC,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YACvC,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 postgresJs(): DatabaseAdapter;
3
+ //# sourceMappingURL=postgres-js.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-js.d.ts","sourceRoot":"","sources":["../../src/database/postgres-js.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,WAAW,CAAA;AAElB,wBAAgB,UAAU,IAAI,eAAe,CAuB5C"}
@@ -0,0 +1,21 @@
1
+ import { drizzle } from 'drizzle-orm/postgres-js';
2
+ import { migrate } from 'drizzle-orm/postgres-js/migrator';
3
+ export function postgresJs() {
4
+ return {
5
+ dialect: 'pg',
6
+ driver: 'postgres-js',
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] postgresJs adapter requires a Postgres URL');
12
+ }
13
+ const db = drizzle({ connection: url, schema });
14
+ return { db: db, close: () => db.$client.end() };
15
+ },
16
+ async migrate(db, migrationsFolder) {
17
+ await migrate(db, { migrationsFolder });
18
+ },
19
+ };
20
+ }
21
+ //# sourceMappingURL=postgres-js.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-js.js","sourceRoot":"","sources":["../../src/database/postgres-js.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAA;AAQ1D,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,aAAa;QACrB,KAAK,CAAC,OAAO,CACX,MAAe,EACf,EAAE,GAAG,EAAsB,EAC3B,EAAE,UAAU,EAA0B;YAEtC,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,CACb,0DAA0D,CAC3D,CAAA;YACH,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;YACxD,OAAO,EAAE,EAAE,EAAE,EAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAA;QAC3D,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"}
package/dist/db.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { LibSQLDatabase } from 'drizzle-orm/libsql';
2
+ import type { PgDatabase, PgQueryResultHKT, PgTable } from 'drizzle-orm/pg-core';
3
+ import type { DatabaseAdapter, DatabaseConnection, DatabaseConnectionResult } from './database/adapter.js';
4
+ import type { Dialect } from './dialect.js';
5
+ export type Driver = 'libsql' | 'pglite' | 'bun-sql' | 'postgres-js';
6
+ /** Per-dialect public db type, computed from the schema's table brands. */
7
+ export type DbFor<TSchema extends Record<string, unknown>> = [
8
+ Extract<TSchema[keyof TSchema], PgTable>
9
+ ] extends [never] ? LibSQLDatabase<TSchema> : PgDatabase<PgQueryResultHKT, TSchema>;
10
+ export declare function validateDatabaseUrl(url: string, dialect: Dialect): void;
11
+ export declare function createDb<TSchema extends Record<string, unknown>>(schema: TSchema, cfg: DatabaseConnection & {
12
+ adapter: DatabaseAdapter;
13
+ dialect: Dialect;
14
+ introspect?: boolean;
15
+ }): Promise<DatabaseConnectionResult<TSchema> & {
16
+ driver: Driver;
17
+ }>;
18
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAEhF,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAA;AAEpE,2EAA2E;AAC3E,MAAM,MAAM,KAAK,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC3D,OAAO,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,CAAC;CACzC,SAAS,CAAC,KAAK,CAAC,GACb,cAAc,CAAC,OAAO,CAAC,GACvB,UAAU,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;AAKzC,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,QAgBhE;AAED,wBAAsB,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,kBAAkB,GAAG;IACxB,OAAO,EAAE,eAAe,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,GACA,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAajE"}
package/dist/db.js ADDED
@@ -0,0 +1,26 @@
1
+ const PG_SERVER_RE = /^postgres(ql)?:\/\//;
2
+ const LIBSQL_REMOTE_RE = /^(libsql|wss?|https?):\/\//;
3
+ export function validateDatabaseUrl(url, dialect) {
4
+ if (dialect === 'sqlite') {
5
+ if (PG_SERVER_RE.test(url)) {
6
+ throw new Error('[bunderstack] DATABASE_URL is a Postgres URL but the schema uses sqliteTable. ' +
7
+ 'Define the schema with drizzle-orm/pg-core, or point DATABASE_URL at a SQLite database.');
8
+ }
9
+ }
10
+ else if (dialect === 'pg') {
11
+ if (LIBSQL_REMOTE_RE.test(url)) {
12
+ throw new Error('[bunderstack] DATABASE_URL looks like a libsql/Turso URL but the schema uses pgTable. ' +
13
+ 'Set DATABASE_URL=postgres://… (or leave it unset for local PGlite).');
14
+ }
15
+ }
16
+ }
17
+ export async function createDb(schema, cfg) {
18
+ if (cfg.adapter.dialect !== cfg.dialect) {
19
+ throw new Error(`[bunderstack] database adapter dialect ${cfg.adapter.dialect} does not match ${cfg.dialect} schema`);
20
+ }
21
+ if (!cfg.introspect)
22
+ validateDatabaseUrl(cfg.url, cfg.dialect);
23
+ const result = await cfg.adapter.connect(schema, { url: cfg.url, authToken: cfg.authToken }, { introspect: cfg.introspect ?? false });
24
+ return { ...result, driver: cfg.adapter.driver };
25
+ }
26
+ //# sourceMappingURL=db.js.map
package/dist/db.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAmBA,MAAM,YAAY,GAAG,qBAAqB,CAAA;AAC1C,MAAM,gBAAgB,GAAG,4BAA4B,CAAA;AAErD,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,OAAgB;IAC/D,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,gFAAgF;gBAC9E,yFAAyF,CAC5F,CAAA;QACH,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,wFAAwF;gBACtF,qEAAqE,CACxE,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAe,EACf,GAIC;IAED,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,0CAA0C,GAAG,CAAC,OAAO,CAAC,OAAO,mBAAmB,GAAG,CAAC,OAAO,SAAS,CACrG,CAAA;IACH,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CACtC,MAAM,EACN,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,EAC1C,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,KAAK,EAAE,CACxC,CAAA;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA;AAClD,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type Dialect = 'sqlite' | 'pg';
2
+ /**
3
+ * Minimal structural view of a drizzle db shared by both dialects. Internal
4
+ * modules run dynamic tables (Record<string, unknown> schemas) where drizzle's
5
+ * generics add no safety, so they accept this instead of a per-dialect union.
6
+ * The public surface (`app.db`, API context) keeps full per-dialect typing via
7
+ * `DbFor` in db.ts.
8
+ */
9
+ export type AnyDb = {
10
+ select: (...args: any[]) => any;
11
+ insert: (...args: any[]) => any;
12
+ update: (...args: any[]) => any;
13
+ delete: (...args: any[]) => any;
14
+ };
15
+ /** Classify a schema by its table brands. Mixed dialects are a config error. */
16
+ export declare function detectDialect(schema: Record<string, unknown>): Dialect;
17
+ //# sourceMappingURL=dialect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAA;AAErC;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;IAC/B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;IAC/B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;IAC/B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;CAChC,CAAA;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CActE"}
@@ -0,0 +1,22 @@
1
+ // src/dialect.ts — schema-driven dialect detection. Imports only dialect-core
2
+ // drizzle entrypoints (no drivers), safe in every module graph.
3
+ import { is } from 'drizzle-orm';
4
+ import { PgTable } from 'drizzle-orm/pg-core';
5
+ import { SQLiteTable } from 'drizzle-orm/sqlite-core';
6
+ /** Classify a schema by its table brands. Mixed dialects are a config error. */
7
+ export function detectDialect(schema) {
8
+ let pgKey;
9
+ let sqliteKey;
10
+ for (const [key, value] of Object.entries(schema)) {
11
+ if (is(value, PgTable))
12
+ pgKey ??= key;
13
+ else if (is(value, SQLiteTable))
14
+ sqliteKey ??= key;
15
+ }
16
+ if (pgKey !== undefined && sqliteKey !== undefined) {
17
+ throw new Error(`[bunderstack] schema mixes dialects: "${pgKey}" is a Postgres table while "${sqliteKey}" is a SQLite table. ` +
18
+ 'Define every table with the same dialect (drizzle-orm/pg-core or drizzle-orm/sqlite-core).');
19
+ }
20
+ return pgKey !== undefined ? 'pg' : 'sqlite';
21
+ }
22
+ //# sourceMappingURL=dialect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialect.js","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,gEAAgE;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAkBrD,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,MAA+B;IAC3D,IAAI,KAAyB,CAAA;IAC7B,IAAI,SAA6B,CAAA;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;YAAE,KAAK,KAAK,GAAG,CAAA;aAChC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;YAAE,SAAS,KAAK,GAAG,CAAA;IACpD,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,yCAAyC,KAAK,gCAAgC,SAAS,uBAAuB;YAC5G,4FAA4F,CAC/F,CAAA;IACH,CAAC;IACD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { EmailAdapter } from '../email.js';
2
+ type SmtpTransport = {
3
+ sendMail(message: Record<string, unknown>): Promise<{
4
+ messageId?: string;
5
+ }>;
6
+ };
7
+ export declare function createSmtpAdapter(options: {
8
+ url: string;
9
+ }, createTransport?: (url: string) => SmtpTransport): EmailAdapter;
10
+ export declare const smtp: (options: {
11
+ url: string;
12
+ }) => EmailAdapter;
13
+ export {};
14
+ //# sourceMappingURL=smtp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp.d.ts","sourceRoot":"","sources":["../../src/email/smtp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5E,CAAA;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACxB,eAAe,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,aACgB,GACjD,YAAY,CA6Bd;AAED,eAAO,MAAM,IAAI,GAAI,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,KAAG,YACpB,CAAA"}
@@ -0,0 +1,27 @@
1
+ import nodemailer from 'nodemailer';
2
+ export function createSmtpAdapter(options, createTransport = (url) => nodemailer.createTransport(url)) {
3
+ const toArray = (v) => v === undefined ? undefined : Array.isArray(v) ? v : [v];
4
+ let transportPromise = null;
5
+ const getTransport = () => {
6
+ transportPromise ??= Promise.resolve(createTransport(options.url));
7
+ return transportPromise;
8
+ };
9
+ return {
10
+ async send(msg) {
11
+ const transport = await getTransport();
12
+ const info = await transport.sendMail({
13
+ from: msg.from,
14
+ to: toArray(msg.to).join(', '),
15
+ subject: msg.subject,
16
+ html: msg.html,
17
+ text: msg.text,
18
+ replyTo: msg.replyTo,
19
+ cc: toArray(msg.cc)?.join(', '),
20
+ bcc: toArray(msg.bcc)?.join(', '),
21
+ });
22
+ return { id: info.messageId };
23
+ },
24
+ };
25
+ }
26
+ export const smtp = (options) => createSmtpAdapter(options);
27
+ //# sourceMappingURL=smtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp.js","sourceRoot":"","sources":["../../src/email/smtp.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAQnC,MAAM,UAAU,iBAAiB,CAC/B,OAAwB,EACxB,kBAAkD,CAAC,GAAG,EAAE,EAAE,CACxD,UAAU,CAAC,eAAe,CAAC,GAAG,CAAkB;IAElD,MAAM,OAAO,GAAG,CAAC,CAAgC,EAAE,EAAE,CACnD,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAE1D,IAAI,gBAAgB,GAER,IAAI,CAAA;IAEhB,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,gBAAgB,KAAK,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;QAClE,OAAO,gBAAgB,CAAA;IACzB,CAAC,CAAA;IAED,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,GAAG;YACZ,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAA;YACtC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC;gBACpC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;gBAC/B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;aAClC,CAAC,CAAA;YACF,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAwB,EAAgB,EAAE,CAC7D,iBAAiB,CAAC,OAAO,CAAC,CAAA"}
@@ -0,0 +1,39 @@
1
+ export type EmailMessage = {
2
+ to: string | string[];
3
+ subject: string;
4
+ html?: string;
5
+ text?: string;
6
+ from?: string;
7
+ replyTo?: string;
8
+ cc?: string | string[];
9
+ bcc?: string | string[];
10
+ };
11
+ export type SentEmail = {
12
+ id?: string;
13
+ };
14
+ /** Adapters receive the message with `from` already resolved. */
15
+ export type EmailAdapter = {
16
+ send(msg: EmailMessage & {
17
+ from: string;
18
+ }): Promise<SentEmail>;
19
+ };
20
+ export type EmailConfigInput = {
21
+ from: string;
22
+ provider?: 'resend' | 'console' | EmailAdapter | EmailAdapter['send'];
23
+ };
24
+ export type EmailFacade = {
25
+ send(msg: EmailMessage): Promise<SentEmail>;
26
+ };
27
+ export type CreateEmailOptions = {
28
+ env: {
29
+ RESEND_API_KEY?: string;
30
+ SMTP_URL?: string;
31
+ NODE_ENV?: string;
32
+ };
33
+ /** Test seam for the resend adapter. */
34
+ fetchFn?: typeof fetch;
35
+ };
36
+ /** Root string provider tag ('resend' | 'console') or undefined. */
37
+ export declare function emailProviderTag(config: EmailConfigInput | undefined): string | undefined;
38
+ export declare function createEmail(config: EmailConfigInput | undefined, opts: CreateEmailOptions): EmailFacade;
39
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC,iEAAiE;AACjE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;CAC/D,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;CACtE,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;CAC5C,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtE,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,CAAA;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GAAG,SAAS,GACnC,MAAM,GAAG,SAAS,CAEpB;AA0FD,wBAAgB,WAAW,CACzB,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,IAAI,EAAE,kBAAkB,GACvB,WAAW,CAmBb"}
package/dist/email.js ADDED
@@ -0,0 +1,97 @@
1
+ // src/email.ts — email sending: console / resend / custom adapters.
2
+ // SMTP is provided by the static `bunderstack/email/smtp` factory subpath.
3
+ /** Root string provider tag ('resend' | 'console') or undefined. */
4
+ export function emailProviderTag(config) {
5
+ return typeof config?.provider === 'string' ? config.provider : undefined;
6
+ }
7
+ const toArray = (v) => v === undefined ? undefined : Array.isArray(v) ? v : [v];
8
+ function createConsoleAdapter() {
9
+ return {
10
+ async send(msg) {
11
+ const line = '─'.repeat(60);
12
+ console.log([
13
+ line,
14
+ '📧 email (console provider — not sent)',
15
+ `from: ${msg.from}`,
16
+ `to: ${toArray(msg.to).join(', ')}`,
17
+ `subject: ${msg.subject}`,
18
+ line,
19
+ msg.text ?? msg.html ?? '',
20
+ line,
21
+ ].join('\n'));
22
+ return {};
23
+ },
24
+ };
25
+ }
26
+ function createResendAdapter(apiKey, fetchFn) {
27
+ return {
28
+ async send(msg) {
29
+ const res = await fetchFn('https://api.resend.com/emails', {
30
+ method: 'POST',
31
+ headers: {
32
+ Authorization: `Bearer ${apiKey}`,
33
+ 'Content-Type': 'application/json',
34
+ },
35
+ body: JSON.stringify({
36
+ from: msg.from,
37
+ to: toArray(msg.to),
38
+ subject: msg.subject,
39
+ html: msg.html,
40
+ text: msg.text,
41
+ reply_to: msg.replyTo,
42
+ cc: toArray(msg.cc),
43
+ bcc: toArray(msg.bcc),
44
+ }),
45
+ });
46
+ if (!res.ok) {
47
+ throw new Error(`resend API error (${res.status}): ${await res.text()}`);
48
+ }
49
+ const data = (await res.json());
50
+ return { id: data.id };
51
+ },
52
+ };
53
+ }
54
+ function resolveAdapter(config, opts) {
55
+ const provider = config.provider;
56
+ if (typeof provider === 'function')
57
+ return { send: provider };
58
+ if (typeof provider === 'object')
59
+ return provider;
60
+ const fetchFn = opts.fetchFn ?? globalThis.fetch.bind(globalThis);
61
+ switch (provider) {
62
+ case 'resend':
63
+ return createResendAdapter(opts.env.RESEND_API_KEY ?? '', fetchFn);
64
+ case 'console':
65
+ return createConsoleAdapter();
66
+ case undefined:
67
+ if (opts.env.NODE_ENV === 'production') {
68
+ throw new Error('email is configured without a provider — set email.provider ' +
69
+ "('resend' | a custom adapter) for production");
70
+ }
71
+ return createConsoleAdapter();
72
+ default:
73
+ if (provider === 'smtp') {
74
+ throw new Error("email provider 'smtp' was removed. Import `smtp` from 'bunderstack/email/smtp' instead.");
75
+ }
76
+ return createConsoleAdapter();
77
+ }
78
+ }
79
+ export function createEmail(config, opts) {
80
+ if (!config) {
81
+ return {
82
+ async send() {
83
+ throw new Error('email is not configured — add an email key to your bunderstack config');
84
+ },
85
+ };
86
+ }
87
+ const adapter = resolveAdapter(config, opts);
88
+ return {
89
+ async send(msg) {
90
+ if (!msg.html && !msg.text) {
91
+ throw new Error('email message needs html or text content');
92
+ }
93
+ return adapter.send({ ...msg, from: msg.from ?? config.from });
94
+ },
95
+ };
96
+ }
97
+ //# sourceMappingURL=email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ export declare const CLIENT_PREFIX: "PUBLIC_";
3
+ export type EnvConfigInput = {
4
+ server?: Record<string, StandardSchemaV1>;
5
+ client?: Record<string, StandardSchemaV1>;
6
+ /** Explicit value source for client vars (e.g. Vite's import.meta.env). */
7
+ runtimeEnv?: Record<string, unknown>;
8
+ };
9
+ export type BunderstackRole = 'all' | 'web' | 'worker';
10
+ /** Vars bunderstack itself consumes, always validated. */
11
+ export type BaseEnv = {
12
+ NODE_ENV?: string;
13
+ DATABASE_URL: string;
14
+ DATABASE_AUTH_TOKEN?: string;
15
+ AUTH_SECRET: string;
16
+ REDIS_URL?: string;
17
+ RESEND_API_KEY?: string;
18
+ SMTP_URL?: string;
19
+ BUNDERSTACK_ROLE: BunderstackRole;
20
+ };
21
+ type InferVars<T> = T extends Record<string, StandardSchemaV1> ? {
22
+ [K in keyof T]: StandardSchemaV1.InferOutput<T[K]>;
23
+ } : unknown;
24
+ export type ValidatedEnv<TEnv extends EnvConfigInput | undefined> = [
25
+ TEnv
26
+ ] extends [EnvConfigInput] ? BaseEnv & InferVars<NonNullable<TEnv>['server']> & InferVars<NonNullable<TEnv>['client']> : BaseEnv;
27
+ export declare class BunderstackEnvError extends Error {
28
+ readonly issues: string[];
29
+ constructor(issues: string[]);
30
+ }
31
+ export type ValidateEnvOptions = {
32
+ /** String tag of the configured email provider ('resend' | 'smtp'), if any. */
33
+ emailProvider?: string;
34
+ /** Value source; defaults to process.env. Tests pass this explicitly. */
35
+ source?: Record<string, string | undefined>;
36
+ /** Dialect-aware DATABASE_URL fallback; createBunderstack passes it. */
37
+ defaultDatabaseUrl?: string;
38
+ };
39
+ export declare function validateEnv<TEnv extends EnvConfigInput | undefined>(envConfig: TEnv, options?: ValidateEnvOptions): ValidatedEnv<TEnv>;
40
+ /**
41
+ * Browser-side companion (t3-env style): validates ONLY the client section.
42
+ * Server keys exist on the returned object as traps that throw on access, so
43
+ * a leaked import fails loudly instead of silently reading undefined.
44
+ */
45
+ export declare function createClientEnv<TEnv extends EnvConfigInput>(envConfig: TEnv): InferVars<TEnv['client']>;
46
+ export {};
47
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO7D,eAAO,MAAM,aAAa,EAAG,SAAkB,CAAA;AAE/C,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;AAItD,0DAA0D;AAC1D,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,eAAe,CAAA;CAClC,CAAA;AAED,KAAK,SAAS,CAAC,CAAC,IACd,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACtC;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GACtD,OAAO,CAAA;AAGb,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,cAAc,GAAG,SAAS,IAAI;IAClE,IAAI;CACL,SAAS,CAAC,cAAc,CAAC,GACtB,OAAO,GACL,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GACtC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GACxC,OAAO,CAAA;AAEX,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;gBAEb,MAAM,EAAE,MAAM,EAAE;CAK7B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC3C,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAqCD,wBAAgB,WAAW,CAAC,IAAI,SAAS,cAAc,GAAG,SAAS,EACjE,SAAS,EAAE,IAAI,EACf,OAAO,GAAE,kBAAuB,GAC/B,YAAY,CAAC,IAAI,CAAC,CA4CpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,cAAc,EACzD,SAAS,EAAE,IAAI,GACd,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAsB3B"}
package/dist/env.js ADDED
@@ -0,0 +1,99 @@
1
+ import { StandardSchemaValidationError, validateStandardSchema, } from './standard-schema.js';
2
+ export const CLIENT_PREFIX = 'PUBLIC_';
3
+ const ROLES = ['all', 'web', 'worker'];
4
+ export class BunderstackEnvError extends Error {
5
+ issues;
6
+ constructor(issues) {
7
+ super(`Invalid environment:\n - ${issues.join('\n - ')}`);
8
+ this.name = 'BunderstackEnvError';
9
+ this.issues = issues;
10
+ }
11
+ }
12
+ const DEV_AUTH_SECRET = 'dev-secret-change-in-prod';
13
+ function validateSection(section, kind, source, issues, out) {
14
+ for (const [key, schema] of Object.entries(section ?? {})) {
15
+ const isPublic = key.startsWith(CLIENT_PREFIX);
16
+ if (kind === 'server' && isPublic) {
17
+ issues.push(`${key}: server vars must not start with ${CLIENT_PREFIX} (move it to env.client)`);
18
+ continue;
19
+ }
20
+ if (kind === 'client' && !isPublic) {
21
+ issues.push(`${key}: client vars must start with ${CLIENT_PREFIX} (rename it or move it to env.server)`);
22
+ continue;
23
+ }
24
+ try {
25
+ out[key] = validateStandardSchema(schema, source[key], 'env');
26
+ }
27
+ catch (error) {
28
+ if (!(error instanceof StandardSchemaValidationError))
29
+ throw error;
30
+ for (const issue of error.issues) {
31
+ const path = issue.path.map(String).join('.');
32
+ issues.push(`${key}${path ? `.${path}` : ''}: ${issue.message}`);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ export function validateEnv(envConfig, options = {}) {
38
+ const source = options.source ?? process.env;
39
+ const issues = [];
40
+ const isProduction = source.NODE_ENV === 'production';
41
+ const base = {
42
+ NODE_ENV: source.NODE_ENV,
43
+ DATABASE_URL: source.DATABASE_URL ?? options.defaultDatabaseUrl ?? 'file:./data.db',
44
+ DATABASE_AUTH_TOKEN: source.DATABASE_AUTH_TOKEN,
45
+ AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,
46
+ REDIS_URL: source.REDIS_URL,
47
+ RESEND_API_KEY: source.RESEND_API_KEY,
48
+ SMTP_URL: source.SMTP_URL,
49
+ BUNDERSTACK_ROLE: (source.BUNDERSTACK_ROLE ?? 'all'),
50
+ };
51
+ if (isProduction && !source.AUTH_SECRET) {
52
+ issues.push('AUTH_SECRET: required in production');
53
+ }
54
+ if (source.BUNDERSTACK_ROLE !== undefined &&
55
+ !ROLES.includes(source.BUNDERSTACK_ROLE)) {
56
+ issues.push(`BUNDERSTACK_ROLE: must be one of ${ROLES.join(', ')} (got "${String(source.BUNDERSTACK_ROLE)}")`);
57
+ }
58
+ if (options.emailProvider === 'resend' && !source.RESEND_API_KEY) {
59
+ issues.push("RESEND_API_KEY: required when email provider is 'resend'");
60
+ }
61
+ if (options.emailProvider === 'smtp' && !source.SMTP_URL) {
62
+ issues.push("SMTP_URL: required when email provider is 'smtp'");
63
+ }
64
+ const userVars = {};
65
+ validateSection(envConfig?.server, 'server', source, issues, userVars);
66
+ validateSection(envConfig?.client, 'client', source, issues, userVars);
67
+ // Introspection (Bunderhost builder) imports the app declaration to read
68
+ // its manifest; missing user env must not kill the boot there.
69
+ const lenient = source.BUNDERSTACK_INTROSPECT === '1';
70
+ if (issues.length > 0 && !lenient)
71
+ throw new BunderstackEnvError(issues);
72
+ return { ...base, ...userVars };
73
+ }
74
+ /**
75
+ * Browser-side companion (t3-env style): validates ONLY the client section.
76
+ * Server keys exist on the returned object as traps that throw on access, so
77
+ * a leaked import fails loudly instead of silently reading undefined.
78
+ */
79
+ export function createClientEnv(envConfig) {
80
+ const source = envConfig.runtimeEnv ??
81
+ (typeof process !== 'undefined'
82
+ ? process.env
83
+ : {});
84
+ const issues = [];
85
+ const values = {};
86
+ validateSection(envConfig.client, 'client', source, issues, values);
87
+ if (issues.length > 0)
88
+ throw new BunderstackEnvError(issues);
89
+ const serverKeys = new Set(Object.keys(envConfig.server ?? {}));
90
+ return new Proxy(values, {
91
+ get(target, prop) {
92
+ if (typeof prop === 'string' && serverKeys.has(prop)) {
93
+ throw new Error(`${prop} is server-only and not available in client env`);
94
+ }
95
+ return Reflect.get(target, prop);
96
+ },
97
+ });
98
+ }
99
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}