@oyolincc/create 0.4.0 → 0.5.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 (391) hide show
  1. package/package.json +2 -2
  2. package/templates/hono-fullstack/.codegraph/.gitignore +5 -0
  3. package/templates/hono-fullstack/README.md +22 -1
  4. package/templates/hono-fullstack/_gitignore +1 -0
  5. package/templates/hono-fullstack/apps/server/package.json +7 -2
  6. package/templates/hono-fullstack/apps/server/src/adapters/cloudflare/entry.ts +4 -30
  7. package/templates/hono-fullstack/apps/server/src/adapters/nodejs/bootstrap.ts +20 -12
  8. package/templates/hono-fullstack/apps/server/src/adapters/nodejs/entry.ts +7 -57
  9. package/templates/hono-fullstack/apps/server/src/app.ts +37 -21
  10. package/templates/hono-fullstack/apps/server/src/config.ts +1 -1
  11. package/templates/hono-fullstack/apps/server/src/di-container.ts +51 -0
  12. package/templates/hono-fullstack/apps/server/src/infra/logger/getter.ts +1 -1
  13. package/templates/hono-fullstack/apps/server/src/infra/logger/pino.ts +21 -34
  14. package/templates/hono-fullstack/apps/server/src/infra/work-runner/errors.ts +22 -0
  15. package/templates/hono-fullstack/apps/server/src/infra/work-runner/pass-through/runner.ts +28 -22
  16. package/templates/hono-fullstack/apps/server/src/infra/work-runner/piscina/runner.ts +11 -34
  17. package/templates/hono-fullstack/apps/server/src/infra/work-runner/{example → piscina}/worker-entry.ts +6 -2
  18. package/templates/hono-fullstack/apps/server/src/infra/work-runner/types.ts +2 -16
  19. package/templates/hono-fullstack/apps/server/src/infra/work-runner/utils/business-error.ts +10 -5
  20. package/templates/hono-fullstack/apps/server/src/infra/work-runner/utils/message.ts +5 -17
  21. package/templates/hono-fullstack/apps/server/src/middlewares/cors.ts +16 -22
  22. package/templates/hono-fullstack/apps/server/src/middlewares/logger.ts +34 -0
  23. package/templates/hono-fullstack/apps/server/src/modules/example/module.ts +8 -0
  24. package/templates/hono-fullstack/apps/server/src/modules/example/queries.ts +8 -0
  25. package/templates/hono-fullstack/apps/server/src/modules/example/routes.ts +74 -68
  26. package/templates/hono-fullstack/apps/server/src/modules/example/service.test.ts +53 -0
  27. package/templates/hono-fullstack/apps/server/src/modules/example/service.ts +54 -0
  28. package/templates/hono-fullstack/apps/server/src/modules/example/types.ts +12 -0
  29. package/templates/hono-fullstack/apps/server/src/modules/example/work-task/tasks.test.ts +9 -35
  30. package/templates/hono-fullstack/apps/server/src/modules/example/work-task/tasks.ts +15 -46
  31. package/templates/hono-fullstack/apps/server/src/shared/errors/defs/index.ts +6 -1
  32. package/templates/hono-fullstack/apps/server/src/shared/errors/handler.ts +1 -1
  33. package/templates/hono-fullstack/apps/server/src/shared/network/openapi/index.ts +1 -1
  34. package/templates/hono-fullstack/apps/server/src/shared/types/app.ts +51 -0
  35. package/templates/hono-fullstack/apps/server/src/shared/types/db.ts +126 -0
  36. package/templates/hono-fullstack/apps/server/src/shared/utils/data-access/check.ts +19 -0
  37. package/templates/hono-fullstack/apps/server/src/shared/utils/data-access/model.ts +47 -0
  38. package/templates/hono-fullstack/apps/server/src/shared/utils/data-access/params.ts +105 -0
  39. package/templates/hono-fullstack/apps/server/src/shared/utils/data-access/query.test.ts +139 -0
  40. package/templates/hono-fullstack/apps/server/src/shared/utils/data-access/query.ts +236 -0
  41. package/templates/hono-fullstack/apps/server/vite.config.ts +2 -2
  42. package/templates/hono-fullstack/apps/server/wrangler.jsonc +1 -1
  43. package/templates/hono-fullstack/apps/stack/frontend/assets/styles.css +6 -0
  44. package/templates/hono-fullstack/apps/stack/frontend/components/general/ErrorMessage.tsx +3 -1
  45. package/templates/hono-fullstack/apps/stack/frontend/components/layouts/AppLayout.tsx +2 -1
  46. package/templates/hono-fullstack/apps/stack/frontend/components/layouts/Header.tsx +14 -2
  47. package/templates/hono-fullstack/apps/stack/frontend/components/layouts/Page.tsx +2 -1
  48. package/templates/hono-fullstack/apps/stack/frontend/components/layouts/PageContainer.tsx +4 -1
  49. package/templates/hono-fullstack/apps/stack/frontend/modules/example/api.ts +16 -9
  50. package/templates/hono-fullstack/apps/stack/frontend/modules/example/components/ExampleForm.tsx +25 -12
  51. package/templates/hono-fullstack/apps/stack/frontend/modules/example/components/ExampleList.tsx +13 -4
  52. package/templates/hono-fullstack/apps/stack/frontend/modules/example/hooks/api-hooks.ts +3 -3
  53. package/templates/hono-fullstack/apps/stack/frontend/routes/__root.tsx +1 -1
  54. package/templates/hono-fullstack/apps/stack/frontend/routes/index.tsx +16 -4
  55. package/templates/hono-fullstack/apps/stack/package.json +9 -4
  56. package/templates/hono-fullstack/apps/stack/panda.config.ts +31 -0
  57. package/templates/hono-fullstack/apps/stack/tsconfig.json +1 -0
  58. package/templates/hono-fullstack/apps/stack/turbo.json +20 -0
  59. package/templates/hono-fullstack/apps/stack/vite.config.ts +48 -12
  60. package/templates/hono-fullstack/apps/stack/wrangler.jsonc +1 -1
  61. package/templates/hono-fullstack/envs/.env.example.sqlite-d1 +1 -0
  62. package/templates/hono-fullstack/libs/db/drizzle-kit/sqlite-d1.config.ts +29 -10
  63. package/templates/hono-fullstack/libs/db/package.json +1 -0
  64. package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/columns.ts +1 -1
  65. package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/modules/examples/examples.ts +6 -3
  66. package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/vo.ts +7 -1
  67. package/templates/hono-fullstack/libs/definition/README.md +81 -0
  68. package/templates/hono-fullstack/libs/definition/package.json +3 -1
  69. package/templates/hono-fullstack/libs/definition/src/constants/index.ts +1 -0
  70. package/templates/hono-fullstack/libs/definition/src/constants/pagination.ts +3 -0
  71. package/templates/hono-fullstack/libs/definition/src/modules/common-contracts.ts +24 -0
  72. package/templates/hono-fullstack/libs/definition/src/modules/example/contracts.ts +34 -0
  73. package/templates/hono-fullstack/libs/definition/src/modules/example/index.ts +1 -16
  74. package/templates/hono-fullstack/libs/definition/src/modules/index.ts +2 -0
  75. package/templates/hono-fullstack/libs/definition/src/modules/vo-generated-types.ts +12 -0
  76. package/templates/hono-fullstack/libs/ui/.storybook/main.ts +32 -0
  77. package/templates/hono-fullstack/libs/ui/.storybook/panda.config.ts +22 -0
  78. package/templates/hono-fullstack/libs/ui/.storybook/preview.tsx +79 -0
  79. package/templates/hono-fullstack/libs/ui/.storybook/styles.css +1 -0
  80. package/templates/hono-fullstack/libs/ui/.storybook/vite.config.ts +37 -0
  81. package/templates/hono-fullstack/libs/ui/components.json +15 -0
  82. package/templates/hono-fullstack/libs/ui/package.json +114 -0
  83. package/templates/hono-fullstack/libs/ui/panda.config.ts +41 -0
  84. package/templates/hono-fullstack/libs/ui/src/Tooltip.tsx +47 -0
  85. package/templates/hono-fullstack/libs/ui/src/components/atoms/buttons/Button.tsx +80 -0
  86. package/templates/hono-fullstack/libs/ui/src/components/atoms/buttons/CloseButton.tsx +15 -0
  87. package/templates/hono-fullstack/libs/ui/src/components/atoms/buttons/IconButton.tsx +10 -0
  88. package/templates/hono-fullstack/libs/ui/src/components/atoms/collections/Combobox.tsx +91 -0
  89. package/templates/hono-fullstack/libs/ui/src/components/atoms/collections/Select.tsx +88 -0
  90. package/templates/hono-fullstack/libs/ui/src/components/atoms/collections/TreeView.tsx +142 -0
  91. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Avatar.tsx +64 -0
  92. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Badge.tsx +7 -0
  93. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Card.tsx +23 -0
  94. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Clipboard.tsx +77 -0
  95. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Icon.tsx +9 -0
  96. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Table.tsx +51 -0
  97. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Tag.tsx +23 -0
  98. package/templates/hono-fullstack/libs/ui/src/components/atoms/data-display/Timeline.tsx +33 -0
  99. package/templates/hono-fullstack/libs/ui/src/components/atoms/date-and-time/DatePicker.tsx +255 -0
  100. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Accordion.tsx +48 -0
  101. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Breadcrumb.tsx +50 -0
  102. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Collapsible.tsx +34 -0
  103. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Pagination.tsx +74 -0
  104. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Steps.tsx +91 -0
  105. package/templates/hono-fullstack/libs/ui/src/components/atoms/disclosure/Tabs.tsx +37 -0
  106. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/Alert.tsx +52 -0
  107. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/Progress.tsx +41 -0
  108. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/ProgressCircle.tsx +40 -0
  109. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/Skeleton.tsx +37 -0
  110. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/Spinner.tsx +7 -0
  111. package/templates/hono-fullstack/libs/ui/src/components/atoms/feedback/Toast.tsx +99 -0
  112. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Checkbox.tsx +95 -0
  113. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/ColorPicker.tsx +148 -0
  114. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Editable.tsx +44 -0
  115. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Field.tsx +36 -0
  116. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Fieldset.tsx +34 -0
  117. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/FileUpload.tsx +143 -0
  118. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Input.tsx +7 -0
  119. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/InputAddon.tsx +7 -0
  120. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/InputGroup.tsx +61 -0
  121. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/NativeSelect.tsx +81 -0
  122. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/NumberInput.tsx +63 -0
  123. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/PasswordInput.tsx +76 -0
  124. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/PinInput.tsx +36 -0
  125. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/RadioCard.tsx +96 -0
  126. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/RadioGroup.tsx +61 -0
  127. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/RatingGroup.tsx +106 -0
  128. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/SegmentGroup.tsx +68 -0
  129. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Slider.tsx +87 -0
  130. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Switch.tsx +74 -0
  131. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/TagsInput.tsx +77 -0
  132. package/templates/hono-fullstack/libs/ui/src/components/atoms/forms/Textarea.tsx +7 -0
  133. package/templates/hono-fullstack/libs/ui/src/components/atoms/index.ts +98 -0
  134. package/templates/hono-fullstack/libs/ui/src/components/atoms/internal/AbsoluteCenter.tsx +7 -0
  135. package/templates/hono-fullstack/libs/ui/src/components/atoms/internal/Loader.tsx +69 -0
  136. package/templates/hono-fullstack/libs/ui/src/components/atoms/internal/Span.tsx +5 -0
  137. package/templates/hono-fullstack/libs/ui/src/components/atoms/internal/create-layout.ts +18 -0
  138. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/Float.tsx +7 -0
  139. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/Grid.tsx +17 -0
  140. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/Group.tsx +7 -0
  141. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/ScrollArea.tsx +46 -0
  142. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/Separator.tsx +26 -0
  143. package/templates/hono-fullstack/libs/ui/src/components/atoms/layout/Stack.tsx +54 -0
  144. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/Dialog.tsx +69 -0
  145. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/Drawer.tsx +49 -0
  146. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/HoverCard.tsx +37 -0
  147. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/Menu.tsx +74 -0
  148. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/OverlayManager.test.ts +124 -0
  149. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/OverlayManager.tsx +189 -0
  150. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/Popover.tsx +57 -0
  151. package/templates/hono-fullstack/libs/ui/src/components/atoms/overlays/Tooltip.tsx +37 -0
  152. package/templates/hono-fullstack/libs/ui/src/components/atoms/typography/Heading.tsx +6 -0
  153. package/templates/hono-fullstack/libs/ui/src/components/atoms/typography/Link.tsx +7 -0
  154. package/templates/hono-fullstack/libs/ui/src/components/atoms/typography/LinkOverlay.tsx +21 -0
  155. package/templates/hono-fullstack/libs/ui/src/components/atoms/typography/Text.tsx +6 -0
  156. package/templates/hono-fullstack/libs/ui/src/components/atoms/utilities/VisuallyHidden.tsx +13 -0
  157. package/templates/hono-fullstack/libs/ui/src/hooks.ts +242 -0
  158. package/templates/hono-fullstack/libs/ui/src/index.ts +19 -0
  159. package/templates/hono-fullstack/libs/ui/src/theme/animation-styles.ts +50 -0
  160. package/templates/hono-fullstack/libs/ui/src/theme/breakpoints.ts +7 -0
  161. package/templates/hono-fullstack/libs/ui/src/theme/conditions.ts +12 -0
  162. package/templates/hono-fullstack/libs/ui/src/theme/containers.ts +16 -0
  163. package/templates/hono-fullstack/libs/ui/src/theme/global-css.ts +12 -0
  164. package/templates/hono-fullstack/libs/ui/src/theme/keyframes.ts +157 -0
  165. package/templates/hono-fullstack/libs/ui/src/theme/layer-styles.ts +11 -0
  166. package/templates/hono-fullstack/libs/ui/src/theme/patterns/grid.ts +51 -0
  167. package/templates/hono-fullstack/libs/ui/src/theme/patterns/index.ts +60 -0
  168. package/templates/hono-fullstack/libs/ui/src/theme/patterns/stack.ts +46 -0
  169. package/templates/hono-fullstack/libs/ui/src/theme/recipes/absolute-center.ts +38 -0
  170. package/templates/hono-fullstack/libs/ui/src/theme/recipes/accordion.ts +68 -0
  171. package/templates/hono-fullstack/libs/ui/src/theme/recipes/alert.ts +83 -0
  172. package/templates/hono-fullstack/libs/ui/src/theme/recipes/avatar.ts +155 -0
  173. package/templates/hono-fullstack/libs/ui/src/theme/recipes/badge.ts +67 -0
  174. package/templates/hono-fullstack/libs/ui/src/theme/recipes/breadcrumb.ts +69 -0
  175. package/templates/hono-fullstack/libs/ui/src/theme/recipes/button.ts +149 -0
  176. package/templates/hono-fullstack/libs/ui/src/theme/recipes/card.ts +36 -0
  177. package/templates/hono-fullstack/libs/ui/src/theme/recipes/checkbox.ts +120 -0
  178. package/templates/hono-fullstack/libs/ui/src/theme/recipes/clipboard.ts +22 -0
  179. package/templates/hono-fullstack/libs/ui/src/theme/recipes/collapsible.ts +26 -0
  180. package/templates/hono-fullstack/libs/ui/src/theme/recipes/color-picker.ts +299 -0
  181. package/templates/hono-fullstack/libs/ui/src/theme/recipes/combobox.ts +141 -0
  182. package/templates/hono-fullstack/libs/ui/src/theme/recipes/date-picker.ts +302 -0
  183. package/templates/hono-fullstack/libs/ui/src/theme/recipes/dialog.ts +191 -0
  184. package/templates/hono-fullstack/libs/ui/src/theme/recipes/drawer.ts +170 -0
  185. package/templates/hono-fullstack/libs/ui/src/theme/recipes/editable.ts +64 -0
  186. package/templates/hono-fullstack/libs/ui/src/theme/recipes/field.ts +41 -0
  187. package/templates/hono-fullstack/libs/ui/src/theme/recipes/fieldset.ts +47 -0
  188. package/templates/hono-fullstack/libs/ui/src/theme/recipes/file-upload.ts +86 -0
  189. package/templates/hono-fullstack/libs/ui/src/theme/recipes/group.ts +78 -0
  190. package/templates/hono-fullstack/libs/ui/src/theme/recipes/heading.ts +24 -0
  191. package/templates/hono-fullstack/libs/ui/src/theme/recipes/hover-card.ts +47 -0
  192. package/templates/hono-fullstack/libs/ui/src/theme/recipes/icon.ts +25 -0
  193. package/templates/hono-fullstack/libs/ui/src/theme/recipes/index.ts +120 -0
  194. package/templates/hono-fullstack/libs/ui/src/theme/recipes/input-addon.ts +51 -0
  195. package/templates/hono-fullstack/libs/ui/src/theme/recipes/input-group.ts +77 -0
  196. package/templates/hono-fullstack/libs/ui/src/theme/recipes/input.ts +99 -0
  197. package/templates/hono-fullstack/libs/ui/src/theme/recipes/link.ts +36 -0
  198. package/templates/hono-fullstack/libs/ui/src/theme/recipes/menu.ts +114 -0
  199. package/templates/hono-fullstack/libs/ui/src/theme/recipes/native-select.ts +92 -0
  200. package/templates/hono-fullstack/libs/ui/src/theme/recipes/number-input.ts +91 -0
  201. package/templates/hono-fullstack/libs/ui/src/theme/recipes/pagination.ts +9 -0
  202. package/templates/hono-fullstack/libs/ui/src/theme/recipes/pin-input.ts +33 -0
  203. package/templates/hono-fullstack/libs/ui/src/theme/recipes/popover.ts +78 -0
  204. package/templates/hono-fullstack/libs/ui/src/theme/recipes/progress-circle.ts +50 -0
  205. package/templates/hono-fullstack/libs/ui/src/theme/recipes/progress.ts +112 -0
  206. package/templates/hono-fullstack/libs/ui/src/theme/recipes/radio-card.ts +223 -0
  207. package/templates/hono-fullstack/libs/ui/src/theme/recipes/radio-group.ts +78 -0
  208. package/templates/hono-fullstack/libs/ui/src/theme/recipes/rating-group.ts +98 -0
  209. package/templates/hono-fullstack/libs/ui/src/theme/recipes/scroll-area.ts +119 -0
  210. package/templates/hono-fullstack/libs/ui/src/theme/recipes/segment-group.ts +162 -0
  211. package/templates/hono-fullstack/libs/ui/src/theme/recipes/select.ts +157 -0
  212. package/templates/hono-fullstack/libs/ui/src/theme/recipes/separator.ts +25 -0
  213. package/templates/hono-fullstack/libs/ui/src/theme/recipes/skeleton.ts +65 -0
  214. package/templates/hono-fullstack/libs/ui/src/theme/recipes/slider.ts +164 -0
  215. package/templates/hono-fullstack/libs/ui/src/theme/recipes/spinner.ts +34 -0
  216. package/templates/hono-fullstack/libs/ui/src/theme/recipes/steps.ts +162 -0
  217. package/templates/hono-fullstack/libs/ui/src/theme/recipes/switch.ts +150 -0
  218. package/templates/hono-fullstack/libs/ui/src/theme/recipes/table.ts +150 -0
  219. package/templates/hono-fullstack/libs/ui/src/theme/recipes/tabs.ts +128 -0
  220. package/templates/hono-fullstack/libs/ui/src/theme/recipes/tag.ts +114 -0
  221. package/templates/hono-fullstack/libs/ui/src/theme/recipes/tags-input.ts +201 -0
  222. package/templates/hono-fullstack/libs/ui/src/theme/recipes/text.ts +7 -0
  223. package/templates/hono-fullstack/libs/ui/src/theme/recipes/textarea.ts +90 -0
  224. package/templates/hono-fullstack/libs/ui/src/theme/recipes/timeline.ts +137 -0
  225. package/templates/hono-fullstack/libs/ui/src/theme/recipes/toast.ts +52 -0
  226. package/templates/hono-fullstack/libs/ui/src/theme/recipes/tooltip.ts +44 -0
  227. package/templates/hono-fullstack/libs/ui/src/theme/recipes/tree-view.ts +200 -0
  228. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/amber.ts +91 -0
  229. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/gray.ts +103 -0
  230. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/green.ts +88 -0
  231. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/index.ts +14 -0
  232. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/lime.ts +91 -0
  233. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/colors/red.ts +88 -0
  234. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/index.ts +8 -0
  235. package/templates/hono-fullstack/libs/ui/src/theme/semanticTokens/shadows.ts +46 -0
  236. package/templates/hono-fullstack/libs/ui/src/theme/text-styles.ts +82 -0
  237. package/templates/hono-fullstack/libs/ui/src/theme/tokens/animations.ts +8 -0
  238. package/templates/hono-fullstack/libs/ui/src/theme/tokens/aspect-ratio.ts +6 -0
  239. package/templates/hono-fullstack/libs/ui/src/theme/tokens/borders.ts +5 -0
  240. package/templates/hono-fullstack/libs/ui/src/theme/tokens/colors.ts +35 -0
  241. package/templates/hono-fullstack/libs/ui/src/theme/tokens/durations.ts +11 -0
  242. package/templates/hono-fullstack/libs/ui/src/theme/tokens/easings.ts +9 -0
  243. package/templates/hono-fullstack/libs/ui/src/theme/tokens/index.ts +42 -0
  244. package/templates/hono-fullstack/libs/ui/src/theme/tokens/radii.ts +13 -0
  245. package/templates/hono-fullstack/libs/ui/src/theme/tokens/sizes.ts +27 -0
  246. package/templates/hono-fullstack/libs/ui/src/theme/tokens/spacing.ts +41 -0
  247. package/templates/hono-fullstack/libs/ui/src/theme/tokens/typography.ts +86 -0
  248. package/templates/hono-fullstack/libs/ui/src/theme/tokens/z-index.ts +43 -0
  249. package/templates/hono-fullstack/libs/ui/stories/README.md +107 -0
  250. package/templates/hono-fullstack/libs/ui/stories/actions/Button.stories.tsx +260 -0
  251. package/templates/hono-fullstack/libs/ui/stories/actions/Clipboard.stories.tsx +87 -0
  252. package/templates/hono-fullstack/libs/ui/stories/actions/IconButton.stories.tsx +33 -0
  253. package/templates/hono-fullstack/libs/ui/stories/collections/Combobox.stories.tsx +334 -0
  254. package/templates/hono-fullstack/libs/ui/stories/collections/Select.stories.tsx +342 -0
  255. package/templates/hono-fullstack/libs/ui/stories/collections/TreeView.stories.tsx +252 -0
  256. package/templates/hono-fullstack/libs/ui/stories/color/ColorPicker.stories.tsx +217 -0
  257. package/templates/hono-fullstack/libs/ui/stories/date/DatePicker.stories.tsx +302 -0
  258. package/templates/hono-fullstack/libs/ui/stories/disclosure/Accordion.stories.tsx +105 -0
  259. package/templates/hono-fullstack/libs/ui/stories/disclosure/Collapsible.stories.tsx +55 -0
  260. package/templates/hono-fullstack/libs/ui/stories/disclosure/Steps.stories.tsx +208 -0
  261. package/templates/hono-fullstack/libs/ui/stories/disclosure/Tabs.stories.tsx +176 -0
  262. package/templates/hono-fullstack/libs/ui/stories/display/Avatar.stories.tsx +108 -0
  263. package/templates/hono-fullstack/libs/ui/stories/display/Badge.stories.tsx +90 -0
  264. package/templates/hono-fullstack/libs/ui/stories/display/Card.stories.tsx +121 -0
  265. package/templates/hono-fullstack/libs/ui/stories/display/Heading.stories.tsx +62 -0
  266. package/templates/hono-fullstack/libs/ui/stories/display/Icon.stories.tsx +51 -0
  267. package/templates/hono-fullstack/libs/ui/stories/display/Table.stories.tsx +222 -0
  268. package/templates/hono-fullstack/libs/ui/stories/display/Tag.stories.tsx +168 -0
  269. package/templates/hono-fullstack/libs/ui/stories/display/Text.stories.tsx +32 -0
  270. package/templates/hono-fullstack/libs/ui/stories/display/Timeline.stories.tsx +241 -0
  271. package/templates/hono-fullstack/libs/ui/stories/feedback/Alert.stories.tsx +122 -0
  272. package/templates/hono-fullstack/libs/ui/stories/feedback/Progress.stories.tsx +163 -0
  273. package/templates/hono-fullstack/libs/ui/stories/feedback/ProgressCircle.stories.tsx +176 -0
  274. package/templates/hono-fullstack/libs/ui/stories/feedback/Skeleton.stories.tsx +75 -0
  275. package/templates/hono-fullstack/libs/ui/stories/feedback/Spinner.stories.tsx +49 -0
  276. package/templates/hono-fullstack/libs/ui/stories/feedback/Toast.stories.tsx +145 -0
  277. package/templates/hono-fullstack/libs/ui/stories/forms/Checkbox.stories.tsx +281 -0
  278. package/templates/hono-fullstack/libs/ui/stories/forms/Editable.stories.tsx +94 -0
  279. package/templates/hono-fullstack/libs/ui/stories/forms/Field.stories.tsx +72 -0
  280. package/templates/hono-fullstack/libs/ui/stories/forms/Fieldset.stories.tsx +109 -0
  281. package/templates/hono-fullstack/libs/ui/stories/forms/FileUpload.stories.tsx +115 -0
  282. package/templates/hono-fullstack/libs/ui/stories/forms/Form.stories.tsx +120 -0
  283. package/templates/hono-fullstack/libs/ui/stories/forms/Input.stories.tsx +155 -0
  284. package/templates/hono-fullstack/libs/ui/stories/forms/InputGroup.stories.tsx +79 -0
  285. package/templates/hono-fullstack/libs/ui/stories/forms/NativeSelect.stories.tsx +160 -0
  286. package/templates/hono-fullstack/libs/ui/stories/forms/NumberInput.stories.tsx +149 -0
  287. package/templates/hono-fullstack/libs/ui/stories/forms/PasswordInput.stories.tsx +141 -0
  288. package/templates/hono-fullstack/libs/ui/stories/forms/PinInput.stories.tsx +155 -0
  289. package/templates/hono-fullstack/libs/ui/stories/forms/RadioCard.stories.tsx +265 -0
  290. package/templates/hono-fullstack/libs/ui/stories/forms/RadioGroup.stories.tsx +109 -0
  291. package/templates/hono-fullstack/libs/ui/stories/forms/RatingGroup.stories.tsx +123 -0
  292. package/templates/hono-fullstack/libs/ui/stories/forms/SegmentGroup.stories.tsx +130 -0
  293. package/templates/hono-fullstack/libs/ui/stories/forms/Slider.stories.tsx +190 -0
  294. package/templates/hono-fullstack/libs/ui/stories/forms/Switch.stories.tsx +124 -0
  295. package/templates/hono-fullstack/libs/ui/stories/forms/TagsInput.stories.tsx +154 -0
  296. package/templates/hono-fullstack/libs/ui/stories/forms/Textarea.stories.tsx +148 -0
  297. package/templates/hono-fullstack/libs/ui/stories/layout/Grid.stories.tsx +60 -0
  298. package/templates/hono-fullstack/libs/ui/stories/layout/Positioning.stories.tsx +90 -0
  299. package/templates/hono-fullstack/libs/ui/stories/layout/ScrollArea.stories.tsx +68 -0
  300. package/templates/hono-fullstack/libs/ui/stories/layout/Stack.stories.tsx +87 -0
  301. package/templates/hono-fullstack/libs/ui/stories/navigation/Breadcrumb.stories.tsx +104 -0
  302. package/templates/hono-fullstack/libs/ui/stories/navigation/Link.stories.tsx +62 -0
  303. package/templates/hono-fullstack/libs/ui/stories/navigation/LinkBox.stories.tsx +45 -0
  304. package/templates/hono-fullstack/libs/ui/stories/navigation/Pagination.stories.tsx +74 -0
  305. package/templates/hono-fullstack/libs/ui/stories/overlays/Dialog.stories.tsx +255 -0
  306. package/templates/hono-fullstack/libs/ui/stories/overlays/Drawer.stories.tsx +114 -0
  307. package/templates/hono-fullstack/libs/ui/stories/overlays/HoverCard.stories.tsx +47 -0
  308. package/templates/hono-fullstack/libs/ui/stories/overlays/Menu.stories.tsx +133 -0
  309. package/templates/hono-fullstack/libs/ui/stories/overlays/OverlayManager.stories.tsx +206 -0
  310. package/templates/hono-fullstack/libs/ui/stories/overlays/Popover.stories.tsx +73 -0
  311. package/templates/hono-fullstack/libs/ui/stories/overlays/Tooltip.stories.tsx +114 -0
  312. package/templates/hono-fullstack/libs/ui/stories/tsconfig.json +14 -0
  313. package/templates/hono-fullstack/libs/ui/tsconfig.build.json +5 -0
  314. package/templates/hono-fullstack/libs/ui/tsconfig.json +13 -0
  315. package/templates/hono-fullstack/libs/ui/turbo.json +28 -0
  316. package/templates/hono-fullstack/libs/ui/vite.config.ts +33 -0
  317. package/templates/hono-fullstack/oyo.config.json +30 -4
  318. package/templates/hono-fullstack/package.json +1 -0
  319. package/templates/hono-fullstack/pnpm-workspace.yaml +20 -10
  320. package/templates/hono-fullstack/turbo.json +10 -0
  321. package/templates/hono-server/.codegraph/.gitignore +5 -0
  322. package/templates/hono-server/README.md +9 -1
  323. package/templates/hono-server/_gitignore +1 -0
  324. package/templates/hono-server/apps/server/package.json +7 -2
  325. package/templates/hono-server/apps/server/src/adapters/cloudflare/entry.ts +4 -30
  326. package/templates/hono-server/apps/server/src/adapters/nodejs/bootstrap.ts +20 -12
  327. package/templates/hono-server/apps/server/src/adapters/nodejs/entry.ts +7 -57
  328. package/templates/hono-server/apps/server/src/app.ts +37 -21
  329. package/templates/hono-server/apps/server/src/config.ts +1 -1
  330. package/templates/hono-server/apps/server/src/di-container.ts +51 -0
  331. package/templates/hono-server/apps/server/src/infra/logger/getter.ts +1 -1
  332. package/templates/hono-server/apps/server/src/infra/logger/pino.ts +21 -34
  333. package/templates/hono-server/apps/server/src/infra/work-runner/errors.ts +22 -0
  334. package/templates/hono-server/apps/server/src/infra/work-runner/pass-through/runner.ts +28 -22
  335. package/templates/hono-server/apps/server/src/infra/work-runner/piscina/runner.ts +11 -34
  336. package/templates/hono-server/apps/server/src/infra/work-runner/{example → piscina}/worker-entry.ts +6 -2
  337. package/templates/hono-server/apps/server/src/infra/work-runner/types.ts +2 -16
  338. package/templates/hono-server/apps/server/src/infra/work-runner/utils/business-error.ts +10 -5
  339. package/templates/hono-server/apps/server/src/infra/work-runner/utils/message.ts +5 -17
  340. package/templates/hono-server/apps/server/src/middlewares/cors.ts +16 -22
  341. package/templates/hono-server/apps/server/src/middlewares/logger.ts +34 -0
  342. package/templates/hono-server/apps/server/src/modules/example/module.ts +8 -0
  343. package/templates/hono-server/apps/server/src/modules/example/queries.ts +8 -0
  344. package/templates/hono-server/apps/server/src/modules/example/routes.ts +74 -68
  345. package/templates/hono-server/apps/server/src/modules/example/service.test.ts +53 -0
  346. package/templates/hono-server/apps/server/src/modules/example/service.ts +54 -0
  347. package/templates/hono-server/apps/server/src/modules/example/types.ts +12 -0
  348. package/templates/hono-server/apps/server/src/modules/example/work-task/tasks.test.ts +9 -35
  349. package/templates/hono-server/apps/server/src/modules/example/work-task/tasks.ts +15 -46
  350. package/templates/hono-server/apps/server/src/shared/errors/defs/index.ts +6 -1
  351. package/templates/hono-server/apps/server/src/shared/errors/handler.ts +1 -1
  352. package/templates/hono-server/apps/server/src/shared/network/openapi/index.ts +1 -1
  353. package/templates/hono-server/apps/server/src/shared/types/app.ts +51 -0
  354. package/templates/hono-server/apps/server/src/shared/types/db.ts +126 -0
  355. package/templates/hono-server/apps/server/src/shared/utils/data-access/check.ts +19 -0
  356. package/templates/hono-server/apps/server/src/shared/utils/data-access/model.ts +47 -0
  357. package/templates/hono-server/apps/server/src/shared/utils/data-access/params.ts +105 -0
  358. package/templates/hono-server/apps/server/src/shared/utils/data-access/query.test.ts +139 -0
  359. package/templates/hono-server/apps/server/src/shared/utils/data-access/query.ts +236 -0
  360. package/templates/hono-server/apps/server/vite.config.ts +2 -2
  361. package/templates/hono-server/apps/server/wrangler.jsonc +1 -1
  362. package/templates/hono-server/docker/README.md +1 -1
  363. package/templates/hono-server/envs/.env.example.sqlite-d1 +1 -0
  364. package/templates/hono-server/libs/db/drizzle-kit/sqlite-d1.config.ts +29 -10
  365. package/templates/hono-server/libs/db/package.json +1 -0
  366. package/templates/hono-server/libs/db/src/dialects/sqlite/schema/columns.ts +1 -1
  367. package/templates/hono-server/libs/db/src/dialects/sqlite/schema/modules/examples/examples.ts +6 -3
  368. package/templates/hono-server/libs/db/src/dialects/sqlite/schema/vo.ts +7 -1
  369. package/templates/hono-server/libs/definition/README.md +81 -0
  370. package/templates/hono-server/libs/definition/package.json +3 -1
  371. package/templates/hono-server/libs/definition/src/constants/index.ts +1 -0
  372. package/templates/hono-server/libs/definition/src/constants/pagination.ts +3 -0
  373. package/templates/hono-server/libs/definition/src/modules/common-contracts.ts +24 -0
  374. package/templates/hono-server/libs/definition/src/modules/example/contracts.ts +34 -0
  375. package/templates/hono-server/libs/definition/src/modules/example/index.ts +1 -16
  376. package/templates/hono-server/libs/definition/src/modules/index.ts +2 -0
  377. package/templates/hono-server/libs/definition/src/modules/vo-generated-types.ts +12 -0
  378. package/templates/hono-server/oyo.config.json +30 -4
  379. package/templates/hono-server/package.json +1 -0
  380. package/templates/hono-server/pnpm-workspace.yaml +9 -7
  381. package/templates/hono-server/turbo.json +10 -0
  382. package/templates/monorepo/.codegraph/.gitignore +5 -0
  383. package/templates/monorepo/_gitignore +1 -0
  384. package/templates/monorepo/oyo.config.json +6 -4
  385. package/templates/monorepo/pnpm-workspace.yaml +4 -4
  386. package/templates/monorepo/turbo.json +10 -0
  387. package/templates/hono-fullstack/apps/server/src/modules/example/contracts.ts +0 -9
  388. package/templates/hono-fullstack/apps/server/src/shared/app/types.ts +0 -44
  389. package/templates/hono-fullstack/apps/stack/frontend/styles.css +0 -23
  390. package/templates/hono-server/apps/server/src/modules/example/contracts.ts +0 -9
  391. package/templates/hono-server/apps/server/src/shared/app/types.ts +0 -44
