@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
@@ -28,7 +28,7 @@ Database schema changes remain manual. Production Worker variables are configure
28
28
 
29
29
  Before deploying, replace the placeholder D1 `database_id` and `database_name` in `apps/server/wrangler.jsonc`.
30
30
 
31
- Example tasks run in-process through `PassThroughWorkRunner` by default. To use worker threads, enable `PiscinaWorkRunner` in the Node.js adapter and the adjacent worker pack entry in `apps/server/vite.config.ts`.
31
+ Example tasks run in-process through `PassThroughRunner` by default. To use worker threads, enable `PiscinaWorkRunner` in apps/server/src/di-container.ts and the adjacent worker pack entry in `apps/server/vite.config.ts`.
32
32
 
33
33
  ## Commands
34
34
 
@@ -42,3 +42,11 @@ Example tasks run in-process through `PassThroughWorkRunner` by default. To use
42
42
  - `pnpm --filter @repo/server test`: run the retained server tests.
43
43
 
44
44
  The server base path is configured by `SERVER_BASE_PATH`. Health, OpenAPI YAML, Swagger, CRUD, and worker processing are available below that base path. Docker supports local Compose under `docker/local` and production Compose under `docker/prod`. CI is intentionally not included.
45
+
46
+ ## Contracts and database development
47
+
48
+ Example routes validate shared contracts and call the inferDI-managed ExampleService; queries use the shared data-access layer and explicit id/list VOs. List responses contain results and pagination meta; create responses contain result and write meta. PATCH /examples/:id updates message, DELETE /examples accepts a JSON ids array, and POST /examples/process uses the configured work runner.
49
+
50
+ Run codegen:contracts and codegen:vo in libs/definition only after manually updating the DB package artifacts. These commands use IS_OVERRIDE=1 and can overwrite hand-edited contracts; review the diff and restore custom rules. See libs/definition/README.md.
51
+
52
+ IS_D1_LOCAL=1 selects the shared local metadata.sqlite database for Drizzle D1 commands. First run db:warmup:cloudflare:local in apps/server, then run dev:d1:push in libs/db manually. Remove IS_D1_LOCAL for remote D1 and provide Cloudflare credentials. The switch follows process.env truthiness: even the string 0 enables local mode. No schema push is run automatically.
@@ -11,6 +11,7 @@ node_modules
11
11
  dist
12
12
  dist-ssr
13
13
  .output
14
+ styled-system
14
15
  *.local
15
16
 
16
17
  # Editor directories and files
@@ -2,7 +2,9 @@
2
2
  "name": "@repo/server",
3
3
  "version": "0.0.0",
4
4
  "private": true,
5
- "files": ["dist"],
5
+ "files": [
6
+ "dist"
7
+ ],
6
8
  "type": "module",
