create-next-imagicma 0.1.13 → 0.1.15

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 (33) hide show
  1. package/package.json +1 -1
  2. package/template-hono/.env.example +16 -3
  3. package/template-hono/AGENTS.md +91 -16
  4. package/template-hono/README.md +89 -3
  5. package/template-hono/client/src/components/HelloClient.tsx +1 -1
  6. package/template-hono/client/src/globals.css +1 -417
  7. package/template-hono/client/src/lib/ai-ui-stream.ts +64 -0
  8. package/template-hono/client/src/providers.tsx +1 -1
  9. package/template-hono/client/src/theme/default-theme.css +482 -0
  10. package/template-hono/drizzle.config.ts +3 -36
  11. package/template-hono/package.json +5 -1
  12. package/template-hono/pnpm-lock.yaml +186 -54
  13. package/template-hono/server/app.ts +2 -0
  14. package/template-hono/server/controllers/ai-chat-controller.ts +49 -0
  15. package/template-hono/server/controllers/greeting-controller.ts +25 -0
  16. package/template-hono/server/db/client.ts +25 -0
  17. package/template-hono/server/env.ts +89 -0
  18. package/template-hono/server/index.ts +1 -1
  19. package/template-hono/server/lib/ai-provider.ts +74 -0
  20. package/template-hono/server/lib/ai.ts +205 -0
  21. package/template-hono/server/middlewares/auth.ts +69 -0
  22. package/template-hono/server/middlewares/index.ts +12 -0
  23. package/template-hono/server/repositories/message-repository.ts +13 -0
  24. package/template-hono/server/routes/ai-chat.ts +9 -0
  25. package/template-hono/server/routes/greeting.ts +2 -18
  26. package/template-hono/shared/routes.ts +55 -0
  27. package/template-hono/shared/schema/greeting.ts +17 -0
  28. package/template-hono/shared/schema.ts +8 -16
  29. package/template-hono/tailwind.config.mjs +111 -62
  30. package/template-hono/vite.config.ts +1 -1
  31. package/template-hono/server/database-path.ts +0 -35
  32. package/template-hono/server/db.ts +0 -20
  33. package/template-hono/server/storage.ts +0 -30
@@ -8,15 +8,18 @@ importers:
8
8
 
9
9
  .:
10
10
  dependencies:
11
+ '@ai-sdk/openai':
12
+ specifier: ^2.0.102
13
+ version: 2.0.102(zod@4.3.6)
14
+ '@ai-sdk/openai-compatible':
15
+ specifier: ^1.0.13
16
+ version: 1.0.35(zod@4.3.6)
11
17
  '@hono/node-server':
12
18
  specifier: ^1.19.9
13
19
  version: 1.19.9(hono@4.11.9)
14
20
  '@hono/zod-validator':
15
21
  specifier: ^0.7.6
16
22
  version: 0.7.6(hono@4.11.9)(zod@4.3.6)
17
- '@libsql/client':
18
- specifier: ^0.17.0
19
- version: 0.17.0
20
23
  '@radix-ui/react-accordion':
21
24
  specifier: ^1.2.4
22
25
  version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -101,6 +104,9 @@ importers:
101
104
  '@tanstack/react-query':
102
105
  specifier: ^5.60.5
103
106
  version: 5.90.20(react@19.2.3)
107
+ ai:
108
+ specifier: ^5.0.172
109
+ version: 5.0.172(zod@4.3.6)
104
110
  class-variance-authority:
105
111
  specifier: ^0.7.1
106
112
  version: 0.7.1
@@ -112,10 +118,10 @@ importers:
112
118
  version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
113
119
  drizzle-orm:
114
120
  specifier: ^0.39.3
115
- version: 0.39.3(@libsql/client@0.17.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@11.10.0)(pg@8.18.0)
121
+ version: 0.39.3(@libsql/client@0.17.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@11.10.0)(pg@8.20.0)
116
122
  drizzle-zod:
117
123
  specifier: ^0.7.0