@@ -0,0 +1,236 @@
1
+ import { relations, type SqliteTableType, type SqliteColType } from '@repo/db/sqlite/schema'
2
+ import { count, getColumns, sql, type DBQueryConfig } from 'drizzle-orm'
3
+ import type { SQLiteInsertValue, SQLiteUpdateSetSource } from 'drizzle-orm/sqlite-core'
4
+ import type {
5
+ Result,
6
+ SQLiteAsyncRelationalQueryHKT,
7
+ SQLiteSyncRelationalQuery,
8
+ } from 'drizzle-orm/sqlite-core/async'
9
+ import type { RelationalQueryBuilder } from 'drizzle-orm/sqlite-core/query-builders/query'
10
+ import type {
11
+ DeleteOptions,
12
+ DeleteResults,
13
+ InsertOptions,
14
+ InsertResults,
15
+ QueryDB,
16
+ QueryOneOptions,
17
+ QueryOptions,
18
+ QueryPageOptions,
19
+ QueryResultKind,
20
+ QueryResults,
21
+ QueryRow,
22
+ UpdateOptions,
23
+ UpdateResults,
24
+ VOsMap,
25
+ } from '@/shared/types/db'
26
+ import type { Model } from './model'
27
+ import {
28
+ objectWhereToSQL,
29
+ parseDeleteOptions,
30
+ parseDrizzleQueryOptions,
31
+ parseUpdateOptions,
32
+ } from './params'
33
+
34
+ type TableConfig<T extends SqliteTableType> = {
35
+ table: T
36
+ name: string
37
+ relations: Record<never, never>
38
+ }
39
+
40
+ type TableReader<K extends QueryResultKind, T extends SqliteTableType> = RelationalQueryBuilder<
41
+ K,
42
+ typeof relations,
43
+ TableConfig<T>,
44
+ SQLiteAsyncRelationalQueryHKT
45
+ >
46
+
47
+ type TotalInfo = { total: number } | undefined
48
+
49
+ /**
50
+ * 为固定查询创建按 db/tx 实例隔离的预编译缓存。
51
+ * 在领域 queries.ts 顶层调用一次,每个模块持有自己的 WeakMap;此时无需提供 db。
52
+ * 返回的函数首次收到某个 db/tx 时同步 prepare,后续复用同一组 statement。
53
+ * 初始化入口也可调用它提前准备;prepare 回调只创建语句,不执行查询。
54
+ * 准备失败不写入缓存,后续允许重试;数据库连接的关闭仍由调用方负责。
55
+ *
56
+ * @example
57
+ * // queries.ts 顶层定义,只创建缓存,不准备语句。
58
+ * export const prepareQueries = createPreparedQueries((db) => ({
59
+ * findByTitle: db.select().from(sources)
60
+ * .where(eq(sources.title, sql.placeholder('title'))).prepare(),
61
+ * }))
62
+ *
63
+ * // 查询函数仍接受 db/tx;也可在初始化入口直接调用 prepareQueries(db) 预热。
64
+ * export function findByTitle(db: QueryDB, title: string) {
65
+ * return prepareQueries(db).findByTitle.get({ title })
66
+ * }
67
+ */
68
+ export function createPreparedQueries<T extends Record<string, object>>(
69
+ prepare: (db: QueryDB) => T,
70
+ ) {
71
+ const cache = new WeakMap<QueryDB, T>()
72
+
73
+ return (db: QueryDB): T => {
74
+ let queries = cache.get(db)
75
+ if (queries === undefined) {
76
+ queries = prepare(db)
77
+ cache.set(db, queries)
78
+ }
79
+ return queries
80
+ }
81
+ }
82
+
83
+ /**
84
+ * 绑定领域的表与 VO,生成可直接导出的通用查询函数;不创建事务,db 或 tx 由调用方传入。
85
+ * 返回值沿用驱动行为:better-sqlite3 直接返回结果,D1 返回 Promise。
86
+ * 通过 Drizzle 自带的 db._.resultKind 判断驱动,避免同步 SQLite 事务被改成异步执行。
87
+ */
88
+ export function createQueries<T extends SqliteTableType, VOs extends VOsMap>(
89
+ model: Model<T, VOs>,
90
+ defaults: Pick<QueryOptions<T, keyof VOs & string>, 'orderBy'> = {},
91
+ ) {
92
+ type M = Model<T, VOs>
93
+ type VT = keyof VOs & string
94
+
95
+ const relation = Object.entries(relations).find(
96
+ ([, relation]) => (relation.table as SqliteTableType) === model.table,
97
+ )
98
+ if (!relation) throw new Error(`Table is not registered in relations: ${model.tableName}`)
99
+ const tableKey = relation[0] as keyof typeof relations
100
+ const { orderBy } = defaults
101
+
102
+ /** 按条件读取多条记录;voType 选择字段,limit 控制分页,withTotal 决定是否另查总数。 */
103
+ function query<K extends QueryResultKind, Q extends QueryOptions<T, VT> = {}>(
104
+ db: QueryDB<K>,
105
+ options: Q = {} as Q,
106
+ ): Result<K, QueryResults<M, Q>> {
107
+ const { selectFields, where, orderByObj, offset, limit, withTotal } = parseDrizzleQueryOptions(
108
+ model,
109
+ options,
110
+ )
111
+ // 表与 VO 在工厂创建时绑定;动态表名的类型适配只留在公共层。
112
+ const reader = db.query[tableKey] as unknown as TableReader<K, T>
113
+ const statement = reader.findMany({
114
+ columns: selectFields,
115
+ where: where || {},
116
+ orderBy: orderByObj || orderBy,
117
+ ...(limit === undefined ? {} : { offset, limit }),
118
+ } as DBQueryConfig<'many', typeof relations, TableConfig<T>>)
119
+ const totalInfo: TotalInfo | Promise<TotalInfo> = withTotal
120
+ ? db
121
+ .select({ total: count() })
122
+ .from(model.table)
123
+ .where(objectWhereToSQL(model.table, where))
124
+ .get()
125
+ : undefined
126
+
127
+ // 动态 VO 选择的运行时分支在这里统一对应到 schema 推断的公开结果类型。
128
+ const finish = (results: unknown[], total?: { total: number }) =>
129
+ ({
130
+ results,
131
+ meta: { offset, ...(limit === undefined ? {} : { limit }), ...total },
132
+ }) as QueryResults<M, Q>
133
+
134
+ // 同步驱动保持同步执行,避免给同步 SQLite 事务引入异步回调。
135
+ if (db._.resultKind === 'sync') {
136
+ const results = (statement as SQLiteSyncRelationalQuery<unknown[]>).sync()
137
+ return finish(results, totalInfo as TotalInfo) as Result<K, QueryResults<M, Q>>
138
+ }
139
+ return Promise.all([statement.execute(), totalInfo]).then(([results, total]) =>
140
+ finish(results, total),
141
+ ) as Result<K, QueryResults<M, Q>>
142
+ }
143
+
144
+ // 单条读取未命中时返回 null;写入结果沿用参考项目的 result/meta、updated、deleted 结构。
145
+ /** 按条件读取第一条记录,未命中返回 null;需要确定顺序时传入 orderBy。 */
146
+ function findOne<K extends QueryResultKind, Q extends QueryOneOptions<T, VT> = {}>(
147
+ db: QueryDB<K>,
148
+ options: Q = {} as Q,
149
+ ): Result<K, QueryRow<M, Q> | null> {
150
+ const result = query(db, { ...options, page: 1, limit: 1, withTotal: false as const })
151
+ const finish = (value: { results: unknown[] }) =>
152
+ (value.results[0] || null) as QueryRow<M, Q> | null
153
+
154
+ if (db._.resultKind === 'sync') {
155
+ return finish(result as { results: unknown[] }) as Result<K, QueryRow<M, Q> | null>
156
+ }
157
+ return Promise.resolve(result).then(finish) as Result<K, QueryRow<M, Q> | null>
158
+ }
159
+
160
+ /** 按页读取记录并附带总数;limit 必填,page 默认从第 1 页开始。 */
161
+ function findPage<K extends QueryResultKind, Q extends QueryPageOptions<T, VT>>(
162
+ db: QueryDB<K>,
163
+ options: Q,
164
+ ) {
165
+ return query(db, { ...options, withTotal: true as const })
166
+ }
167
+
168
+ /** 插入单条或多条记录,按 VO 返回字段及写入数量;空数组返回空结果。 */
169
+ function insert<K extends QueryResultKind, O extends InsertOptions<T, VT>>(
170
+ db: QueryDB<K>,
171
+ options: O,
172
+ ): Result<K, InsertResults<M, O>> {
173
+ // 动态 VO 在执行层统一为列映射;对外结果仍根据调用方的 voType 精确推断。
174
+ const fields: Record<string, SqliteColType> =
175
+ options.voType === undefined ? getColumns(model.table) : model.getVO(options.voType)
176
+ const values = Array.isArray(options.values) ? options.values : [options.values]
177
+ const rows: unknown[] | Promise<unknown[]> = values.length
178
+ ? db
179
+ .insert(model.table)
180
+ .values(values as unknown as SQLiteInsertValue<T>[])
181
+ .returning(fields)
182
+ .all()
183
+ : []
184
+ const finish = (result: unknown[]) =>
185
+ ({
186
+ result,
187
+ meta: { count: values.length, affected: result.length },
188
+ }) as InsertResults<M, O>
189
+
190
+ if (db._.resultKind === 'sync') {
191
+ return finish(rows as unknown[]) as Result<K, InsertResults<M, O>>
192
+ }
193
+ return Promise.resolve(rows).then(finish) as Result<K, InsertResults<M, O>>
194
+ }
195
+
196
+ /** 按条件更新记录并返回 updated 数量;空更新字段、无条件更新均抛出异常。 */
197
+ function update<K extends QueryResultKind>(
198
+ db: QueryDB<K>,
199
+ options: UpdateOptions<T>,
200
+ ): Result<K, UpdateResults> {
201
+ const { value, conditions } = parseUpdateOptions(model, options)
202
+ const rows: unknown[] | Promise<unknown[]> = db
203
+ .update(model.table)
204
+ .set(value as SQLiteUpdateSetSource<T>)
205
+ .where(conditions)
206
+ .returning({ affected: sql<number>`1` })
207
+ .all()
208
+ const finish = (result: unknown[]): UpdateResults => ({ updated: result.length })
209
+
210
+ if (db._.resultKind === 'sync') {
211
+ return finish(rows as unknown[]) as Result<K, UpdateResults>
212
+ }
213
+ return Promise.resolve(rows).then(finish) as Result<K, UpdateResults>
214
+ }
215
+
216
+ /** 按条件删除记录并返回 deleted 数量;无条件删除抛出异常。 */
217
+ function deleteRecords<K extends QueryResultKind>(
218
+ db: QueryDB<K>,
219
+ options: DeleteOptions<T>,
220
+ ): Result<K, DeleteResults> {
221
+ const { conditions } = parseDeleteOptions(model, options)
222
+ const rows: unknown[] | Promise<unknown[]> = db
223
+ .delete(model.table)
224
+ .where(conditions)
225
+ .returning({ affected: sql<number>`1` })
226
+ .all()
227
+ const finish = (result: unknown[]): DeleteResults => ({ deleted: result.length })
228
+
229
+ if (db._.resultKind === 'sync') {
230
+ return finish(rows as unknown[]) as Result<K, DeleteResults>
231
+ }
232
+ return Promise.resolve(rows).then(finish) as Result<K, DeleteResults>
233
+ }
234
+
235
+ return { query, findOne, findPage, insert, update, deleteRecords }
236
+ }
@@ -66,8 +66,8 @@ export default defineConfig(() => {
66
66
  }),