7
9
  "exports": {
8
10
  "./nodejs": "./dist/nodejsEntry.mjs",
@@ -17,6 +19,7 @@
17
19
  "dev:cloudflare-chain": "turbo watch dev:cloudflare --filter=@repo/server",
18
20
  "dev:cloudflare": "wrangler dev --config wrangler.jsonc --persist-to ../../.wrangler/state",
19
21
  "db:migrate:cloudflare:local": "wrangler d1 migrations apply DB --local --config wrangler.jsonc --persist-to ../../.wrangler/state",
22
+ "db:warmup:cloudflare:local": "wrangler d1 execute DB --local --config wrangler.jsonc --persist-to ../../.wrangler/state --command \"SELECT 1\"",
20
23
  "build:node-chain": "turbo build:node --filter=@repo/server",
21
24
  "build:node": "vp pack",
22
25
  "cf:typegen": "wrangler types --config wrangler.jsonc",
@@ -28,7 +31,10 @@
28
31
  "dependencies": {
29
32
  "@hono/node-server": "catalog:server",
30
33
  "@hono/standard-validator": "catalog:server",
34
+ "@hono/structured-logger": "catalog:server",
31
35
  "@hono/swagger-ui": "catalog:server",
36
+ "@inferdi/hono": "catalog:server",
37
+ "@inferdi/inferdi": "catalog:",
32
38
  "@repo/db": "workspace:*",
33
39
  "@repo/definition": "workspace:*",
34
40
  "@valibot/to-json-schema": "catalog:server",
@@ -38,7 +44,6 @@
38
44
  "drizzle-orm": "catalog:db",
39
45
  "hono": "catalog:server",
40
46
  "hono-openapi": "catalog:server",
41
- "hono-pino": "catalog:server",
42
47
  "hono-problem-details": "catalog:server",
43
48
  "ky": "catalog:shared",
44
49
  "pino": "catalog:server",
@@ -1,36 +1,10 @@
1
- import { createD1Client } from '@repo/db/sqlite/d1-client'
2
1
  import { env } from 'cloudflare:workers'
3
- import { getRuntimeKey } from 'hono/adapter'
4
2
  import { createApp } from '@/app'
5
- import { resolveConfig } from '@/config'
6
3
  import { setRootLogger } from '@/infra/logger/getter'
7
- import { createPinoLogger } from '@/infra/logger/pino'
8
- import { PassThroughWorkRunner } from '@/infra/work-runner/pass-through/runner'
9
- import type { AppDependencies, AppLogger } from '@/shared/app/types'
10
4
 
11
- const appConfig = resolveConfig(env as any)
12
- const { runtime, log } = appConfig
13
- const { rootLogger, loggerHandler } = createPinoLogger({
14
- isLocal: runtime.isLocal,
15
- logBase: log.base,
16
- runtime: getRuntimeKey(),
17
- logRoll: log.roll,
18
- logPretty: log.pretty,
5
+ const instance = createApp({
6
+ env: { ...env },
19
7
  })
20
- setRootLogger(rootLogger as unknown as AppLogger)
8
+ setRootLogger(instance.logger)
21
9
 
22
- export const workRunner = new PassThroughWorkRunner()
23
- const d1Client = createD1Client(env.DB)
24
- const dependencies: AppDependencies = {
25
- appConfig,
26
- loggerHandler,
27
- workRunner,
28
- db: d1Client.db,
29
- }
30
-
31
- const app = createApp({
32
- serverBasePath: appConfig.runtime.serverBasePath,
33
- makeDependencies: () => dependencies,
34
- })
35
-
36
- export default app
10
+ export default instance.app
@@ -1,11 +1,11 @@
1
1
  import { serve } from '@hono/node-server'
2
- import app, { closeNodeDependencies } from './entry'
3
2
 
4
- function main() {
3
+ async function main() {
5
4
  const port = Number(process.env.NODE_PORT)
6
5
  if (!port || Number.isNaN(port)) {
7
6
  throw new Error(`Invalid port: ${process.env.NODE_PORT}`)
8
7
  }
8
+ const { default: app, disposeApp, rootLogger } = await import('./entry')
9
9
 
10
10
  const server = serve(
11
11
  {
@@ -18,8 +18,10 @@ function main() {
18
18
  )
19
19
 
20
20
  let isShuttingDown = false
21
+ let shutdownExitCode = 0
21
22
 
22
- const gracefulShutdown = async (signal: string) => {
23
+ const gracefulShutdown = async (signal: string, exitCode = 0) => {
24
+ shutdownExitCode ||= exitCode
23
25
  if (isShuttingDown) return
24
26
  isShuttingDown = true
25
27
 
@@ -38,24 +40,30 @@ function main() {
38
40
  })
39
41
  console.log('✔ HTTP server successfully closed.')
40
42
 
41
- await closeNodeDependencies()
42
- console.log('✔ Node dependencies successfully closed.')
43
+ await disposeApp()
44
+ console.log('✔ App successfully disposed.')
43
45
 
44
46
  console.log('Graceful shutdown completed.')
45
- process.exit(0)
47
+ process.exit(shutdownExitCode)
46
48
  } catch (err) {
47
49
  console.error('Error during shutdown:', err)
48
50
  process.exit(1)
49
51
  }
50
52
  }
51
53
 
52
- process.on('SIGTERM', () => gracefulShutdown('SIGTERM'))
53
- process.on('SIGINT', () => gracefulShutdown('SIGINT'))
54
+ process.on('SIGTERM', () => void gracefulShutdown('SIGTERM'))
55
+ process.on('SIGINT', () => void gracefulShutdown('SIGINT'))
56
+ process.on('unhandledRejection', (reason) => {
57
+ rootLogger.fatal({ err: reason }, 'unhandledRejection')
58
+ void gracefulShutdown('unhandledRejection', 1)
59
+ })
60
+ process.on('uncaughtException', (error) => {
61
+ rootLogger.fatal({ err: error }, 'uncaughtException')
62
+ void gracefulShutdown('uncaughtException', 1)
63
+ })
54
64
  }
55
65
 
56
- try {
57
- main()
58
- } catch (error) {
66
+ void main().catch((error) => {
59
67
  console.error('[server] failed to start', error)
60
68
  process.exit(1)
61
- }
69
+ })
@@ -1,62 +1,12 @@
1
- import { createSqliteClient } from '@repo/db/sqlite/sqlite'
2
- import { sqliteSchemaConfig } from '@repo/definition/backend'
3
1
  import { createApp } from '@/app'
4
- import { resolveConfig } from '@/config'
5
- import { createPinoLogger } from '@/infra/logger/pino'
6
- import { getRuntimeKey } from 'hono/adapter'
7
- import type { AppDependencies, AppLogger } from '@/shared/app/types'
8
- // import { PiscinaWorkRunner } from '@/infra/work-runner/piscina/runner'
9
- import { PassThroughWorkRunner } from '@/infra/work-runner/pass-through/runner'
10
- import { getLogger, setRootLogger } from '@/infra/logger/getter'
2
+ import { setRootLogger } from '@/infra/logger/getter'
11
3
 
12
- function installProcessErrorHandlers(isLocal: boolean) {
13
- process.on('unhandledRejection', (reason) => {
14
- getLogger().error({ err: reason }, 'unhandledRejection')
15
- if (isLocal) process.exit(1)
16
- })
17
- process.on('uncaughtException', (error) => {
18
- getLogger().fatal({ err: error }, 'uncaughtException')
19
- process.exit(1)
20
- })
21
- }
22
-
23
- const appConfig = resolveConfig(process.env)
24
- const sqliteConfig = sqliteSchemaConfig.resolve({
25
- context: process.env,
26
- matchContextKey: 'constantCase',
27
- })
28
- const { runtime, log } = appConfig
29
- const { rootLogger, loggerHandler } = createPinoLogger({
30
- isLocal: runtime.isLocal,
31
- logBase: log.base,
32
- runtime: getRuntimeKey(),
33
- logRoll: log.roll,
34
- logPretty: log.pretty,
35
- })
36
- setRootLogger(rootLogger as unknown as AppLogger)
37
- installProcessErrorHandlers(runtime.isLocal)
38
-
39
- // To enable Piscina, use PiscinaWorkRunner and enable the worker pack entry in vite.config.ts.
40
- // export const workRunner = PiscinaWorkRunner.getInstance(appConfig.worker)
41
- export const workRunner = new PassThroughWorkRunner()
42
- export const sqliteClient = createSqliteClient(sqliteConfig.dbPath)
43
-
44
- let dependencies: AppDependencies | undefined
45
- let closePromise: Promise<void> | undefined
46
- const app = createApp({
47
- serverBasePath: appConfig.runtime.serverBasePath,
48
- makeDependencies: () => {
49
- dependencies ||= { appConfig, loggerHandler, workRunner, db: sqliteClient.db }
50
- return dependencies
51
- },
4
+ const instance = createApp({
5
+ env: process.env,
52
6
  })
7
+ setRootLogger(instance.logger)
53
8
 
54
- export const closeNodeDependencies = (): Promise<void> => {
55
- closePromise ||= (async () => {
56
- await workRunner.shutdown()
57
- sqliteClient.close()
58
- })()
59
- return closePromise
60
- }
9
+ export const rootLogger = instance.logger
10
+ export const disposeApp = instance.dispose
61
11
 
62
- export default app
12
+ export default instance.app
@@ -1,43 +1,59 @@
1
1
  import { Hono } from 'hono'
2
+ import { inferdiHono } from '@inferdi/hono'
2
3
  import { contextStorage } from 'hono/context-storage'
3
4
  import { csrf } from 'hono/csrf'
4
5
  import { secureHeaders } from 'hono/secure-headers'
5
6
  import { requestId } from 'hono/request-id'
7
+ import { describeRoute } from 'hono-openapi'
8
+ import * as v from 'valibot'
6
9
  import { corsMiddleware } from './middlewares/cors'
7
- import { exampleRoutes } from './modules/example/routes'
8
- import type { CreateAppOptions, AppEnv } from './shared/app/types'
10
+ import type { CreateAppOptions, AppEnv, AppInstance } from './shared/types/app'
9
11
  import { E } from './shared/errors/defs'
10
12
  import { globalErrorHandler } from './shared/errors/handler'
11
- import { configureOpenAPI } from './shared/network/openapi'
12
- import { objectEntries } from './shared/utils'
13
+ import { configureOpenAPI, jsonResponse, OpenApiTags } from './shared/network/openapi'
14
+ import { successJson } from './shared/network/utils'
15
+ import { loggerMiddleware } from './middlewares/logger'
16
+ import { createDIContainer } from './di-container'
17
+ import { flushPino } from './infra/logger/pino'
18
+ import { routes as exampleRoutes } from './modules/example/routes'
13
19
 
14
- export const createApp = ({ serverBasePath, makeDependencies }: CreateAppOptions): Hono<AppEnv> => {
15
- const app = new Hono<AppEnv>().basePath(serverBasePath)
20
+ export const createApp = ({ serverBasePath, env }: CreateAppOptions): AppInstance => {
21
+ const diContainer = createDIContainer({ env })
22
+ const rootLogger = diContainer.get('rootLogger')
23
+ const appConfig = diContainer.get('appConfig')
24
+ const app = new Hono<AppEnv>().basePath(serverBasePath ?? appConfig.runtime.serverBasePath)
16
25
 
17
- app.use('*', async (c, next) => {
18
- const deps = await makeDependencies(c)
19
- objectEntries(deps).forEach(([key, value]) => c.set(key, value))
20
- await next()
21
- })
22
26
  app.use(contextStorage())
23
27
  app.use('*', requestId())
24
- app.use('*', async (c, next) => {
25
- const loggerHandler = c.get('loggerHandler')
26
- await loggerHandler(c as never, async () => {
27
- c.get('logger')?.assign({ reqId: c.get('requestId') })
28
- await next()
29
- })
30
- })
28
+ app.use('*', loggerMiddleware(rootLogger))
29
+ app.use('*', inferdiHono({ container: diContainer }))
31
30
  app.use('*', secureHeaders())
32
- app.use('*', corsMiddleware())
31
+ app.use('*', corsMiddleware(appConfig.middleware.cors))
33
32
  app.use('*', csrf())
34
33
 
35
- app.route('/', exampleRoutes)
34
+ app.get(
35
+ '/health',
36
+ describeRoute({
37
+ operationId: 'getHealth',
38
+ tags: [OpenApiTags.System],
39
+ summary: 'Health check',
40
+ responses: { 200: jsonResponse(v.object({ data: v.object({ status: v.string() }) })) },
41
+ }),
42
+ (c) => successJson(c, { status: 'ok' }),
43
+ )
44
+ app.route('/examples', exampleRoutes)
36
45
  configureOpenAPI(app)
37
46
 
38
47
  app.notFound(() => {
39
48
  throw E.NORMAL.NOT_FOUND.create()
40
49
  })
41
50
  app.onError(globalErrorHandler)
42
- return app
51
+ return {
52
+ app,
53
+ logger: rootLogger,
54
+ dispose: async () => {
55
+ await diContainer.dispose()
56
+ await flushPino(rootLogger)
57
+ },
58
+ }
43
59
  }
@@ -9,7 +9,7 @@ import {
9
9
  } from '@repo/definition/backend'
10
10
  import { getRuntimeKey } from 'hono/adapter'
11
11
  import { flatten as flattenValiIssues, isValiError } from 'valibot'
12
- import type { AppConfig } from '@/shared/app/types'
12
+ import type { AppConfig } from '@/shared/types/app'
13
13
 
14
14
  export function resolveConfig(context: Record<string, unknown>): AppConfig {
15
15
  try {
@@ -0,0 +1,51 @@
1
+ import { getRuntimeKey } from 'hono/adapter'
2
+ import { Container } from '@inferdi/inferdi'
3
+ import { resolveConfig } from './config'
4
+ import { createPino } from './infra/logger/pino'
5
+ import { sqliteSchemaConfig } from '@repo/definition/backend'
6
+ import { createD1Client, type D1Binding } from '@repo/db/sqlite/d1-client'
7
+ import { createSqliteClient } from '@repo/db/sqlite/sqlite'
8
+ import type { Database } from './shared/types/db'
9
+ import { exampleModule } from './modules/example/module'
10
+ import { PassThroughRunner } from './infra/work-runner/pass-through/runner'
11
+ // import { PiscinaWorkRunner } from './infra/work-runner/piscina/runner'
12
+ import type { AppWorkRunner } from './infra/work-runner/types'
13
+
14
+ export const createDIContainer = ({ env }: { env: Record<string, unknown> }) => {
15
+ const runtimeKey = getRuntimeKey()
16
+ return new Container()
17
+ .registerValue('appConfig', resolveConfig(env))
18
+ .registerFactory('rootLogger', (c) => {
19
+ const { runtime, log } = c.get('appConfig')
20
+ return createPino({
21
+ isLocal: runtime.isLocal,
22
+ logConfig: log,
23
+ })
24
+ })
25
+ .registerFactory('database', (): Database => {
26
+ if (runtimeKey === 'workerd') return createD1Client(env.DB as D1Binding)
27
+
28
+ const { dbPath } = sqliteSchemaConfig.resolve({
29
+ context: env,
30
+ matchContextKey: 'constantCase',
31
+ })
32
+ const client = createSqliteClient(dbPath)
33
+ return {
34
+ db: client.db,
35
+ [Symbol.dispose]() {
36
+ client.close()
37
+ },
38
+ }
39
+ })
40
+ .registerFactory('workRunner', (_c) => {
41
+ // Enable together with the worker pack entry in vite.config.ts.
42
+ // const runner: AppWorkRunner = PiscinaWorkRunner.getInstance(_c.get('appConfig').worker)
43
+ const runner: AppWorkRunner = new PassThroughRunner()
44
+ return Object.assign(runner, {
45
+ [Symbol.asyncDispose]: () => runner.shutdown(),
46
+ })
47
+ })
48
+ .use(exampleModule)
49
+ }
50
+
51
+ export type DIContainer = ReturnType<typeof createDIContainer>
@@ -1,4 +1,4 @@
1
- import type { AppEnv, AppLogger } from '@/shared/app/types'
1
+ import type { AppEnv, AppLogger } from '@/shared/types/app'
2
2
  import { hasProp } from '@/shared/utils'
3
3
  import { getContext } from 'hono/context-storage'
4
4
 
@@ -1,9 +1,8 @@
1
1
  import { createRequire } from 'node:module'
2
2
  import { isAbsolute, join, resolve } from 'node:path'
3
- import { type Runtime } from 'hono/adapter'
4
- import { pinoLogger } from 'hono-pino'
5
- import pino, { type LoggerOptions } from 'pino'
6
- import type { AppConfig } from '@/shared/app/types'
3
+ import { getRuntimeKey } from 'hono/adapter'
4
+ import pino, { type Logger, type LoggerOptions } from 'pino'
5
+ import type { LogConfig } from '@/shared/types/app'
7
6
  import { serializeErr } from '@/shared/errors/log'
8
7
 
9
8
  // const pinoInstance = pino({
@@ -33,7 +32,7 @@ export const createPinoOptions = ({
33
32
  baseConfig,
34
33
  }: {
35
34
  isLocal: boolean
36
- baseConfig: AppConfig['log']['base']
35
+ baseConfig: LogConfig['base']
37
36
  }) => {
38
37
  const pinoOptions: LoggerOptions = {
39
38
  level: baseConfig.loggerLevel || (isLocal ? 'debug' : 'info'),
@@ -69,38 +68,28 @@ export const createPinoOptions = ({
69
68
  return pinoOptions
70
69
  }
71
70
 
72
- export const createPinoLogger = ({
73
- isLocal,
74
- logBase,
75
- runtime,
76
- logRoll,
77
- logPretty,
78
- }: {
79
- isLocal: boolean
80
- logBase: AppConfig['log']['base']
81
- runtime: Runtime
82
- logRoll?: AppConfig['log']['roll']
83
- logPretty?: AppConfig['log']['pretty']
84
- }) => {
85
- const pinoOptions = createPinoOptions({ isLocal, baseConfig: logBase })
71
+ export const createPino = ({ isLocal, logConfig }: { isLocal: boolean; logConfig: LogConfig }) => {
72
+ const runtime = getRuntimeKey()
73
+ const { base, roll, pretty } = logConfig
74
+ const pinoOptions = createPinoOptions({ isLocal, baseConfig: base })
86
75
  const level = pinoOptions.level
87
76
  if (runtime === 'node' || runtime === 'bun') {
88
- if (isLocal && logPretty) {
77
+ if (isLocal && pretty) {
89
78
  try {
90
79
  createRequire(import.meta.url).resolve('pino-pretty')
91
- pinoOptions.transport = { target: 'pino-pretty', level, options: logPretty }
80
+ pinoOptions.transport = { target: 'pino-pretty', level, options: pretty }
92
81
  } catch {
93
82
  console.warn('[logger] pino-pretty is not installed; falling back to JSON stdout')
94
83
  }
95
- } else if (logRoll) {
96
- const { loggerDir, loggerFileBase } = logRoll
84
+ } else if (roll) {
85
+ const { loggerDir, loggerFileBase } = roll
97
86
  pinoOptions.transport = {
98
87
  targets: [
99
88
  {
100
89
  target: 'pino-roll',
101
90
  level,
102
91
  options: {
103
- ...logRoll,
92
+ ...roll,
104
93
  file: join(
105
94
  isAbsolute(loggerDir) ? loggerDir : resolve(process.cwd(), loggerDir),
106
95
  loggerFileBase,
@@ -112,15 +101,13 @@ export const createPinoLogger = ({
112
101
  }
113
102
  }
114
103
  }
115
- const rootLogger = pino(pinoOptions)
116
- const loggerHandler = pinoLogger({
117
- pino: rootLogger,
118
- // access log 只记请求完成;错误细节由 onError 走 serializers.err。
119
- // 默认在 c.error 时升 error 且 msg=error.message,会打出一条无结构的重复 error。
120
- http: {
121
- onResLevel: () => 'info',
122
- onResMessage: () => 'Request completed',
123
- },
104
+ return pino(pinoOptions)
105
+ }
106
+
107
+ export const flushPino = async (logger: Logger) => {
108
+ const runtime = getRuntimeKey()
109
+ if (runtime !== 'node' && runtime !== 'bun') return
110
+ await new Promise<void>((resolve, reject) => {
111
+ logger.flush((error) => (error ? reject(error) : resolve()))
124
112
  })
125
- return { rootLogger, loggerHandler }
126
113
  }
@@ -1,6 +1,7 @@
1
1
  import { hasProp } from '@/shared/utils'
2
2
  import { WorkerErrorCode } from './constants'
3
3
  import type { RunnerTaskError, RunnerTaskErrorDetails } from './types'
4
+ import { isWorkerTaskBusinessError } from './utils/business-error'
4
5
 
5
6
  const workerErrorCodes = Object.values(WorkerErrorCode)
6
7
 
@@ -38,3 +39,24 @@ export function isWorkerTaskError(error: unknown): error is WorkerTaskError {
38
39
  workerErrorCodes.includes(error.code as WorkerErrorCode))
39
40
  )
40
41
  }
42
+
43
+ export function serializeWorkerTaskError(error: unknown): RunnerTaskError<WorkerErrorCode> {
44
+ if (isWorkerTaskError(error)) return error.serialize()
45
+ if (isWorkerTaskBusinessError(error)) {
46
+ return new WorkerTaskError(
47
+ WorkerErrorCode.TASK_INTERNAL,
48
+ error.message,
49
+ error.cause.details,
50
+ error.cause.cause,
51
+ ).serialize()
52
+ }
53
+ if (error instanceof Error && error.name === 'AbortError') {
54
+ return new WorkerTaskError(WorkerErrorCode.TASK_ABORTED, error.message, undefined).serialize()
55
+ }
56
+ return new WorkerTaskError(
57
+ WorkerErrorCode.UNKNOWN,
58
+ 'Worker task failed unexpectedly',
59
+ undefined,
60
+ error,
61
+ ).serialize()
62
+ }
@@ -1,41 +1,47 @@
1
- import { executeExampleTask } from '../example/worker-entry'
1
+ import { executeExampleTask as runExampleTask } from '@/modules/example/work-task/tasks'
2
2
  import { getLogger } from '@/infra/logger/getter'
3
3
  import { WorkSubject } from '../constants'
4
+ import { serializeWorkerTaskError } from '../errors'
4
5
  import type {
5
6
  AppWorkRunner,
7
+ RunnerTaskInput,
6
8
  RunnerTaskParams,
7
9
  RunnerTaskRunOptions,
8
10
  RunnerTaskRunResult,
9
- WorkerMessage,
10
- WorkerMessagePort,
11
11
  } from '../types'
12
- import { handleWorkerMessage } from '../utils/message'
13
12
 
14
- function createMessagePort(subject: WorkSubject): WorkerMessagePort {
15
- const logger = getLogger()
16
- return {
17
- postMessage(message: WorkerMessage) {
18
- handleWorkerMessage(message, logger, { subject })
19
- },
20
- close() {},
21
- }
13
+ const taskMap = {
14
+ [WorkSubject.PROCESS_EXAMPLE]: runExampleTask,
15
+ } satisfies {
16
+ [TSubject in WorkSubject]?: (
17
+ input: RunnerTaskInput<TSubject>,
18
+ ) => Promise<RunnerTaskRunResult<TSubject>>
22
19
  }
23
20
 
24
- export class PassThroughWorkRunner implements AppWorkRunner {
21
+ export class PassThroughRunner implements AppWorkRunner {
25
22
  async run<TSubject extends WorkSubject>(
26
- taskParams: RunnerTaskParams<TSubject>,
23
+ task: RunnerTaskParams<TSubject>,
27
24
  options?: RunnerTaskRunOptions,
28
25
  ): Promise<RunnerTaskRunResult<TSubject>> {
29
- if (taskParams.subject !== WorkSubject.PROCESS_EXAMPLE) {
30
- throw new Error(`[PassThroughWorkRunner] task name not found: ${String(taskParams.subject)}`)
26
+ const targetTask = taskMap[task.subject]
27
+ if (!targetTask) {
28
+ throw new Error(`[PassThroughRunner] task name not found: ${String(task.subject)}`)
31
29
  }
32
30
 
33
- options?.signal?.throwIfAborted()
34
-
35
- return executeExampleTask({
36
- input: taskParams.input,
37
- messagePort: createMessagePort(taskParams.subject),
38
- }) as Promise<RunnerTaskRunResult<TSubject>>
31
+ const logger = getLogger().child({ subject: task.subject })
32
+ logger.debug('Task executing in current thread')
33
+ let result: RunnerTaskRunResult<TSubject>
34
+ try {
35
+ options?.signal?.throwIfAborted()
36
+ result = (await targetTask(task.input)) as RunnerTaskRunResult<TSubject>
37
+ } catch (error) {
38
+ result = { ok: false, error: serializeWorkerTaskError(error) }
39
+ }
40
+ logger[result.ok ? 'info' : 'error'](
41
+ { subject: task.subject, ok: result.ok },
42
+ `Task ${result.ok ? 'completed' : 'failed'}`,
43
+ )
44
+ return result
39
45
  }
40
46
 
41
47
  async shutdown(): Promise<void> {}