118
- version: 0.7.1(drizzle-orm@0.39.3(@libsql/client@0.17.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@11.10.0)(pg@8.18.0))(zod@4.3.6)
124
+ version: 0.7.1(drizzle-orm@0.39.3(@libsql/client@0.17.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@11.10.0)(pg@8.20.0))(zod@4.3.6)
119
125
  embla-carousel-react:
120
126
  specifier: ^8.6.0
121
127
  version: 8.6.0(react@19.2.3)
@@ -134,6 +140,9 @@ importers:
134
140
  next-themes:
135
141
  specifier: ^0.4.6
136
142
  version: 0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
143
+ pg:
144
+ specifier: ^8.20.0
145
+ version: 8.20.0
137
146
  react:
138
147
  specifier: 19.2.3
139
148
  version: 19.2.3
@@ -174,6 +183,9 @@ importers:
174
183
  '@types/node':
175
184
  specifier: ^20
176
185
  version: 20.19.31
186
+ '@types/pg':
187
+ specifier: ^8.20.0
188
+ version: 8.20.0
177
189
  '@types/react':
178
190
  specifier: ^19
179
191
  version: 19.2.13
@@ -207,6 +219,34 @@ importers:
207
219
 
208
220
  packages:
209
221
 
222
+ '@ai-sdk/gateway@2.0.76':
223
+ resolution: {integrity: sha512-NoL38IElvxdxxjnLDPZKapb2oFyZCMhZ3qXHyERpXC5DrRO9CwkY/48/0iXihVeG3srZ04xmxMjjgdmtE8yeQQ==}
224
+ engines: {node: '>=18'}
225
+ peerDependencies:
226
+ zod: ^3.25.76 || ^4.1.8
227
+
228
+ '@ai-sdk/openai-compatible@1.0.35':
229
+ resolution: {integrity: sha512-wDN0NfYNfe/i+12YR3n6g7zETHNQrw8WJhL9IjgNG1shXdoFDCqzitSz2rYqfqbuKirUIcChrMvjIpcr5nX14w==}
230
+ engines: {node: '>=18'}
231
+ peerDependencies:
232
+ zod: ^3.25.76 || ^4.1.8
233
+
234
+ '@ai-sdk/openai@2.0.102':
235
+ resolution: {integrity: sha512-tYarHJhyMioGegsnhpqz1/tKoCAJJ6zBHoIQaredNkt8V3o/JXj2647NnEOJVe7WHQXGvCfzbfnP1TADFhPmcA==}
236
+ engines: {node: '>=18'}
237
+ peerDependencies:
238
+ zod: ^3.25.76 || ^4.1.8
239
+
240
+ '@ai-sdk/provider-utils@3.0.23':
241
+ resolution: {integrity: sha512-60GYsRj5wIJQRcq5YwYJq4KhwLeStceXEJiZdecP1miiH+6FMmrnc7lZDOJoQ6m9lrudEb+uI4LEwddLz5+rPQ==}
242
+ engines: {node: '>=18'}
243
+ peerDependencies:
244
+ zod: ^3.25.76 || ^4.1.8
245
+
246
+ '@ai-sdk/provider@2.0.1':
247
+ resolution: {integrity: sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==}
248
+ engines: {node: '>=18'}
249
+
210
250
  '@alloc/quick-lru@5.2.0':
211
251
  resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
212
252
  engines: {node: '>=10'}
@@ -926,6 +966,10 @@ packages:
926
966
  '@neon-rs/load@0.0.4':
927
967
  resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
928
968
 
969
+ '@opentelemetry/api@1.9.0':
970
+ resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
971
+ engines: {node: '>=8.0.0'}
972
+
929
973
  '@radix-ui/number@1.1.1':
930
974
  resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
931
975
 
@@ -1727,6 +1771,9 @@ packages:
1727
1771
  cpu: [x64]
1728
1772
  os: [win32]
1729
1773
 
1774
+ '@standard-schema/spec@1.1.0':
1775
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
1776
+
1730
1777
  '@tailwindcss/node@4.1.18':
1731
1778
  resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
1732
1779
 
@@ -1878,6 +1925,9 @@ packages:
1878
1925
  '@types/node@20.19.31':