67
67
  nodejsEntry: './src/adapters/nodejs/entry.ts',
68
68
  cloudflareEntry: './src/adapters/cloudflare/entry.ts',
69
- // Enable this entry together with PiscinaWorkRunner in the Node.js adapter.
70
- // 'workers/example-worker': './src/infra/work-runner/example/worker-entry.ts',
69
+ // Enable this entry together with PiscinaWorkRunner in di-container.ts.
70
+ // 'workers/piscina-worker': './src/infra/work-runner/piscina/worker-entry.ts',
71
71
  },
72
72
  // deps: {
73
73
  // neverBundle: [...builtinModules],
@@ -11,7 +11,7 @@
11
11
  "observability": {
12
12
  "logs": {
13
13
  "enabled": true,
14
- "invocation_logs": true,
14
+ "invocation_logs": false,
15
15
  },
16
16
  "traces": {
17
17
  "enabled": false,
@@ -2,4 +2,4 @@
2
2
 
3
3
  Copy `docker/.env.example` to `docker/.env` and `envs/.env.example.server` to `envs/.env.server`. Build with `bash scripts/build-docker-server.sh`, then run `docker/local/local-app-deploy.sh`. Production Compose lives under `docker/prod`; copy `.env.example.server` to `.env.server` before use.
4
4
 
5
- The image is a Turbo-pruned, multi-stage production deployment. It validates the Node entry and Example worker artifacts, runs as a non-root user, and checks `/health`.
5
+ The image is a Turbo-pruned, multi-stage production deployment. It validates the Node entry artifact, runs as a non-root user, and checks `/health`.
@@ -1,3 +1,4 @@
1
1
  CLOUDFLARE_ACCOUNT_ID=
2
2
  CLOUDFLARE_DATABASE_ID=
3
3
  CLOUDFLARE_TOKEN=
4
+ IS_D1_LOCAL=1
@@ -4,19 +4,38 @@ import { d1SchemaConfig } from '@repo/definition/backend'
4
4
 
5
5
  const configDir = import.meta.dirname
6
6
 
7
- const { cloudflareAccountId, cloudflareDatabaseId, cloudflareToken } = d1SchemaConfig.resolve({
8
- context: process.env,
9
- matchContextKey: 'constantCase',
10
- })
7
+ let dbCredentials:
8
+ | {
9
+ accountId: string
10
+ databaseId: string
11
+ token: string
12
+ }
13
+ | {
14
+ url: string
15
+ } = {
16
+ url: path.join(
17
+ configDir,
18
+ '../../../.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite',
19
+ ),
20
+ }
21
+ const isD1Local = !!process.env.IS_D1_LOCAL
22
+
23
+ if (!isD1Local) {
24
+ const { cloudflareAccountId, cloudflareDatabaseId, cloudflareToken } = d1SchemaConfig.resolve({
25
+ context: process.env,
26
+ matchContextKey: 'constantCase',
27
+ })
28
+ dbCredentials = {
29
+ accountId: cloudflareAccountId,
30
+ databaseId: cloudflareDatabaseId,
31
+ token: cloudflareToken,
32
+ }
33
+ }
11
34
 
12
35
  export default defineConfig({
13
36
  dialect: 'sqlite',
14
- driver: 'd1-http',
37
+ driver: isD1Local ? undefined : 'd1-http',
15
38
  schema: path.join(configDir, '../src/dialects/sqlite/schema/tables.ts'),
16
39
  out: path.join(configDir, '../migrations/sqlite-d1'),
17
- dbCredentials: {
18
- accountId: cloudflareAccountId,
19
- databaseId: cloudflareDatabaseId,
20
- token: cloudflareToken,
21
- },
40
+ dbCredentials,
22
41
  })
@@ -22,6 +22,7 @@
22
22
  "dev:sqlite:gen": "oyo env sqlite -- drizzle-kit generate --config=drizzle-kit/sqlite.config.ts",
23
23
  "dev:sqlite:migrate": "oyo env sqlite -- drizzle-kit migrate --config=drizzle-kit/sqlite.config.ts",
24
24
  "dev:d1:gen": "oyo env sqlite-d1 -- drizzle-kit generate --config=drizzle-kit/sqlite-d1.config.ts",
25
+ "dev:d1:push": "oyo env sqlite-d1 -- drizzle-kit push --config=drizzle-kit/sqlite-d1.config.ts",
25
26
  "dev:d1:migrate": "oyo env sqlite-d1 -- drizzle-kit migrate --config=drizzle-kit/sqlite-d1.config.ts"
26
27
  },
27
28
  "dependencies": {
@@ -12,7 +12,7 @@ export const idType = customType<{ data: string; driverData: number | bigint }>(
12
12
 
13
13
  export const autoIncrementId = (name: string) =>
14
14
  idType(name)
15
- .primaryKey({ autoIncrement: true })
15
+ .primaryKey()
16
16
  .$defaultFn(() => sql`null`)
17
17
 
18
18
  export function timestampMsColumn(name: string) {
@@ -11,12 +11,15 @@ export const examples = sqliteTable('examples', {
11
11
 
12
12
  export type InsertExample = typeof examples.$inferInsert
13
13
 
14
- export const voExamples = defineVO({
14
+ export const voExamplesId = defineVO({ id: examples.id })
15
+ export type IExamplesIdVO = SelectVOResults<typeof voExamplesId>
16
+
17
+ export const voExamplesList = defineVO({
15
18
  id: examples.id,
16
19
  message: examples.message,
17
20
  createdAt: examples.createdAt,
18
21
  updatedAt: examples.updatedAt,
19
22
  })
20
- export type IExamplesVO = SelectVOResults<typeof voExamples>
23
+ export type IExamplesListVO = SelectVOResults<typeof voExamplesList>
21
24
 
22
- export const vcExamples = { default: voExamples } as const
25
+ export const vcExamples = { id: voExamplesId, list: voExamplesList }
@@ -1 +1,7 @@
1
- export { vcExamples, voExamples, type IExamplesVO } from './modules/examples/examples'
1
+ export {
2
+ vcExamples,
3
+ voExamplesId,
4
+ voExamplesList,
5
+ type IExamplesIdVO,
6
+ type IExamplesListVO,
7
+ } from './modules/examples/examples'
@@ -0,0 +1,81 @@
1
+ # Definition
2
+
3
+ 存放前后端共享的业务常量、Valibot contracts 和类型。contracts 根据 Drizzle 表生成初稿,再由业务维护;VO 类型根据显式声明的查询投影生成。数据库结构只能提供字段线索,不能替代 API 设计。
4
+
5
+ ## 生成流程
6
+
7
+ 1. 修改 `libs/db/src/dialects/sqlite/schema` 中的表定义,并自行更新 DB 构建产物。生成器读取的是 `libs/db/dist/sqlite/schema.mjs`,不会自动编译源码。
8
+ 2. 检查仓库根目录 `oyo.config.json` 的 `codeGenerator` 配置。
9
+ 3. 在仓库根目录按需执行;contracts 按提示选择表并确认名称,VO 读取入口中的全部 `voXxx` 导出:
10
+
11
+ ```sh
12
+ pnpm --filter @repo/definition codegen:contracts
13
+ pnpm --filter @repo/definition codegen:vo
14
+ ```
15
+
16
+ 4. 查看 diff,补齐业务约束、允许编辑的字段和模块导出,再接入调用方。
17
+
18
+ **当前两个生成脚本均设置了 `IS_OVERRIDE=1`,会覆盖对应产物,包括手改的 contracts 和公共分页文件。** 重新生成前保留改动,生成后逐项合并业务规则。生成器默认跳过已有文件,但当前脚本主动开启了覆盖;`IS_TEST=1` 仅解析和交互,不写文件或配置记录。
19
+
20
+ ## 配置重点
21
+
22
+ 路径以 `codeGenerator.root` 为基准;`root` 相对配置文件所在目录。
23
+
24
+ | 配置 | 当前用途 |
25
+ | --------------------------------------- | -------------------------------------------------------------------------------------- |
26
+ | `database.entry` | Drizzle 表定义的运行时入口,contracts 与 VO 共用 |
27
+ | `database.customTypes` | 自定义列类型映射;当前 `integer → string` 对应自定义 ID 列,不代表所有整数列都转字符串 |
28
+ | `contracts.outputDir` | 必填,默认输出位置,目前为 `src/modules` |
29
+ | `contracts.createOne.excludePrimaryKey` | 默认 `true`,创建 DTO 排除主键 |
30
+ | `contracts.createOne.excludeFields` | 按 Drizzle 属性名排除字段;当前为 `createdAt`、`updatedAt`,实体没有对应字段时忽略 |
31
+ | `contracts.constantsSource` | 公共 contracts 引用的常量文件,当前提供 `DEFAULT_PAGE_SIZE` |
32
+ | `contracts.models` | 实体名到 contracts 文件路径的映射,当前为 `example/contracts.ts` |
33
+ | `contracts.commonContracts` | 公共 contracts 文件路径,默认位于 `outputDir` 下 |
34
+ | `vo.outputDir` | 必填,VO 类型输出目录,目前为 `src/modules` |
35
+ | `vo.models` | 生成文件路径记录;`vo-generated-types` 对应 VO 类型文件 |
36
+
37
+ 生成时会记录文件路径到 `contracts.models` / `contracts.commonContracts`。调整目录后同步修改这些记录;已有记录优先于默认输出路径。创建字段排除配置仅影响 `$CreateOne`,查询字段不受影响。
38
+
39
+ ## 产物约定
40
+
41
+ | 产物 | 用途与维护要求 |
42
+ | ---------------- | ----------------------------------------------------------------------------------------------- |
43
+ | `实体$CreateOne` | 创建 API DTO 草稿。筛选客户端可提交的字段,移除服务端自动填充字段;也承载供更新复用的字段规则 |
44
+ | `实体$UpdateOne` | 从 `$CreateOne` 选取允许编辑的字段并转为可选。初始 `v.pick(..., [])` 为空,**必须主动填写字段** |
45
+ | `实体$FindOne` | 查询条件草稿,字段可选;包含查询输入转换,有 `createdAt` 时补充起止时间条件 |
46
+ | `实体$FindMany` | `$FindOne` 与公共分页规则组合 |
47
+ | `I实体…` | 对应 schema 的输入类型;经过转换后的数据类型需要时使用 `v.InferOutput` |
48
+
49
+ 这些是请求约定,不是数据库 insert/update schema,也不是响应结构。服务端校验后由 Service 组装 IP、时间等字段并写库。没有前端表单的后台任务同样按操作定义输入约定;无需为复用生成物而模拟表单 DTO。响应类型按实际 VO 定义。
50
+
51
+ 前端表单与 API 字段和规则一致时可直接复用;存在确认字段、界面专用字段或不同必填规则时,基于对应 contract 派生表单 schema。服务端必须独立校验 API DTO,不能依赖前端校验。
52
+
53
+ ## VO 工作流
54
+
55
+ 在 DB schema 中用 `defineVO` 声明需要返回的列集合,并通过 `schema/vo.ts` 从 `database.entry` 导出。导出名使用 `voXxx`,生成类型名为 `IXxxVO`:
56
+
57
+ ```ts
58
+ export const voExamplesList = defineVO({
59
+ id: examples.id,
60
+ message: examples.message,
61
+ })
62
+ ```
63
+
64
+ 执行 `codegen:vo` 后,默认集中输出到 `vo.outputDir/vo-generated-types.ts`。VO 生成不依赖 contracts,也不受 `contracts.createOne` 排除字段配置影响。服务端查询的 `voType` 选择仍需在 Model 的 VO 集合中配置;生成类型不会自动改变查询或序列化行为。
65
+
66
+ - **维护投影源,不手改生成文件。** 列集合变化后更新 DB 构建产物,再重新生成;生成文件整体覆盖,不做业务规则合并。
67
+ - **VO 是响应类型,不提供运行时校验。** ID、日期等按列解析规则映射为前端类型,当前日期为 `string`;调用方仍须保证实际响应的序列化结果一致。
68
+ - **检查类型精度。** `$type<T>()` 中的业务枚举、JSON 结构等无法从运行时完整还原,必要时在独立业务类型中细化。当前非空列或带默认值的列生成必填字段,其余为可选且允许 `null`;需核对实际查询结果,尤其是可空列和关联查询。
69
+ - **按实际场景定义投影。** 列表、详情分别选择需要的字段,避免整表暴露。仅含必填字符串 `id` 的投影自动复用公共 `IIdVO`,保留原实体类型名。
70
+ - **接入导出链。** 将生成类型从 `modules/index.ts` 等入口导出,前后端通过 definition 使用,前端无需依赖 DB 包。
71
+
72
+ ## 生成后必查
73
+
74
+ - **业务常量不能靠 DB 类型自动推断。** Drizzle 的 `$type<T>()` 在运行时不保留枚举成员;默认值也不等于枚举范围。需要时手动接入 `v.picklist(Object.values(...))`,不使用 `v.enum`。
75
+ - **保留真正需要的转换。** 字符串常量直接用 `picklist`,无需先 `string` / `toString`;数值查询参数需要时先 `toNumber` 再校验常量范围。
76
+ - **补业务规则。** 当前 example 的 message 使用 trim 和非空校验,重新生成后需检查。字段关联、权限、唯一性和非 CRUD 操作等由业务补充,生成器不承诺覆盖。
77
+ - **检查必填、空值与默认值。** DB 默认值可能使创建字段变为 optional;生成规则不会自动允许 `null`。需要清空字段时显式允许 nullable;检查自动 trim、非空规则是否适合正文等字段。
78
+ - **收敛查询与更新范围。** 不是每个 DB 字段都应允许查询或编辑;范围查询、分页整数限制等按接口补齐。当前 example 仅允许更新 message。
79
+ - **补齐导出。** 生成文件不会自动接入各层 `index.ts`;检查实体、`modules` 及 `frontend` / `backend` 的导出链,避免文件存在但包入口不可用。
80
+
81
+ DB 结构变更后重新生成只是起点。以最终业务 contract 为准,检查调用方与 Service 的字段映射,并保留手工补充的校验。
@@ -14,7 +14,9 @@
14
14
  "build": "vp pack",
15
15
  "dev": "vp pack --watch",
16
16
  "test": "vp test",
17
- "check": "vp check"
17
+ "check": "vp check",
18
+ "codegen:contracts": "IS_OVERRIDE=1 oyo gen contracts",
19
+ "codegen:vo": "IS_OVERRIDE=1 oyo gen vo"
18
20
  },
19
21
  "dependencies": {
20
22
  "change-case": "catalog:shared",
@@ -0,0 +1 @@
1
+ export * from './pagination'
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_PAGE_SIZE = 10
2
+ export const MAX_PAGE_SIZE = 100
3
+ export const DEFAULT_QUERY_MAX = 1000
@@ -0,0 +1,24 @@
1
+ import * as v from 'valibot'
2
+ import { DEFAULT_PAGE_SIZE } from '../constants/index'
3
+
4
+ export const PaginationSchema = v.object({
5
+ page: v.optional(
6
+ v.pipe(
7
+ v.unknown(),
8
+ v.toNumber('非法页码'),
9
+ v.finite('非法页码'),
10
+ v.minValue(1, '非法页码'),
11
+ ) as v.GenericSchema<number, number>,
12
+ 1,
13
+ ),
14
+ limit: v.optional(
15
+ v.pipe(
16
+ v.unknown(),
17
+ v.toNumber('非法limit'),
18
+ v.finite('非法limit'),
19
+ v.minValue(1, '非法limit'),
20
+ ) as v.GenericSchema<number, number>,
21
+ DEFAULT_PAGE_SIZE,
22
+ ),
23
+ })
24
+ export type Pagination = v.InferOutput<typeof PaginationSchema>
@@ -0,0 +1,34 @@
1
+ import * as v from 'valibot'
2
+ import { PaginationSchema } from '../common-contracts'
3
+
4
+ export const Example$CreateOne = v.object({
5
+ message: v.pipe(v.string('message无效'), v.trim(), v.minLength(1, 'message不能为空')),
6
+ })
7
+ export type IExampleCreateOne = v.InferInput<typeof Example$CreateOne>
8
+
9
+ export const Example$UpdateOne = v.partial(v.pick(Example$CreateOne, ['message']))
10
+ export type IExampleUpdateOne = v.InferInput<typeof Example$UpdateOne>
11
+
12
+ export const Example$FindOne = v.partial(
13
+ v.object({
14
+ id: v.pipe(v.unknown(), v.toString('id无效')) as v.GenericSchema<string, string>,
15
+ message: v.pipe(v.unknown(), v.toString('message无效')) as v.GenericSchema<string, string>,
16
+ }),
17
+ )
18
+ export type IExampleFindOne = v.InferInput<typeof Example$FindOne>
19
+
20
+ export const Example$FindMany = v.object({
21
+ ...PaginationSchema.entries,
22
+ ...Example$FindOne.entries,
23
+ })
24
+ export type IExampleFindMany = v.InferInput<typeof Example$FindMany>
25
+
26
+ export const Example$Process = v.pick(Example$CreateOne, ['message'])
27
+ export type IExampleProcess = v.InferInput<typeof Example$Process>
28
+
29
+ export const Example$ProcessResult = v.object({
30
+ original: v.string(),
31
+ normalized: v.string(),
32
+ length: v.number(),
33
+ })
34
+ export type IExampleProcessResult = v.InferOutput<typeof Example$ProcessResult>
@@ -1,16 +1 @@
1
- export type Example = {
2
- id: string
3
- message: string
4
- createdAt: string
5
- updatedAt: string
6
- }
7
-
8
- export type CreateExampleInput = Pick<Example, 'message'>
9
-
10
- export type ProcessExampleInput = Pick<Example, 'message'>
11
-
12
- export type ProcessExampleOutput = {
13
- original: string
14
- normalized: string
15
- length: number
16
- }
1
+ export * from './contracts'
@@ -1 +1,3 @@
1
1
  export * from './example'
2
+ export * from './common-contracts'
3
+ export * from './vo-generated-types'
@@ -0,0 +1,12 @@
1
+ // 自动生成的面向前端的 VO 类型,请勿手动修改
2
+ export type IIdVO = {
3
+ id: string
4
+ }
5
+
6
+ export type IExamplesIdVO = IIdVO
7
+ export type IExamplesListVO = {
8
+ id: string
9
+ message: string
10
+ createdAt: string
11
+ updatedAt: string
12
+ }
@@ -9,9 +9,35 @@
9
9
  },
10
10
  "codeGenerator": {
11
11
  "root": ".",
12
- "scope": "@repo",
13
- "author": "",
14
- "gitUrlBase": "",
15
- "license": "MIT"
12
+ "database": {
13
+ "entry": "./libs/db/dist/sqlite/schema.mjs",
14
+ "customTypes": {
15
+ "integer": "string"
16
+ }
17
+ },
18
+ "repo-package": {
19
+ "scope": "@repo",
20
+ "author": "",
21
+ "gitUrlBase": "",
22
+ "license": "MIT"
23
+ },
24
+ "contracts": {
25
+ "outputDir": "./libs/definition/src/modules",
26
+ "createOne": {
27
+ "excludePrimaryKey": true,
28
+ "excludeFields": ["createdAt", "updatedAt"]
29
+ },
30
+ "constantsSource": "./libs/definition/src/constants/index",
31
+ "models": {
32
+ "example": "./libs/definition/src/modules/example/contracts.ts"
33
+ },
34
+ "commonContracts": "./libs/definition/src/modules/common-contracts.ts"
35
+ },
36
+ "vo": {
37
+ "outputDir": "./libs/definition/src/modules",
38
+ "models": {
39
+ "vo-generated-types": "libs/definition/src/modules/vo-generated-types.ts"
40
+ }
41
+ }
16
42
  }
17
43
  }
@@ -4,6 +4,7 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "prepare": "vp config",
7
+ "cf:typegen": "pnpm -C apps/server cf:typegen",
7
8
  "changeset": "vp exec changeset",
8
9
  "build": "turbo build",
9
10
  "build:libs": "turbo build --filter=!@repo/stack --filter=!@repo/server"