@async/db 0.2.0

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 (398) hide show
  1. package/CHANGELOG.md +167 -0
  2. package/README.md +431 -0
  3. package/SPEC.md +1429 -0
  4. package/db.config.example.mjs +128 -0
  5. package/dist/cli/args.d.ts +8 -0
  6. package/dist/cli/args.js +16 -0
  7. package/dist/cli/commands/create.d.ts +3 -0
  8. package/dist/cli/commands/create.js +13 -0
  9. package/dist/cli/commands/doctor.d.ts +3 -0
  10. package/dist/cli/commands/doctor.js +31 -0
  11. package/dist/cli/commands/generate.d.ts +6 -0
  12. package/dist/cli/commands/generate.js +24 -0
  13. package/dist/cli/commands/operations.d.ts +12 -0
  14. package/dist/cli/commands/operations.js +61 -0
  15. package/dist/cli/commands/schema.d.ts +11 -0
  16. package/dist/cli/commands/schema.js +1086 -0
  17. package/dist/cli/commands/serve.d.ts +9 -0
  18. package/dist/cli/commands/serve.js +18 -0
  19. package/dist/cli/commands/sync.d.ts +3 -0
  20. package/dist/cli/commands/sync.js +11 -0
  21. package/dist/cli/commands/types.d.ts +7 -0
  22. package/dist/cli/commands/types.js +37 -0
  23. package/dist/cli/commands/viewer.d.ts +6 -0
  24. package/dist/cli/commands/viewer.js +29 -0
  25. package/dist/cli/index.d.ts +2 -0
  26. package/dist/cli/index.js +108 -0
  27. package/dist/cli/output.d.ts +25 -0
  28. package/dist/cli/output.js +149 -0
  29. package/dist/cli/schema-prompt.d.ts +20 -0
  30. package/dist/cli/schema-prompt.js +66 -0
  31. package/dist/cli.d.ts +2 -0
  32. package/dist/cli.js +3 -0
  33. package/dist/client-cache.d.ts +105 -0
  34. package/dist/client-cache.js +916 -0
  35. package/dist/client.d.ts +64 -0
  36. package/dist/client.js +405 -0
  37. package/dist/config-public.d.ts +1 -0
  38. package/dist/config-public.js +1 -0
  39. package/dist/config.d.ts +54 -0
  40. package/dist/config.js +2 -0
  41. package/dist/csv.d.ts +1 -0
  42. package/dist/csv.js +1 -0
  43. package/dist/db.d.ts +3 -0
  44. package/dist/db.js +3 -0
  45. package/dist/doctor.d.ts +1 -0
  46. package/dist/doctor.js +1 -0
  47. package/dist/errors.d.ts +1 -0
  48. package/dist/errors.js +1 -0
  49. package/dist/features/config/defaults.d.ts +98 -0
  50. package/dist/features/config/defaults.js +95 -0
  51. package/dist/features/config/load.d.ts +11 -0
  52. package/dist/features/config/load.js +265 -0
  53. package/dist/features/config/public.d.ts +17 -0
  54. package/dist/features/config/public.js +75 -0
  55. package/dist/features/doctor/duplicate-ids.d.ts +18 -0
  56. package/dist/features/doctor/duplicate-ids.js +79 -0
  57. package/dist/features/doctor/field-consistency.d.ts +17 -0
  58. package/dist/features/doctor/field-consistency.js +48 -0
  59. package/dist/features/doctor/index.d.ts +39 -0
  60. package/dist/features/doctor/index.js +177 -0
  61. package/dist/features/doctor/relations.d.ts +22 -0
  62. package/dist/features/doctor/relations.js +90 -0
  63. package/dist/features/doctor/schema-guidance.d.ts +35 -0
  64. package/dist/features/doctor/schema-guidance.js +184 -0
  65. package/dist/features/generate/registry.d.ts +14 -0
  66. package/dist/features/generate/registry.js +37 -0
  67. package/dist/features/http/registry.d.ts +46 -0
  68. package/dist/features/http/registry.js +86 -0
  69. package/dist/features/operations/index.d.ts +49 -0
  70. package/dist/features/operations/index.js +199 -0
  71. package/dist/features/operations/maps.d.ts +1 -0
  72. package/dist/features/operations/maps.js +10 -0
  73. package/dist/features/operations/readiness.d.ts +30 -0
  74. package/dist/features/operations/readiness.js +228 -0
  75. package/dist/features/operations/runtime.d.ts +57 -0
  76. package/dist/features/operations/runtime.js +288 -0
  77. package/dist/features/runtime/collection.d.ts +51 -0
  78. package/dist/features/runtime/collection.js +198 -0
  79. package/dist/features/runtime/db.d.ts +152 -0
  80. package/dist/features/runtime/db.js +824 -0
  81. package/dist/features/runtime/document.d.ts +43 -0
  82. package/dist/features/runtime/document.js +111 -0
  83. package/dist/features/runtime/fanout.d.ts +24 -0
  84. package/dist/features/runtime/fanout.js +77 -0
  85. package/dist/features/runtime/json-pointer.d.ts +5 -0
  86. package/dist/features/runtime/json-pointer.js +49 -0
  87. package/dist/features/runtime/scope-state.d.ts +44 -0
  88. package/dist/features/runtime/scope-state.js +185 -0
  89. package/dist/features/runtime/state.d.ts +1 -0
  90. package/dist/features/runtime/state.js +1 -0
  91. package/dist/features/schema/api.d.ts +107 -0
  92. package/dist/features/schema/api.js +460 -0
  93. package/dist/features/schema/builders.d.ts +86 -0
  94. package/dist/features/schema/builders.js +110 -0
  95. package/dist/features/schema/fields.d.ts +38 -0
  96. package/dist/features/schema/fields.js +296 -0
  97. package/dist/features/schema/generated.d.ts +29 -0
  98. package/dist/features/schema/generated.js +32 -0
  99. package/dist/features/schema/locator.d.ts +16 -0
  100. package/dist/features/schema/locator.js +135 -0
  101. package/dist/features/schema/manifest.d.ts +91 -0
  102. package/dist/features/schema/manifest.js +384 -0
  103. package/dist/features/schema/metadata.d.ts +30 -0
  104. package/dist/features/schema/metadata.js +75 -0
  105. package/dist/features/schema/project.d.ts +46 -0
  106. package/dist/features/schema/project.js +442 -0
  107. package/dist/features/schema/relations.d.ts +38 -0
  108. package/dist/features/schema/relations.js +109 -0
  109. package/dist/features/schema/resolvers.d.ts +36 -0
  110. package/dist/features/schema/resolvers.js +111 -0
  111. package/dist/features/schema/resource.d.ts +75 -0
  112. package/dist/features/schema/resource.js +253 -0
  113. package/dist/features/schema/source-definitions.d.ts +21 -0
  114. package/dist/features/schema/source-definitions.js +29 -0
  115. package/dist/features/schema/sources.d.ts +83 -0
  116. package/dist/features/schema/sources.js +689 -0
  117. package/dist/features/schema/standard-schema.d.ts +57 -0
  118. package/dist/features/schema/standard-schema.js +232 -0
  119. package/dist/features/schema/validation.d.ts +69 -0
  120. package/dist/features/schema/validation.js +434 -0
  121. package/dist/features/storage/events.d.ts +12 -0
  122. package/dist/features/storage/events.js +30 -0
  123. package/dist/features/storage/json.d.ts +112 -0
  124. package/dist/features/storage/json.js +239 -0
  125. package/dist/features/storage/memory.d.ts +30 -0
  126. package/dist/features/storage/memory.js +44 -0
  127. package/dist/features/storage/resource-json.d.ts +31 -0
  128. package/dist/features/storage/resource-json.js +76 -0
  129. package/dist/features/storage/runtime.d.ts +37 -0
  130. package/dist/features/storage/runtime.js +184 -0
  131. package/dist/features/storage/source-metadata.d.ts +20 -0
  132. package/dist/features/storage/source-metadata.js +25 -0
  133. package/dist/features/storage/source.d.ts +37 -0
  134. package/dist/features/storage/source.js +60 -0
  135. package/dist/features/storage/static.d.ts +29 -0
  136. package/dist/features/storage/static.js +42 -0
  137. package/dist/features/sync/defaults.d.ts +21 -0
  138. package/dist/features/sync/defaults.js +21 -0
  139. package/dist/features/sync/index.d.ts +35 -0
  140. package/dist/features/sync/index.js +85 -0
  141. package/dist/features/sync/mirror-state.d.ts +14 -0
  142. package/dist/features/sync/mirror-state.js +4 -0
  143. package/dist/features/sync/runtime-dirs.d.ts +5 -0
  144. package/dist/features/sync/runtime-dirs.js +9 -0
  145. package/dist/features/sync/source-writes.d.ts +15 -0
  146. package/dist/features/sync/source-writes.js +27 -0
  147. package/dist/features/sync/synthetic-seed.d.ts +26 -0
  148. package/dist/features/sync/synthetic-seed.js +83 -0
  149. package/dist/features/viewer/manifest.d.ts +148 -0
  150. package/dist/features/viewer/manifest.js +165 -0
  151. package/dist/fs-utils.d.ts +1 -0
  152. package/dist/fs-utils.js +1 -0
  153. package/dist/generate/hono/app.d.ts +6 -0
  154. package/dist/generate/hono/app.js +51 -0
  155. package/dist/generate/hono/graphql.d.ts +7 -0
  156. package/dist/generate/hono/graphql.js +53 -0
  157. package/dist/generate/hono/index.d.ts +55 -0
  158. package/dist/generate/hono/index.js +140 -0
  159. package/dist/generate/hono/package.d.ts +6 -0
  160. package/dist/generate/hono/package.js +44 -0
  161. package/dist/generate/hono/readme.d.ts +13 -0
  162. package/dist/generate/hono/readme.js +28 -0
  163. package/dist/generate/hono/repository.d.ts +1 -0
  164. package/dist/generate/hono/repository.js +27 -0
  165. package/dist/generate/hono/rest.d.ts +1 -0
  166. package/dist/generate/hono/rest.js +38 -0
  167. package/dist/generate/hono/schema.d.ts +13 -0
  168. package/dist/generate/hono/schema.js +18 -0
  169. package/dist/generate/hono/sqlite.d.ts +20 -0
  170. package/dist/generate/hono/sqlite.js +266 -0
  171. package/dist/generate/hono/validators.d.ts +1 -0
  172. package/dist/generate/hono/validators.js +141 -0
  173. package/dist/generate/hono.d.ts +1 -0
  174. package/dist/generate/hono.js +1 -0
  175. package/dist/graphql/execute.d.ts +14 -0
  176. package/dist/graphql/execute.js +719 -0
  177. package/dist/graphql/http.d.ts +15 -0
  178. package/dist/graphql/http.js +29 -0
  179. package/dist/graphql/index.d.ts +3 -0
  180. package/dist/graphql/index.js +3 -0
  181. package/dist/graphql/parser.d.ts +54 -0
  182. package/dist/graphql/parser.js +433 -0
  183. package/dist/hono.d.ts +77 -0
  184. package/dist/hono.js +1 -0
  185. package/dist/index.d.ts +1065 -0
  186. package/dist/index.js +14 -0
  187. package/dist/integrations/hono.d.ts +136 -0
  188. package/dist/integrations/hono.js +508 -0
  189. package/dist/integrations/kv.d.ts +69 -0
  190. package/dist/integrations/kv.js +69 -0
  191. package/dist/integrations/postgres.d.ts +52 -0
  192. package/dist/integrations/postgres.js +113 -0
  193. package/dist/integrations/sqlite.d.ts +112 -0
  194. package/dist/integrations/sqlite.js +489 -0
  195. package/dist/integrations/vite.d.ts +45 -0
  196. package/dist/integrations/vite.js +111 -0
  197. package/dist/json.d.ts +48 -0
  198. package/dist/json.js +1 -0
  199. package/dist/jsonc.d.ts +1 -0
  200. package/dist/jsonc.js +1 -0
  201. package/dist/kv.d.ts +24 -0
  202. package/dist/kv.js +1 -0
  203. package/dist/mock.d.ts +1 -0
  204. package/dist/mock.js +1 -0
  205. package/dist/names.d.ts +1 -0
  206. package/dist/names.js +1 -0
  207. package/dist/operations.d.ts +3 -0
  208. package/dist/operations.js +3 -0
  209. package/dist/postgres.d.ts +24 -0
  210. package/dist/postgres.js +1 -0
  211. package/dist/redis.d.ts +14 -0
  212. package/dist/redis.js +1 -0
  213. package/dist/rest/formats.d.ts +80 -0
  214. package/dist/rest/formats.js +318 -0
  215. package/dist/rest/handler.d.ts +111 -0
  216. package/dist/rest/handler.js +833 -0
  217. package/dist/rest/shape.d.ts +33 -0
  218. package/dist/rest/shape.js +218 -0
  219. package/dist/schema-builders.d.ts +1 -0
  220. package/dist/schema-builders.js +1 -0
  221. package/dist/schema-manifest.d.ts +1 -0
  222. package/dist/schema-manifest.js +1 -0
  223. package/dist/schema.d.ts +193 -0
  224. package/dist/schema.js +6 -0
  225. package/dist/server.d.ts +116 -0
  226. package/dist/server.js +601 -0
  227. package/dist/shared/csv.d.ts +8 -0
  228. package/dist/shared/csv.js +149 -0
  229. package/dist/shared/errors.d.ts +40 -0
  230. package/dist/shared/errors.js +55 -0
  231. package/dist/shared/fs-utils.d.ts +4 -0
  232. package/dist/shared/fs-utils.js +30 -0
  233. package/dist/shared/jsonc.d.ts +2 -0
  234. package/dist/shared/jsonc.js +99 -0
  235. package/dist/shared/mock.d.ts +40 -0
  236. package/dist/shared/mock.js +83 -0
  237. package/dist/shared/names.d.ts +28 -0
  238. package/dist/shared/names.js +127 -0
  239. package/dist/shared/operations.d.ts +32 -0
  240. package/dist/shared/operations.js +302 -0
  241. package/dist/sqlite.d.ts +24 -0
  242. package/dist/sqlite.js +1 -0
  243. package/dist/state.d.ts +1 -0
  244. package/dist/state.js +1 -0
  245. package/dist/sync.d.ts +1 -0
  246. package/dist/sync.js +1 -0
  247. package/dist/tracing.d.ts +95 -0
  248. package/dist/tracing.js +260 -0
  249. package/dist/types.d.ts +51 -0
  250. package/dist/types.js +285 -0
  251. package/dist/viewer-manifest.d.ts +1 -0
  252. package/dist/viewer-manifest.js +1 -0
  253. package/dist/vite.d.ts +59 -0
  254. package/dist/vite.js +1 -0
  255. package/dist/web/json-viewer.d.ts +5 -0
  256. package/dist/web/json-viewer.js +176 -0
  257. package/dist/web/viewer.d.ts +12 -0
  258. package/dist/web/viewer.js +1015 -0
  259. package/docs/README.md +42 -0
  260. package/docs/architecture.md +112 -0
  261. package/docs/ci-and-release.md +177 -0
  262. package/docs/cms-storage-patterns.md +108 -0
  263. package/docs/concepts.md +141 -0
  264. package/docs/configuration.md +552 -0
  265. package/docs/fixtures-and-schemas.md +527 -0
  266. package/docs/fork-branch-workflows.md +108 -0
  267. package/docs/generated-files.md +174 -0
  268. package/docs/getting-started.md +165 -0
  269. package/docs/integrations.md +206 -0
  270. package/docs/json-production.md +120 -0
  271. package/docs/package-api.md +418 -0
  272. package/docs/prototype-to-production.md +378 -0
  273. package/docs/server-and-viewer.md +466 -0
  274. package/docs/store-graduation.md +120 -0
  275. package/docs/typescript-schema-sources.md +79 -0
  276. package/examples/advanced/README.md +55 -0
  277. package/examples/advanced/db/projects.schema.jsonc +44 -0
  278. package/examples/advanced/db/settings.jsonc +9 -0
  279. package/examples/advanced/db/users.json +23 -0
  280. package/examples/advanced/db/users.schema.mjs +31 -0
  281. package/examples/advanced/db.config.mjs +18 -0
  282. package/examples/advanced/example.json +5 -0
  283. package/examples/advanced/src/generated/db.types.d.ts +64 -0
  284. package/examples/basic/README.md +95 -0
  285. package/examples/basic/db/operations/get-user.jsonc +8 -0
  286. package/examples/basic/db/settings.json +7 -0
  287. package/examples/basic/db/users.schema.jsonc +36 -0
  288. package/examples/basic/db.config.mjs +68 -0
  289. package/examples/basic/example.json +5 -0
  290. package/examples/basic/src/generated/db.types.d.ts +39 -0
  291. package/examples/cms-json-publish/README.md +21 -0
  292. package/examples/cms-json-publish/db/navigation.json +7 -0
  293. package/examples/cms-json-publish/db/pages.json +18 -0
  294. package/examples/cms-json-publish/example.json +5 -0
  295. package/examples/cms-json-publish/src/cms.mjs +104 -0
  296. package/examples/computed-fields/README.md +93 -0
  297. package/examples/computed-fields/db/orders.schema.mjs +62 -0
  298. package/examples/computed-fields/db/posts.schema.mjs +59 -0
  299. package/examples/computed-fields/db/products.schema.mjs +39 -0
  300. package/examples/computed-fields/db/users.schema.mjs +43 -0
  301. package/examples/computed-fields/db.config.mjs +15 -0
  302. package/examples/computed-fields/example.json +5 -0
  303. package/examples/computed-fields/src/generated/db.types.d.ts +81 -0
  304. package/examples/content-collections/README.md +91 -0
  305. package/examples/content-collections/db/authors.json +12 -0
  306. package/examples/content-collections/db/authors.schema.mjs +20 -0
  307. package/examples/content-collections/db/blog/draft-roadmap.mdx +12 -0
  308. package/examples/content-collections/db/blog/index.schema.mjs +61 -0
  309. package/examples/content-collections/db/blog/launch-notes.mdx +15 -0
  310. package/examples/content-collections/db/docs/index.schema.mjs +32 -0
  311. package/examples/content-collections/db/docs/intro.mdx +11 -0
  312. package/examples/content-collections/db/docs/schema-workflow.mdx +10 -0
  313. package/examples/content-collections/db/site.schema.jsonc +21 -0
  314. package/examples/content-collections/db.config.mjs +26 -0
  315. package/examples/content-collections/example.json +5 -0
  316. package/examples/content-collections/src/content-preview.mjs +66 -0
  317. package/examples/content-collections/src/generated/db.types.d.ts +81 -0
  318. package/examples/csv/README.md +52 -0
  319. package/examples/csv/db/customers.csv +4 -0
  320. package/examples/csv/db.config.mjs +13 -0
  321. package/examples/csv/example.json +5 -0
  322. package/examples/data-first/README.md +54 -0
  323. package/examples/data-first/db/posts.json +16 -0
  324. package/examples/data-first/db/settings.json +8 -0
  325. package/examples/data-first/db/users.json +14 -0
  326. package/examples/data-first/db.config.mjs +13 -0
  327. package/examples/data-first/example.json +5 -0
  328. package/examples/diagnostics/README.md +55 -0
  329. package/examples/diagnostics/db/projects.schema.jsonc +27 -0
  330. package/examples/diagnostics/db/users.json +9 -0
  331. package/examples/diagnostics/db/users.schema.jsonc +23 -0
  332. package/examples/diagnostics/db.config.mjs +16 -0
  333. package/examples/diagnostics/example.json +5 -0
  334. package/examples/free-plan-upgrade/README.md +22 -0
  335. package/examples/free-plan-upgrade/db/appSettings.json +4 -0
  336. package/examples/free-plan-upgrade/db/projects.json +7 -0
  337. package/examples/free-plan-upgrade/example.json +5 -0
  338. package/examples/free-plan-upgrade/src/upgrade-tenant-to-paid.mjs +105 -0
  339. package/examples/hono-auth/README.md +74 -0
  340. package/examples/hono-auth/db/pages.schema.jsonc +44 -0
  341. package/examples/hono-auth/db/users.schema.jsonc +42 -0
  342. package/examples/hono-auth/db.config.mjs +17 -0
  343. package/examples/hono-auth/example.json +5 -0
  344. package/examples/hono-auth/package.json +14 -0
  345. package/examples/hono-auth/src/app.mjs +79 -0
  346. package/examples/hono-auth/src/server.mjs +13 -0
  347. package/examples/production-json/README.md +102 -0
  348. package/examples/production-json/db/appSettings.schema.jsonc +41 -0
  349. package/examples/production-json/db/featureFlags.schema.jsonc +84 -0
  350. package/examples/production-json/db/operations/get-control-plane.jsonc +6 -0
  351. package/examples/production-json/db/operations/get-feature-flag.jsonc +9 -0
  352. package/examples/production-json/db/operations/list-feature-flags.jsonc +8 -0
  353. package/examples/production-json/db/operations/read-public-settings.jsonc +8 -0
  354. package/examples/production-json/db.config.mjs +33 -0
  355. package/examples/production-json/example.json +5 -0
  356. package/examples/production-json/src/client-demo.mjs +28 -0
  357. package/examples/production-json/src/generated/db.types.d.ts +60 -0
  358. package/examples/relations/README.md +56 -0
  359. package/examples/relations/db/posts.schema.jsonc +46 -0
  360. package/examples/relations/db/users.schema.jsonc +34 -0
  361. package/examples/relations/db.config.mjs +13 -0
  362. package/examples/relations/example.json +5 -0
  363. package/examples/rest-client/README.md +54 -0
  364. package/examples/rest-client/db/settings.json +5 -0
  365. package/examples/rest-client/db/users.schema.jsonc +42 -0
  366. package/examples/rest-client/db.config.mjs +13 -0
  367. package/examples/rest-client/example.json +5 -0
  368. package/examples/rest-client/src/client-demo.mjs +24 -0
  369. package/examples/schema-first/README.md +55 -0
  370. package/examples/schema-first/db/auditEvents.schema.jsonc +24 -0
  371. package/examples/schema-first/db/settings.schema.jsonc +29 -0
  372. package/examples/schema-first/db/users.schema.jsonc +36 -0
  373. package/examples/schema-first/db.config.mjs +15 -0
  374. package/examples/schema-first/example.json +5 -0
  375. package/examples/schema-first/src/generated/db.types.d.ts +47 -0
  376. package/examples/schema-manifest/README.md +50 -0
  377. package/examples/schema-manifest/db/projects.schema.jsonc +48 -0
  378. package/examples/schema-manifest/db/users.schema.jsonc +35 -0
  379. package/examples/schema-manifest/db.config.mjs +41 -0
  380. package/examples/schema-manifest/example.json +5 -0
  381. package/examples/schema-manifest/src/generated/db.schema.json +130 -0
  382. package/examples/schema-manifest/src/generated/db.types.d.ts +50 -0
  383. package/examples/schema-ui/README.md +103 -0
  384. package/examples/schema-ui/db/pages.schema.jsonc +53 -0
  385. package/examples/schema-ui/db/users.schema.jsonc +30 -0
  386. package/examples/schema-ui/db.config.mjs +55 -0
  387. package/examples/schema-ui/example.json +5 -0
  388. package/examples/schema-ui/src/cms-ssr.mjs +276 -0
  389. package/examples/schema-ui/src/generated/db.schema.json +133 -0
  390. package/examples/schema-ui/src/generated/db.types.d.ts +46 -0
  391. package/examples/schema-ui/src/render-admin.mjs +175 -0
  392. package/examples/schema-ui/src/schema-ui-ssr-handler.mjs +149 -0
  393. package/examples/schema-ui/src/start-schema-ui-server.mjs +140 -0
  394. package/examples/standard-schema/README.md +55 -0
  395. package/examples/standard-schema/db/settings.schema.mjs +22 -0
  396. package/examples/standard-schema/db/users.schema.mjs +72 -0
  397. package/examples/standard-schema/example.json +5 -0
  398. package/package.json +108 -0
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ export { loadConfig } from './config.js';
2
+ export { mergeManifest, parseFixturePath, resourceNameFromPath } from './config-public.js';
3
+ export { createDbClient, createIndexedDbCacheStorage } from './client.js';
4
+ export { openDb, Db, DbCollection, DbDocument } from './db.js';
5
+ export { runDbDoctor } from './doctor.js';
6
+ export { executeGraphql, executeGraphqlBatch, parseGraphql } from './graphql/index.js';
7
+ export { generateHonoStarter, renderHonoStarter } from './generate/hono.js';
8
+ export { createDbSchema, createSchemaValidator, loadDbSchema, loadProjectSchema, makeGeneratedSchema, normalizeSchemaLoadMode, resolveSchemaLocator } from './schema.js';
9
+ export { generateSchemaManifest, renderSchemaManifest } from './schema-manifest.js';
10
+ export { generateViewerManifest, renderViewerManifest } from './viewer-manifest.js';
11
+ export { createDbRequestHandler, startDbServer } from './server.js';
12
+ export { syncDb } from './sync.js';
13
+ export { generateTypes, renderTypes } from './types.js';
14
+ export { buildOperationManifest, createDbOperationHandler, hashOperation } from './operations.js';
@@ -0,0 +1,136 @@
1
+ type HonoResourceKind = 'collection' | 'document' | string;
2
+ type HonoRouteMethod = 'list' | 'get' | 'create' | 'patch' | 'delete' | 'put' | 'operation' | string;
3
+ type HonoHookName = 'beforeList' | 'beforeGet' | 'beforeCreate' | 'beforePatch' | 'beforeDelete' | 'beforePut';
4
+ type HonoRequestLike = {
5
+ url?: string;
6
+ param(name: string): string;
7
+ json(): Promise<unknown>;
8
+ text?(): Promise<string>;
9
+ raw?: {
10
+ text?(): Promise<string>;
11
+ };
12
+ header?(name: string): string | undefined;
13
+ };
14
+ type HonoContextLike = {
15
+ req: HonoRequestLike;
16
+ set?(key: string, value: unknown): unknown;
17
+ get?(key: string): unknown;
18
+ json(body: unknown, status?: number): unknown;
19
+ text(body: string, status?: number): unknown;
20
+ body(body: unknown, status?: number, headers?: Record<string, unknown>): unknown;
21
+ header(name: string, value: string): unknown;
22
+ [key: string]: unknown;
23
+ };
24
+ type HonoNext = () => void | Promise<void>;
25
+ type HonoHandler = (context: HonoContextLike) => unknown | Promise<unknown>;
26
+ type HonoMiddleware = (context: HonoContextLike, next: HonoNext) => unknown | Promise<unknown>;
27
+ type HonoAppLike = {
28
+ use(path: string, middleware: HonoMiddleware): unknown;
29
+ onError(handler: (error: StatusError, context: HonoContextLike) => unknown): unknown;
30
+ get(path: string, handler: HonoHandler): unknown;
31
+ post(path: string, handler: HonoHandler): unknown;
32
+ patch(path: string, handler: HonoHandler): unknown;
33
+ delete(path: string, handler: HonoHandler): unknown;
34
+ put(path: string, handler: HonoHandler): unknown;
35
+ };
36
+ type HonoRoutesAppLike = Pick<HonoAppLike, 'get' | 'post' | 'patch' | 'delete' | 'put'>;
37
+ type DbConfig = {
38
+ server?: {
39
+ maxBodyBytes?: number;
40
+ trace?: boolean | {
41
+ enabled?: boolean;
42
+ slowMs?: number;
43
+ console?: boolean;
44
+ events?: boolean;
45
+ header?: string;
46
+ } | null;
47
+ [key: string]: unknown;
48
+ };
49
+ operations?: {
50
+ enabled?: boolean;
51
+ [key: string]: unknown;
52
+ };
53
+ [key: string]: unknown;
54
+ };
55
+ type HonoCollection = {
56
+ all(): Promise<Record<string, unknown>[]>;
57
+ get(id: string): Promise<Record<string, unknown> | null>;
58
+ create(body: unknown): Promise<Record<string, unknown>>;
59
+ patch(id: string, body: unknown): Promise<Record<string, unknown> | null>;
60
+ delete(id: string): Promise<unknown>;
61
+ };
62
+ type HonoDocument = {
63
+ all(): Promise<Record<string, unknown>>;
64
+ put(body: unknown): Promise<Record<string, unknown>>;
65
+ update(body: unknown): Promise<Record<string, unknown>>;
66
+ };
67
+ type HonoResource = {
68
+ name: string;
69
+ kind: HonoResourceKind;
70
+ routePath?: string;
71
+ [key: string]: unknown;
72
+ };
73
+ type HonoDb = {
74
+ config: DbConfig;
75
+ resources: Map<string, HonoResource>;
76
+ collection(name: string): HonoCollection;
77
+ document(name: string): HonoDocument;
78
+ events?: {
79
+ emit?(event: unknown): unknown;
80
+ };
81
+ [key: string]: unknown;
82
+ };
83
+ type HonoHookContext = Record<string, unknown> & {
84
+ c: HonoContextLike;
85
+ db: HonoDb;
86
+ resource: HonoResource | null;
87
+ resourceName: string | null;
88
+ method: HonoRouteMethod;
89
+ id?: string;
90
+ body?: Record<string, unknown>;
91
+ ref?: string;
92
+ };
93
+ type HonoHook = (context: HonoHookContext) => unknown | Promise<unknown>;
94
+ type HonoResourceRouteOptions = {
95
+ methods?: unknown[];
96
+ hooks?: Partial<Record<HonoHookName, HonoHook>>;
97
+ [key: string]: unknown;
98
+ } | false;
99
+ type HonoRouteOptions = Record<string, unknown> & {
100
+ prefix?: string;
101
+ resources?: unknown[];
102
+ exclude?: unknown[];
103
+ methods?: unknown[];
104
+ trace?: unknown;
105
+ hooks?: Partial<Record<HonoHookName, HonoHook>>;
106
+ lifecycleHooks?: {
107
+ beforeRequest?: HonoHook;
108
+ beforeWrite?: HonoHook;
109
+ [key: string]: unknown;
110
+ };
111
+ resourceOptions?: Record<string, HonoResourceRouteOptions>;
112
+ resourcesOptions?: Record<string, HonoResourceRouteOptions>;
113
+ operations?: boolean | 'auto' | Record<string, unknown>;
114
+ };
115
+ type HonoAppOptions = HonoRouteOptions & {
116
+ api?: string | string[];
117
+ restRoutes?: HonoRouteOptions;
118
+ rest?: HonoRouteOptions;
119
+ graphqlPath?: string;
120
+ graphql?: {
121
+ path?: string;
122
+ [key: string]: unknown;
123
+ };
124
+ storage?: {
125
+ kind?: string;
126
+ [key: string]: unknown;
127
+ };
128
+ };
129
+ type StatusError = Error & {
130
+ status?: number;
131
+ };
132
+ export declare function createDbHonoApp(options?: HonoAppOptions): Promise<HonoAppLike>;
133
+ export declare function dbContext(dbOrOptions?: HonoDb | HonoAppOptions): HonoMiddleware;
134
+ export declare function createDbContext(options?: HonoAppOptions): Promise<HonoMiddleware>;
135
+ export declare function registerDbRoutes(app: HonoRoutesAppLike, db: HonoDb, options?: HonoRouteOptions): void;
136
+ export {};
@@ -0,0 +1,508 @@
1
+ import { openDb } from '../db.js';
2
+ import { dbError, serializeError } from '../errors.js';
3
+ import { executeGraphql } from '../graphql/index.js';
4
+ import { resolveResource } from '../names.js';
5
+ import { createDbOperationHandler } from '../operations.js';
6
+ import { shapeCollectionRead } from '../rest/shape.js';
7
+ import { makeGeneratedSchema } from '../schema.js';
8
+ import { openSqliteDb } from '../sqlite.js';
9
+ import { createRequestTrace, tracePhase } from '../tracing.js';
10
+ export async function createDbHonoApp(options = {}) {
11
+ const { Hono } = await importHono();
12
+ const app = new Hono();
13
+ const db = await openHonoDb(options);
14
+ const api = normalizeApi(options.api ?? ['rest']);
15
+ app.use('*', dbContext(db));
16
+ app.onError((error, c) => c.json(serializeError(error, 'HONO_DB_ERROR'), error.status ?? 500));
17
+ if (api.includes('rest')) {
18
+ const restOptions = options.restRoutes ?? options.rest ?? {};
19
+ registerDbRoutes(app, db, {
20
+ ...restOptions,
21
+ trace: restOptions.trace ?? options.trace,
22
+ });
23
+ }
24
+ if (api.includes('graphql')) {
25
+ const graphqlPath = options.graphqlPath ?? options.graphql?.path ?? '/graphql';
26
+ app.get(graphqlPath, (c) => c.text(makeGeneratedSchema([...db.resources.values()]).graphql));
27
+ app.post(graphqlPath, async (c) => c.json(await executeGraphql(db, await c.req.json())));
28
+ }
29
+ return app;
30
+ }
31
+ export function dbContext(dbOrOptions = {}) {
32
+ const db = typeof dbOrOptions?.collection === 'function'
33
+ ? dbOrOptions
34
+ : null;
35
+ let dbPromise = db ? Promise.resolve(db) : null;
36
+ return async (c, next) => {
37
+ dbPromise ??= openHonoDb(dbOrOptions);
38
+ c.set('db', await dbPromise);
39
+ await next();
40
+ };
41
+ }
42
+ export async function createDbContext(options = {}) {
43
+ return dbContext(await openHonoDb(options));
44
+ }
45
+ async function openHonoDb(options) {
46
+ if (options.storage?.kind === 'sqlite') {
47
+ return await openSqliteDb(options);
48
+ }
49
+ return await openDb(options);
50
+ }
51
+ export function registerDbRoutes(app, db, options = {}) {
52
+ registerOperationRoutes(app, db, options);
53
+ for (const resource of restResources(db, options)) {
54
+ if (resource.kind === 'collection') {
55
+ const collectionPath = joinPaths(options.prefix, resource.routePath);
56
+ app.get(collectionPath, async (c) => {
57
+ return withHonoTrace(options, db, resource, 'list', c, 'GET', async (trace) => {
58
+ const shortCircuit = await runHonoHooks(options, db, resource, 'list', c, {}, trace);
59
+ if (shortCircuit !== undefined) {
60
+ return shortCircuit;
61
+ }
62
+ const url = new URL(c.req.url ?? collectionPath, 'http://db.local');
63
+ const records = await tracePhase(trace, 'collection-read', () => db.collection(resource.name).all(), {
64
+ resource: resource.name,
65
+ operation: 'all',
66
+ });
67
+ const shaped = await tracePhase(trace, 'response-shaping', () => shapeCollectionRead(db, resource, records, url, { allowPagination: true }), {
68
+ resource: resource.name,
69
+ });
70
+ return tracePhase(trace, 'response-formatting', () => c.json(shaped), {
71
+ resource: resource.name,
72
+ target: 'resource',
73
+ });
74
+ });
75
+ });
76
+ app.get(`${collectionPath}/:id`, async (c) => {
77
+ const id = c.req.param('id');
78
+ return withHonoTrace(options, db, resource, 'get', c, 'GET', async (trace) => {
79
+ const shortCircuit = await runHonoHooks(options, db, resource, 'get', c, { id }, trace);
80
+ if (shortCircuit !== undefined) {
81
+ return shortCircuit;
82
+ }
83
+ const record = await tracePhase(trace, 'collection-read', () => db.collection(resource.name).get(id), {
84
+ resource: resource.name,
85
+ operation: 'get',
86
+ });
87
+ const url = new URL(c.req.url ?? `${collectionPath}/${id}`, 'http://db.local');
88
+ const body = record
89
+ ? await tracePhase(trace, 'response-shaping', () => shapeCollectionRead(db, resource, [record], url, { allowPagination: false }), {
90
+ resource: resource.name,
91
+ })
92
+ : null;
93
+ return tracePhase(trace, 'response-formatting', () => (record ? c.json(body[0]) : c.json({ error: 'Not found' }, 404)), {
94
+ resource: resource.name,
95
+ target: 'resource',
96
+ });
97
+ }, { id });
98
+ });
99
+ app.post(collectionPath, async (c) => {
100
+ return withHonoTrace(options, db, resource, 'create', c, 'POST', async (trace) => {
101
+ const body = await tracePhase(trace, 'request-body', () => c.req.json());
102
+ const shortCircuit = await runHonoHooks(options, db, resource, 'create', c, { body }, trace);
103
+ if (shortCircuit !== undefined) {
104
+ return shortCircuit;
105
+ }
106
+ const record = await tracePhase(trace, 'collection-write', () => db.collection(resource.name).create(body), {
107
+ resource: resource.name,
108
+ operation: 'create',
109
+ });
110
+ return tracePhase(trace, 'response-formatting', () => c.json(record, 201), {
111
+ resource: resource.name,
112
+ target: 'resource',
113
+ });
114
+ });
115
+ });
116
+ app.patch(`${collectionPath}/:id`, async (c) => {
117
+ const id = c.req.param('id');
118
+ return withHonoTrace(options, db, resource, 'patch', c, 'PATCH', async (trace) => {
119
+ const body = await tracePhase(trace, 'request-body', () => c.req.json());
120
+ const shortCircuit = await runHonoHooks(options, db, resource, 'patch', c, { id, body }, trace);
121
+ if (shortCircuit !== undefined) {
122
+ return shortCircuit;
123
+ }
124
+ const record = await tracePhase(trace, 'collection-write', () => db.collection(resource.name).patch(id, body), {
125
+ resource: resource.name,
126
+ operation: 'patch',
127
+ });
128
+ return tracePhase(trace, 'response-formatting', () => (record ? c.json(record) : c.json({ error: 'Not found' }, 404)), {
129
+ resource: resource.name,
130
+ target: 'resource',
131
+ });
132
+ }, { id });
133
+ });
134
+ app.delete(`${collectionPath}/:id`, async (c) => {
135
+ const id = c.req.param('id');
136
+ return withHonoTrace(options, db, resource, 'delete', c, 'DELETE', async (trace) => {
137
+ const shortCircuit = await runHonoHooks(options, db, resource, 'delete', c, { id }, trace);
138
+ if (shortCircuit !== undefined) {
139
+ return shortCircuit;
140
+ }
141
+ const deleted = await tracePhase(trace, 'collection-write', () => db.collection(resource.name).delete(id), {
142
+ resource: resource.name,
143
+ operation: 'delete',
144
+ });
145
+ return tracePhase(trace, 'response-formatting', () => (deleted ? c.body(null, 204) : c.json({ error: 'Not found' }, 404)), {
146
+ resource: resource.name,
147
+ target: 'resource',
148
+ });
149
+ }, { id });
150
+ });
151
+ }
152
+ else {
153
+ const documentPath = joinPaths(options.prefix, resource.routePath);
154
+ app.get(documentPath, async (c) => {
155
+ return withHonoTrace(options, db, resource, 'get', c, 'GET', async (trace) => {
156
+ const shortCircuit = await runHonoHooks(options, db, resource, 'get', c, {}, trace);
157
+ if (shortCircuit !== undefined) {
158
+ return shortCircuit;
159
+ }
160
+ const document = await tracePhase(trace, 'document-read', () => db.document(resource.name).all(), {
161
+ resource: resource.name,
162
+ operation: 'all',
163
+ });
164
+ return tracePhase(trace, 'response-formatting', () => c.json(document), {
165
+ resource: resource.name,
166
+ target: 'resource',
167
+ });
168
+ });
169
+ });
170
+ app.put(documentPath, async (c) => {
171
+ return withHonoTrace(options, db, resource, 'put', c, 'PUT', async (trace) => {
172
+ const body = await tracePhase(trace, 'request-body', () => c.req.json());
173
+ const shortCircuit = await runHonoHooks(options, db, resource, 'put', c, { body }, trace);
174
+ if (shortCircuit !== undefined) {
175
+ return shortCircuit;
176
+ }
177
+ const document = await tracePhase(trace, 'document-write', () => db.document(resource.name).put(body), {
178
+ resource: resource.name,
179
+ operation: 'put',
180
+ });
181
+ return tracePhase(trace, 'response-formatting', () => c.json(document), {
182
+ resource: resource.name,
183
+ target: 'resource',
184
+ });
185
+ });
186
+ });
187
+ app.patch(documentPath, async (c) => {
188
+ return withHonoTrace(options, db, resource, 'patch', c, 'PATCH', async (trace) => {
189
+ const body = await tracePhase(trace, 'request-body', () => c.req.json());
190
+ const shortCircuit = await runHonoHooks(options, db, resource, 'patch', c, { body }, trace);
191
+ if (shortCircuit !== undefined) {
192
+ return shortCircuit;
193
+ }
194
+ const document = await tracePhase(trace, 'document-write', () => db.document(resource.name).update(body), {
195
+ resource: resource.name,
196
+ operation: 'patch',
197
+ });
198
+ return tracePhase(trace, 'response-formatting', () => c.json(document), {
199
+ resource: resource.name,
200
+ target: 'resource',
201
+ });
202
+ });
203
+ });
204
+ }
205
+ }
206
+ }
207
+ function registerOperationRoutes(app, db, options) {
208
+ const operationOptions = honoOperationOptions(db, options);
209
+ if (!operationOptions) {
210
+ return;
211
+ }
212
+ const operationHandler = createDbOperationHandler(db, operationOptions);
213
+ const operationPath = joinPaths(options.prefix, '/operations/:ref');
214
+ app.post(operationPath, async (c) => {
215
+ const ref = c.req.param('ref');
216
+ const trace = createRequestTrace(db, {
217
+ method: 'POST',
218
+ url: c.req?.url ?? operationPath,
219
+ }, {
220
+ trace: options.trace,
221
+ });
222
+ trace?.markHandled(undefined);
223
+ trace?.attachHonoHeader(c);
224
+ trace?.setRoute({
225
+ route: 'hono-operation',
226
+ operation: 'execute',
227
+ id: ref,
228
+ });
229
+ try {
230
+ const shortCircuit = await runHonoOperationHooks(options, db, ref, c, {}, trace);
231
+ if (shortCircuit !== undefined) {
232
+ trace?.finish(db, shortCircuit);
233
+ return shortCircuit;
234
+ }
235
+ const body = await tracePhase(trace, 'registered-operation-body', () => readHonoJsonBody(c, db));
236
+ const result = await tracePhase(trace, 'registered-operation-execution', () => operationHandler.executeRequest(ref, body, {
237
+ trace,
238
+ }), {
239
+ ref,
240
+ });
241
+ const response = sendHonoOperationResult(c, result);
242
+ trace?.finish(db, response);
243
+ return response;
244
+ }
245
+ catch (error) {
246
+ const statusError = error;
247
+ trace?.setError(statusError);
248
+ const response = c.json(serializeError(statusError, 'HONO_DB_OPERATION_ERROR'), statusError.status ?? 500);
249
+ trace?.finish(db, response);
250
+ return response;
251
+ }
252
+ });
253
+ }
254
+ function honoOperationOptions(db, options) {
255
+ if (options.operations === false) {
256
+ return null;
257
+ }
258
+ if (options.operations === undefined || options.operations === 'auto') {
259
+ return db.config.operations?.enabled === true ? true : null;
260
+ }
261
+ return options.operations;
262
+ }
263
+ function sendHonoOperationResult(c, result) {
264
+ const headers = result.headers ?? {};
265
+ for (const [name, value] of Object.entries(headers)) {
266
+ c.header(name, String(value));
267
+ }
268
+ const contentType = String(headers['content-type'] ?? '');
269
+ if (result.status === 204) {
270
+ return c.body(null, 204);
271
+ }
272
+ if (contentType.includes('application/json')) {
273
+ return c.json(result.body, result.status);
274
+ }
275
+ return c.body(result.rawBody ?? String(result.body ?? ''), result.status);
276
+ }
277
+ async function runHonoOperationHooks(options, db, ref, c, extras = {}, trace = null) {
278
+ const beforeRequest = options.lifecycleHooks?.beforeRequest;
279
+ if (typeof beforeRequest !== 'function') {
280
+ return undefined;
281
+ }
282
+ const context = {
283
+ c,
284
+ db,
285
+ resource: null,
286
+ resourceName: null,
287
+ method: 'operation',
288
+ ref,
289
+ ...extras,
290
+ };
291
+ const result = await tracePhase(trace, 'hono-hook', () => beforeRequest(context), {
292
+ hook: 'beforeRequest',
293
+ operation: 'operation',
294
+ ref,
295
+ });
296
+ if (result !== undefined) {
297
+ trace?.setRoute({
298
+ hook: 'beforeRequest',
299
+ shortCircuit: true,
300
+ });
301
+ }
302
+ return result;
303
+ }
304
+ async function readHonoJsonBody(c, db) {
305
+ const text = await readHonoBodyText(c);
306
+ if (text === null) {
307
+ return c.req.json();
308
+ }
309
+ const maxBytes = Number(db.config.server?.maxBodyBytes ?? 1048576);
310
+ const byteLength = Buffer.byteLength(text, 'utf8');
311
+ if (byteLength > maxBytes) {
312
+ throw dbError('JSON_BODY_TOO_LARGE', `Request body is too large. Received more than ${maxBytes} bytes.`, {
313
+ status: 413,
314
+ hint: 'Send a smaller JSON payload or increase server.maxBodyBytes in db.config.mjs for local development.',
315
+ details: {
316
+ maxBodyBytes: maxBytes,
317
+ },
318
+ });
319
+ }
320
+ const trimmed = text.trim();
321
+ if (!trimmed) {
322
+ return {};
323
+ }
324
+ try {
325
+ return JSON.parse(trimmed);
326
+ }
327
+ catch (error) {
328
+ const parseError = error;
329
+ throw dbError('REST_INVALID_JSON_BODY', 'Request body is not valid JSON.', {
330
+ status: 400,
331
+ hint: 'Check for trailing commas, unquoted property names, or an incomplete JSON object.',
332
+ details: {
333
+ parserMessage: parseError.message,
334
+ },
335
+ });
336
+ }
337
+ }
338
+ async function readHonoBodyText(c) {
339
+ if (typeof c.req?.text === 'function') {
340
+ return c.req.text();
341
+ }
342
+ if (typeof c.req?.raw?.text === 'function') {
343
+ return c.req.raw.text();
344
+ }
345
+ return null;
346
+ }
347
+ function restResources(db, options) {
348
+ const allow = normalizeResourceSet(db, options.resources);
349
+ const deny = normalizeResourceSet(db, options.exclude);
350
+ const methods = new Set((options.methods ?? []).map((method) => String(method).toLowerCase()));
351
+ return [...db.resources.values()].filter((resource) => {
352
+ if (allow && !allow.has(resource.name)) {
353
+ return false;
354
+ }
355
+ if (deny?.has(resource.name)) {
356
+ return false;
357
+ }
358
+ const resourceOptions = resourceRestOptions(options, resource);
359
+ if (resourceOptions === false) {
360
+ return false;
361
+ }
362
+ if (methods.size > 0 && !resourceMethods(resource).some((method) => methods.has(method))) {
363
+ return false;
364
+ }
365
+ return true;
366
+ });
367
+ }
368
+ async function withHonoTrace(options, db, resource, operation, c, httpMethod, handler, details = {}) {
369
+ const trace = createRequestTrace(db, {
370
+ method: httpMethod,
371
+ url: c.req?.url ?? resource.routePath ?? '/',
372
+ }, {
373
+ trace: options.trace,
374
+ });
375
+ trace?.markHandled(undefined);
376
+ trace?.attachHonoHeader(c);
377
+ trace?.setRoute({
378
+ route: 'hono-rest',
379
+ resource: resource.name,
380
+ operation,
381
+ ...details,
382
+ });
383
+ try {
384
+ const response = await handler(trace);
385
+ trace?.finish(db, response);
386
+ return response;
387
+ }
388
+ catch (error) {
389
+ trace?.setError(error);
390
+ trace?.finish(db, undefined);
391
+ throw error;
392
+ }
393
+ }
394
+ async function runHonoHooks(options, db, resource, method, c, extras = {}, trace = null) {
395
+ if (!methodAllowed(options, resource, method)) {
396
+ return c.json({ error: 'Method not allowed' }, 405);
397
+ }
398
+ const hookName = hookNameForMethod(method);
399
+ const context = {
400
+ c,
401
+ db,
402
+ resource,
403
+ resourceName: resource.name,
404
+ method,
405
+ ...extras,
406
+ };
407
+ const beforeRequest = options.lifecycleHooks?.beforeRequest;
408
+ const beforeWrite = isWriteMethod(method) ? options.lifecycleHooks?.beforeWrite : null;
409
+ const globalHook = options.hooks?.[hookName];
410
+ const resourceOptions = resourceRestOptions(options, resource);
411
+ const resourceHook = resourceOptions ? resourceOptions.hooks?.[hookName] : undefined;
412
+ const hooks = [
413
+ ['beforeRequest', beforeRequest],
414
+ ['beforeWrite', beforeWrite],
415
+ [hookName, globalHook],
416
+ [`resource:${hookName}`, resourceHook],
417
+ ];
418
+ for (const [name, hook] of hooks) {
419
+ if (typeof hook !== 'function') {
420
+ continue;
421
+ }
422
+ const result = await tracePhase(trace, 'hono-hook', () => hook(context), {
423
+ hook: name,
424
+ resource: resource.name,
425
+ operation: method,
426
+ });
427
+ if (result !== undefined) {
428
+ trace?.setRoute({
429
+ hook: name,
430
+ shortCircuit: true,
431
+ });
432
+ return result;
433
+ }
434
+ }
435
+ return undefined;
436
+ }
437
+ function isWriteMethod(method) {
438
+ return method === 'create'
439
+ || method === 'patch'
440
+ || method === 'put'
441
+ || method === 'delete';
442
+ }
443
+ function methodAllowed(options, resource, method) {
444
+ const globalMethods = normalizeMethodSet(options.methods);
445
+ const resourceOptions = resourceRestOptions(options, resource);
446
+ const resourceMethods = normalizeMethodSet(resourceOptions ? resourceOptions.methods : null);
447
+ return (!globalMethods || globalMethods.has(method))
448
+ && (!resourceMethods || resourceMethods.has(method));
449
+ }
450
+ function hookNameForMethod(method) {
451
+ switch (method) {
452
+ case 'list':
453
+ return 'beforeList';
454
+ case 'get':
455
+ return 'beforeGet';
456
+ case 'create':
457
+ return 'beforeCreate';
458
+ case 'patch':
459
+ return 'beforePatch';
460
+ case 'delete':
461
+ return 'beforeDelete';
462
+ case 'put':
463
+ return 'beforePut';
464
+ default:
465
+ return null;
466
+ }
467
+ }
468
+ function normalizeResourceSet(db, values) {
469
+ if (!Array.isArray(values)) {
470
+ return null;
471
+ }
472
+ return new Set(values.map((value) => resolveResource(db.resources, value).resource?.name ?? String(value)));
473
+ }
474
+ function normalizeMethodSet(values) {
475
+ if (!Array.isArray(values)) {
476
+ return null;
477
+ }
478
+ return new Set(values.map((value) => String(value).toLowerCase()));
479
+ }
480
+ function resourceRestOptions(options, resource) {
481
+ const configured = options.resourceOptions ?? options.resourcesOptions ?? {};
482
+ return configured[resource.name] ?? configured[resource.routePath?.slice(1)] ?? configured[resource.name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)];
483
+ }
484
+ function resourceMethods(resource) {
485
+ return resource.kind === 'collection'
486
+ ? ['list', 'get', 'create', 'patch', 'delete']
487
+ : ['get', 'put', 'patch'];
488
+ }
489
+ function joinPaths(prefix = '', routePath = '') {
490
+ const left = `/${String(prefix ?? '').replace(/^\/+/, '').replace(/\/+$/, '')}`;
491
+ const right = `/${String(routePath ?? '').replace(/^\/+/, '')}`;
492
+ if (left === '/') {
493
+ return right;
494
+ }
495
+ return `${left}${right === '/' ? '' : right}`;
496
+ }
497
+ function normalizeApi(value) {
498
+ return Array.isArray(value) ? value : String(value).split(',').map((item) => item.trim()).filter(Boolean);
499
+ }
500
+ async function importHono() {
501
+ try {
502
+ const moduleName = 'hono';
503
+ return await import(moduleName);
504
+ }
505
+ catch (error) {
506
+ throw new Error(`db/hono requires hono to be installed in your app: ${error.message}`);
507
+ }
508
+ }