1879
1926
  resolution: {integrity: sha512-5jsi0wpncvTD33Sh1UCgacK37FFwDn+EG7wCmEvs62fCvBL+n8/76cAYDok21NF6+jaVWIqKwCZyX7Vbu8eB3A==}
1880
1927
 
1928
+ '@types/pg@8.20.0':
1929
+ resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==}
1930
+
1881
1931
  '@types/react-dom@19.2.3':
1882
1932
  resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
1883
1933
  peerDependencies:
@@ -1889,6 +1939,10 @@ packages:
1889
1939
  '@types/ws@8.18.1':
1890
1940
  resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
1891
1941
 
1942
+ '@vercel/oidc@3.1.0':
1943
+ resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==}
1944
+ engines: {node: '>= 20'}
1945
+
1892
1946
  '@vitejs/plugin-react@5.1.4':
1893
1947
  resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==}
1894
1948
  engines: {node: ^20.19.0 || >=22.12.0}
@@ -1905,6 +1959,12 @@ packages:
1905
1959
  engines: {node: '>=0.4.0'}
1906
1960
  hasBin: true
1907
1961
 
1962
+ ai@5.0.172:
1963
+ resolution: {integrity: sha512-MjHohHMW9HkdsmVUA/gfV3FYeezu+cAXADg2b8HdRwuHjEg3GsL0WqjIfgb0Z9ntEqyzcgy9oJKe4yloEIpQAw==}
1964
+ engines: {node: '>=18'}
1965
+ peerDependencies:
1966
+ zod: ^3.25.76 || ^4.1.8
1967
+
1908
1968
  ajv@6.12.6:
1909
1969
  resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
1910
1970
 
@@ -2299,6 +2359,10 @@ packages:
2299
2359
  eventemitter3@4.0.7:
2300
2360
  resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
2301
2361
 
2362
+ eventsource-parser@3.0.6:
2363
+ resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==}
2364
+ engines: {node: '>=18.0.0'}
2365
+
2302
2366
  expand-template@2.0.3:
2303
2367
  resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
2304
2368
  engines: {node: '>=6'}
@@ -2473,6 +2537,9 @@ packages:
2473
2537
  json-schema-traverse@0.4.1:
2474
2538
  resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
2475
2539
 
2540
+ json-schema@0.4.0:
2541
+ resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
2542
+
2476
2543
  json-stable-stringify-without-jsonify@1.0.1:
2477
2544
  resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
2478
2545
 
@@ -2698,27 +2765,27 @@ packages:
2698
2765
  pg-cloudflare@1.3.0:
2699
2766
  resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==}
2700
2767
 
2701
- pg-connection-string@2.11.0:
2702
- resolution: {integrity: sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==}
2768
+ pg-connection-string@2.12.0:
2769
+ resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==}
2703
2770
 
2704
2771
  pg-int8@1.0.1:
2705
2772
  resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
2706
2773
  engines: {node: '>=4.0.0'}
2707
2774
 
2708
- pg-pool@3.11.0:
2709
- resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==}
2775
+ pg-pool@3.13.0:
2776
+ resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==}
2710
2777
  peerDependencies:
2711
2778
  pg: '>=8.0'
2712
2779
 
2713
- pg-protocol@1.11.0:
2714
- resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==}
2780
+ pg-protocol@1.13.0:
2781
+ resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==}
2715
2782
 
2716
2783
  pg-types@2.2.0:
2717
2784
  resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
2718
2785
  engines: {node: '>=4'}
2719
2786
 
2720
- pg@8.18.0:
2721
- resolution: {integrity: sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==}
2787
+ pg@8.20.0:
2788
+ resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==}
2722
2789
  engines: {node: '>= 16.0.0'}
2723
2790
  peerDependencies:
2724
2791
  pg-native: '>=3.0.1'
@@ -3152,6 +3219,36 @@ packages:
3152
3219
 
3153
3220
  snapshots:
3154
3221
 
3222
+ '@ai-sdk/gateway@2.0.76(zod@4.3.6)':
3223
+ dependencies:
3224
+ '@ai-sdk/provider': 2.0.1
3225
+ '@ai-sdk/provider-utils': 3.0.23(zod@4.3.6)
3226
+ '@vercel/oidc': 3.1.0
3227
+ zod: 4.3.6
3228
+
3229
+ '@ai-sdk/openai-compatible@1.0.35(zod@4.3.6)':
3230
+ dependencies:
3231
+ '@ai-sdk/provider': 2.0.1
3232
+ '@ai-sdk/provider-utils': 3.0.23(zod@4.3.6)
3233
+ zod: 4.3.6
3234
+
3235
+ '@ai-sdk/openai@2.0.102(zod@4.3.6)':
3236
+ dependencies:
3237
+ '@ai-sdk/provider': 2.0.1
3238
+ '@ai-sdk/provider-utils': 3.0.23(zod@4.3.6)
3239
+ zod: 4.3.6
3240
+
3241
+ '@ai-sdk/provider-utils@3.0.23(zod@4.3.6)':
3242
+ dependencies:
3243
+ '@ai-sdk/provider': 2.0.1
3244
+ '@standard-schema/spec': 1.1.0
3245
+ eventsource-parser: 3.0.6
3246
+ zod: 4.3.6
3247
+
3248
+ '@ai-sdk/provider@2.0.1':
3249
+ dependencies:
3250
+ json-schema: 0.4.0
3251
+
3155
3252
  '@alloc/quick-lru@5.2.0': {}
3156
3253
 
3157
3254
  '@babel/code-frame@7.29.0':
@@ -3623,10 +3720,12 @@ snapshots:
3623
3720
  - bufferutil
3624
3721
  - encoding
3625
3722
  - utf-8-validate
3723
+ optional: true
3626
3724
 
3627
3725
  '@libsql/core@0.17.0':
3628
3726
  dependencies:
3629
3727
  js-base64: 3.7.8
3728
+ optional: true
3630
3729
 
3631
3730
  '@libsql/darwin-arm64@0.5.22':
3632
3731
  optional: true
@@ -3644,6 +3743,7 @@ snapshots:
3644
3743
  - bufferutil
3645
3744
  - encoding
3646
3745
  - utf-8-validate
3746
+ optional: true
3647
3747
 
3648
3748
  '@libsql/isomorphic-ws@0.1.5':
3649
3749
  dependencies:
@@ -3652,6 +3752,7 @@ snapshots:
3652
3752
  transitivePeerDependencies:
3653
3753
  - bufferutil
3654
3754
  - utf-8-validate
3755
+ optional: true
3655
3756
 
3656
3757
  '@libsql/linux-arm-gnueabihf@0.5.22':
3657
3758
  optional: true
@@ -3674,7 +3775,10 @@ snapshots:
3674
3775
  '@libsql/win32-x64-msvc@0.5.22':
3675
3776
  optional: true
3676
3777
 
3677
- '@neon-rs/load@0.0.4': {}
3778
+ '@neon-rs/load@0.0.4':
3779
+ optional: true
3780
+
3781
+ '@opentelemetry/api@1.9.0': {}
3678
3782
 
3679
3783
  '@radix-ui/number@1.1.1': {}
3680
3784
 
@@ -4450,6 +4554,8 @@ snapshots:
4450
4554
  '@rollup/rollup-win32-x64-msvc@4.57.1':
4451
4555
  optional: true
4452
4556
 
4557
+ '@standard-schema/spec@1.1.0': {}
4558
+
4453
4559
  '@tailwindcss/node@4.1.18':
4454
4560
  dependencies:
4455
4561
  '@jridgewell/remapping': 2.3.5
@@ -4584,6 +4690,12 @@ snapshots:
4584
4690
  dependencies:
4585
4691
  undici-types: 6.21.0
4586
4692
 
4693
+ '@types/pg@8.20.0':
4694
+ dependencies:
4695
+ '@types/node': 20.19.31
4696
+ pg-protocol: 1.13.0
4697
+ pg-types: 2.2.0
4698
+
4587
4699
  '@types/react-dom@19.2.3(@types/react@19.2.13)':
4588
4700
  dependencies:
4589
4701
  '@types/react': 19.2.13
@@ -4595,6 +4707,9 @@ snapshots:
4595
4707
  '@types/ws@8.18.1':
4596
4708
  dependencies:
4597
4709
  '@types/node': 20.19.31
4710
+ optional: true
4711
+
4712
+ '@vercel/oidc@3.1.0': {}
4598
4713
 
4599
4714
  '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.30.2))':
4600
4715
  dependencies:
@@ -4614,6 +4729,14 @@ snapshots:
4614
4729
 
4615
4730
  acorn@8.15.0: {}
4616
4731
 
4732
+ ai@5.0.172(zod@4.3.6):
4733
+ dependencies:
4734
+ '@ai-sdk/gateway': 2.0.76(zod@4.3.6)
4735
+ '@ai-sdk/provider': 2.0.1
4736
+ '@ai-sdk/provider-utils': 3.0.23(zod@4.3.6)
4737
+ '@opentelemetry/api': 1.9.0
4738
+ zod: 4.3.6
4739
+
4617
4740
  ajv@6.12.6:
4618
4741
  dependencies:
4619
4742
  fast-deep-equal: 3.1.3
@@ -4732,6 +4855,7 @@ snapshots:
4732
4855
  node-fetch: 2.7.0
4733
4856
  transitivePeerDependencies:
4734
4857
  - encoding
4858
+ optional: true
4735
4859
 
4736
4860
  cross-spawn@7.0.6:
4737
4861
  dependencies:
@@ -4779,7 +4903,8 @@ snapshots:
4779
4903
 
4780
4904
  d3-timer@3.0.1: {}
4781
4905
 
4782
- data-uri-to-buffer@4.0.1: {}
4906
+ data-uri-to-buffer@4.0.1:
4907
+ optional: true
4783
4908
 
4784
4909
  date-fns-jalali@4.1.0-0: {}
4785
4910
 
@@ -4801,7 +4926,8 @@ snapshots:
4801
4926
 
4802
4927
  deep-is@0.1.4: {}
4803
4928
 
4804
- detect-libc@2.0.2: {}
4929
+ detect-libc@2.0.2:
4930
+ optional: true
4805
4931
 
4806
4932
  detect-libc@2.1.2: {}
4807
4933
 
@@ -4821,16 +4947,18 @@ snapshots:
4821
4947
  transitivePeerDependencies:
4822
4948
  - supports-color
4823
4949
 
4824
- drizzle-orm@0.39.3(@libsql/client@0.17.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@11.10.0)(pg@8.18.0):
4950
+ drizzle-orm@0.39.3(@libsql/client@0.17.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@11.10.0)(pg@8.20.0):
4825
4951
  optionalDependencies:
4826
4952
  '@libsql/client': 0.17.0
4953
+ '@opentelemetry/api': 1.9.0
4827
4954
  '@types/better-sqlite3': 7.6.13
4955
+ '@types/pg': 8.20.0
4828
4956
  better-sqlite3: 11.10.0
4829
- pg: 8.18.0
4957
+ pg: 8.20.0
4830
4958
 
4831
- drizzle-zod@0.7.1(drizzle-orm@0.39.3(@libsql/client@0.17.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@11.10.0)(pg@8.18.0))(zod@4.3.6):
4959
+ drizzle-zod@0.7.1(drizzle-orm@0.39.3(@libsql/client@0.17.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@11.10.0)(pg@8.20.0))(zod@4.3.6):
4832
4960
  dependencies:
4833
- drizzle-orm: 0.39.3(@libsql/client@0.17.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@11.10.0)(pg@8.18.0)
4961
+ drizzle-orm: 0.39.3(@libsql/client@0.17.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.20.0)(better-sqlite3@11.10.0)(pg@8.20.0)
4834
4962
  zod: 4.3.6
4835
4963
 
4836
4964
  electron-to-chromium@1.5.286: {}
@@ -5025,6 +5153,8 @@ snapshots:
5025
5153
 
5026
5154
  eventemitter3@4.0.7: {}
5027
5155
 
5156
+ eventsource-parser@3.0.6: {}
5157
+
5028
5158
  expand-template@2.0.3:
5029
5159
  optional: true
5030
5160
 
@@ -5044,6 +5174,7 @@ snapshots:
5044
5174
  dependencies:
5045
5175
  node-domexception: 1.0.0
5046
5176
  web-streams-polyfill: 3.3.3
5177
+ optional: true
5047
5178
 
5048
5179
  file-entry-cache@8.0.0:
5049
5180
  dependencies:
@@ -5067,6 +5198,7 @@ snapshots:
5067
5198
  formdata-polyfill@4.0.10:
5068
5199
  dependencies:
5069
5200
  fetch-blob: 3.2.0
5201
+ optional: true
5070
5202
 
5071
5203
  framer-motion@11.18.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
5072
5204
  dependencies:
@@ -5141,7 +5273,8 @@ snapshots:
5141
5273
 
5142
5274
  jiti@2.6.1: {}
5143
5275
 
5144
- js-base64@3.7.8: {}
5276
+ js-base64@3.7.8:
5277
+ optional: true
5145
5278
 
5146
5279
  js-tokens@4.0.0: {}
5147
5280
 
@@ -5155,6 +5288,8 @@ snapshots:
5155
5288
 
5156
5289
  json-schema-traverse@0.4.1: {}
5157
5290
 
5291
+ json-schema@0.4.0: {}
5292
+
5158
5293
  json-stable-stringify-without-jsonify@1.0.1: {}
5159
5294
 
5160
5295
  json5@2.2.3: {}
@@ -5182,6 +5317,7 @@ snapshots:
5182
5317
  '@libsql/linux-x64-gnu': 0.5.22
5183
5318
  '@libsql/linux-x64-musl': 0.5.22
5184
5319
  '@libsql/win32-x64-msvc': 0.5.22
5320
+ optional: true
5185
5321
 
5186
5322
  lightningcss-android-arm64@1.30.2:
5187
5323
  optional: true
@@ -5302,17 +5438,20 @@ snapshots:
5302
5438
  semver: 7.7.4
5303
5439
  optional: true
5304
5440
 
5305
- node-domexception@1.0.0: {}
5441
+ node-domexception@1.0.0:
5442
+ optional: true
5306
5443
 
5307
5444
  node-fetch@2.7.0:
5308
5445
  dependencies:
5309
5446
  whatwg-url: 5.0.0
5447
+ optional: true
5310
5448
 
5311
5449
  node-fetch@3.3.2:
5312
5450
  dependencies:
5313
5451
  data-uri-to-buffer: 4.0.1
5314
5452
  fetch-blob: 3.2.0
5315
5453
  formdata-polyfill: 4.0.10
5454
+ optional: true
5316
5455
 
5317
5456
  node-releases@2.0.27: {}
5318
5457
 
@@ -5351,19 +5490,15 @@ snapshots:
5351
5490
  pg-cloudflare@1.3.0:
5352
5491
  optional: true
5353
5492
 
5354
- pg-connection-string@2.11.0:
5355
- optional: true
5493
+ pg-connection-string@2.12.0: {}
5356
5494
 
5357
- pg-int8@1.0.1:
5358
- optional: true
5495
+ pg-int8@1.0.1: {}
5359
5496
 
5360
- pg-pool@3.11.0(pg@8.18.0):
5497
+ pg-pool@3.13.0(pg@8.20.0):
5361
5498
  dependencies:
5362
- pg: 8.18.0
5363
- optional: true
5499
+ pg: 8.20.0
5364
5500
 
5365
- pg-protocol@1.11.0:
5366
- optional: true
5501
+ pg-protocol@1.13.0: {}
5367
5502
 
5368
5503
  pg-types@2.2.0:
5369
5504
  dependencies:
@@ -5372,23 +5507,20 @@ snapshots:
5372
5507
  postgres-bytea: 1.0.1
5373
5508
  postgres-date: 1.0.7
5374
5509
  postgres-interval: 1.2.0
5375
- optional: true
5376
5510
 
5377
- pg@8.18.0:
5511
+ pg@8.20.0:
5378
5512
  dependencies:
5379
- pg-connection-string: 2.11.0
5380
- pg-pool: 3.11.0(pg@8.18.0)
5381
- pg-protocol: 1.11.0
5513
+ pg-connection-string: 2.12.0
5514
+ pg-pool: 3.13.0(pg@8.20.0)
5515
+ pg-protocol: 1.13.0
5382
5516
  pg-types: 2.2.0
5383
5517
  pgpass: 1.0.5
5384
5518
  optionalDependencies:
5385
5519
  pg-cloudflare: 1.3.0
5386
- optional: true
5387
5520
 
5388
5521
  pgpass@1.0.5:
5389
5522
  dependencies:
5390
5523
  split2: 4.2.0
5391
- optional: true
5392
5524
 
5393
5525
  picocolors@1.1.1: {}
5394
5526
 
@@ -5400,19 +5532,15 @@ snapshots:
5400
5532
  picocolors: 1.1.1
5401
5533
  source-map-js: 1.2.1
5402
5534
 
5403
- postgres-array@2.0.0:
5404
- optional: true
5535
+ postgres-array@2.0.0: {}
5405
5536
 
5406
- postgres-bytea@1.0.1:
5407
- optional: true
5537
+ postgres-bytea@1.0.1: {}
5408
5538
 
5409
- postgres-date@1.0.7:
5410
- optional: true
5539
+ postgres-date@1.0.7: {}
5411
5540
 
5412
5541
  postgres-interval@1.2.0:
5413
5542
  dependencies:
5414
5543
  xtend: 4.0.2
5415
- optional: true
5416
5544
 
5417
5545
  prebuild-install@7.1.3:
5418
5546
  dependencies:
@@ -5432,7 +5560,8 @@ snapshots:
5432
5560
 
5433
5561
  prelude-ls@1.2.1: {}
5434
5562
 
5435
- promise-limit@2.7.0: {}
5563
+ promise-limit@2.7.0:
5564
+ optional: true
5436
5565
 
5437
5566
  prop-types@15.8.1:
5438
5567
  dependencies:
@@ -5635,8 +5764,7 @@ snapshots:
5635
5764
 
5636
5765
  source-map@0.6.1: {}
5637
5766
 
5638
- split2@4.2.0:
5639
- optional: true
5767
+ split2@4.2.0: {}
5640
5768
 
5641
5769
  string_decoder@1.3.0:
5642
5770
  dependencies:
@@ -5686,7 +5814,8 @@ snapshots:
5686
5814
  fdir: 6.5.0(picomatch@4.0.3)
5687
5815
  picomatch: 4.0.3
5688
5816
 
5689
- tr46@0.0.3: {}
5817
+ tr46@0.0.3:
5818
+ optional: true
5690
5819
 
5691
5820
  tslib@2.8.1: {}
5692
5821
 
@@ -5783,14 +5912,17 @@ snapshots:
5783
5912
  jiti: 2.6.1
5784
5913
  lightningcss: 1.30.2
5785
5914
 
5786
- web-streams-polyfill@3.3.3: {}
5915
+ web-streams-polyfill@3.3.3:
5916
+ optional: true
5787
5917
 
5788
- webidl-conversions@3.0.1: {}
5918
+ webidl-conversions@3.0.1:
5919
+ optional: true
5789
5920
 
5790
5921
  whatwg-url@5.0.0:
5791
5922
  dependencies:
5792
5923
  tr46: 0.0.3
5793
5924
  webidl-conversions: 3.0.1
5925
+ optional: true
5794
5926
 
5795
5927
  which@2.0.2:
5796
5928
  dependencies:
@@ -5801,11 +5933,11 @@ snapshots:
5801
5933
  wrappy@1.0.2:
5802
5934
  optional: true
5803
5935
 
5804
- ws@8.19.0: {}
5805
-
5806
- xtend@4.0.2:
5936
+ ws@8.19.0:
5807
5937
  optional: true
5808
5938
 
5939
+ xtend@4.0.2: {}
5940
+
5809
5941
  yallist@3.1.1: {}
5810
5942
 
5811
5943
  yocto-queue@0.1.0: {}
@@ -1,5 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import { serveStatic } from "@hono/node-server/serve-static";
3
+ import { aiChatRoute } from "./routes/ai-chat";
3
4
  import { greetingRoute } from "./routes/greeting";
4
5
 
5
6
  type CreateAppOptions = {
@@ -19,6 +20,7 @@ export function createApp({ serveClient = false }: CreateAppOptions = {}) {
19
20
  });
20
21
 
21
22
  app.route("/", greetingRoute);
23
+ app.route("/", aiChatRoute);
22
24
 
23
25
  if (serveClient) {
24
26
  const serveClientFiles = serveStatic({ root: "./dist/client" });
@@ -0,0 +1,49 @@
1
+ import type { Context } from "hono";
2
+ import { ZodError } from "zod";
3
+ import { api } from "../../shared/routes";
4
+ import { createAiErrorBody, AiGatewayError, streamAiChat } from "../lib/ai";
5
+
6
+ export async function postAiChat(c: Context) {
7
+ try {
8
+ const payload = await c.req.json();
9
+ const body = api.ai.chat.post.request.body.parse(payload);
10
+
11
+ return streamAiChat(body.messages, c.req.raw.signal);
12
+ } catch (error) {
13
+ if (error instanceof SyntaxError) {
14
+ return c.json(
15
+ createAiErrorBody("AI_INVALID_JSON", "请求体必须是合法 JSON。"),
16
+ 400,
17
+ );
18
+ }
19
+
20
+ if (error instanceof ZodError) {
21
+ return c.json(
22
+ createAiErrorBody(
23
+ "AI_INVALID_REQUEST",
24
+ "AI 请求体不符合约定,请检查 messages 与 parts 结构。",
25
+ ),
26
+ 400,
27
+ );
28
+ }
29
+
30
+ if (error instanceof AiGatewayError) {
31
+ const status = error.status === 400 ? 400 : 500;
32
+
33
+ return c.json(
34
+ createAiErrorBody(error.code, error.message),
35
+ status,
36
+ );
37
+ }
38
+
39
+ console.error("POST /api/ai/chat failed:", error);
40
+
41
+ return c.json(
42
+ createAiErrorBody(
43
+ "AI_GATEWAY_ERROR",
44
+ "AI 网关请求失败,请稍后重试。",
45
+ ),
46
+ 500,
47
+ );
48
+ }
49
+ }
@@ -0,0 +1,25 @@
1
+ import type { Context } from "hono";
2
+ import { api } from "../../shared/routes";
3
+ import { findLatestMessage } from "../repositories/message-repository";
4
+
5
+ const DEFAULT_GREETING_MESSAGE = "Hello from the Backend API!";
6
+
7
+ export async function getGreeting(c: Context) {
8
+ try {
9
+ const message = (await findLatestMessage()) ?? DEFAULT_GREETING_MESSAGE;
10
+ const body = { message };
11
+
12
+ api.greeting.get.responses[200].parse(body);
13
+
14
+ return c.json(body);
15
+ } catch (error) {
16
+ console.error("GET /api/greeting failed:", error);
17
+
18
+ const message =
19
+ error instanceof Error
20
+ ? "数据库读取失败:请确认 .env.local 中的 DATABASE_URL 可用,并执行 `pnpm db:push` 初始化 PostgreSQL 数据库。"
21
+ : "Internal Server Error";
22
+
23
+ return c.json({ message }, 500);
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+ import pg from "pg";
3
+ import * as schema from "../../shared/schema";
4
+ import { requireDatabaseUrl } from "../env";
5
+
6
+ const { Pool } = pg;
7
+ const databaseUrl = requireDatabaseUrl();
8
+ type DatabasePool = InstanceType<typeof Pool>;
9
+
10
+ declare global {
11
+ var __dbPool: DatabasePool | undefined;
12
+ }
13
+
14
+ const pool =
15
+ globalThis.__dbPool ??
16
+ new Pool({
17
+ connectionString: databaseUrl,
18
+ });
19
+
20
+ if (process.env.NODE_ENV !== "production") {
21
+ globalThis.__dbPool = pool;
22
+ }
23
+
24
+ export const db = drizzle(pool, { schema });
25
+ export { databaseUrl, pool };