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
@@ -1,5 +1,114 @@
1
1
  import animate from "tailwindcss-animate";
2
2
 
3
+ const withAlpha = (name) => `hsl(var(--${name}) / <alpha-value>)`;
4
+
5
+ const themeBorderRadius = {
6
+ lg: "var(--radius)",
7
+ md: "calc(var(--radius) - 0.125rem)",
8
+ sm: "calc(var(--radius) - 0.25rem)",
9
+ full: "var(--radius-full-token)",
10
+ };
11
+
12
+ const themeColors = {
13
+ background: withAlpha("background"),
14
+ foreground: withAlpha("foreground"),
15
+ border: withAlpha("border"),
16
+ input: withAlpha("input"),
17
+ ring: withAlpha("ring"),
18
+
19
+ card: withAlpha("card"),
20
+ "card-foreground": withAlpha("card-foreground"),
21
+ "card-border": withAlpha("card-border"),
22
+
23
+ popover: withAlpha("popover"),
24
+ "popover-foreground": withAlpha("popover-foreground"),
25
+ "popover-border": withAlpha("popover-border"),
26
+
27
+ primary: withAlpha("primary"),
28
+ "primary-foreground": withAlpha("primary-foreground"),
29
+ "primary-border": "var(--primary-border)",
30
+
31
+ secondary: withAlpha("secondary"),
32
+ "secondary-foreground": withAlpha("secondary-foreground"),
33
+ "secondary-border": "var(--secondary-border)",
34
+
35
+ muted: withAlpha("muted"),
36
+ "muted-foreground": withAlpha("muted-foreground"),
37
+ "muted-border": "var(--muted-border)",
38
+
39
+ accent: withAlpha("accent"),
40
+ "accent-foreground": withAlpha("accent-foreground"),
41
+ "accent-border": "var(--accent-border)",
42
+
43
+ destructive: withAlpha("destructive"),
44
+ "destructive-foreground": withAlpha("destructive-foreground"),
45
+ "destructive-border": "var(--destructive-border)",
46
+
47
+ sidebar: withAlpha("sidebar"),
48
+ "sidebar-foreground": withAlpha("sidebar-foreground"),
49
+ "sidebar-border": withAlpha("sidebar-border"),
50
+ "sidebar-ring": withAlpha("sidebar-ring"),
51
+ "sidebar-accent": withAlpha("sidebar-accent"),
52
+ "sidebar-accent-foreground": withAlpha("sidebar-accent-foreground"),
53
+
54
+ "chart-1": withAlpha("chart-1"),
55
+ "chart-2": withAlpha("chart-2"),
56
+ "chart-3": withAlpha("chart-3"),
57
+ "chart-4": withAlpha("chart-4"),
58
+ "chart-5": withAlpha("chart-5"),
59
+
60
+ "background-base": withAlpha("background-base"),
61
+ "on-background": withAlpha("on-background"),
62
+ surface: withAlpha("surface"),
63
+ "surface-bright": withAlpha("surface-bright"),
64
+ "surface-dim": withAlpha("surface-dim"),
65
+ "surface-container-lowest": withAlpha("surface-container-lowest"),
66
+ "surface-container-low": withAlpha("surface-container-low"),
67
+ "surface-container": withAlpha("surface-container"),
68
+ "surface-container-high": withAlpha("surface-container-high"),
69
+ "surface-container-highest": withAlpha("surface-container-highest"),
70
+ "surface-variant": withAlpha("surface-variant"),
71
+ "surface-tint": withAlpha("surface-tint"),
72
+ "on-surface": withAlpha("on-surface"),
73
+ "on-surface-variant": withAlpha("on-surface-variant"),
74
+
75
+ "primary-container": withAlpha("primary-container"),
76
+ "on-primary": withAlpha("on-primary"),
77
+ "on-primary-container": withAlpha("on-primary-container"),
78
+ "primary-fixed": withAlpha("primary-fixed"),
79
+ "primary-fixed-dim": withAlpha("primary-fixed-dim"),
80
+ "on-primary-fixed": withAlpha("on-primary-fixed"),
81
+ "on-primary-fixed-variant": withAlpha("on-primary-fixed-variant"),
82
+ "inverse-primary": withAlpha("inverse-primary"),
83
+
84
+ "secondary-container": withAlpha("secondary-container"),
85
+ "on-secondary": withAlpha("on-secondary"),
86
+ "on-secondary-container": withAlpha("on-secondary-container"),
87
+ "secondary-fixed": withAlpha("secondary-fixed"),
88
+ "secondary-fixed-dim": withAlpha("secondary-fixed-dim"),
89
+ "on-secondary-fixed": withAlpha("on-secondary-fixed"),
90
+ "on-secondary-fixed-variant": withAlpha("on-secondary-fixed-variant"),
91
+
92
+ tertiary: withAlpha("tertiary"),
93
+ "tertiary-container": withAlpha("tertiary-container"),
94
+ "on-tertiary": withAlpha("on-tertiary"),
95
+ "on-tertiary-container": withAlpha("on-tertiary-container"),
96
+ "tertiary-fixed": withAlpha("tertiary-fixed"),
97
+ "tertiary-fixed-dim": withAlpha("tertiary-fixed-dim"),
98
+ "on-tertiary-fixed": withAlpha("on-tertiary-fixed"),
99
+ "on-tertiary-fixed-variant": withAlpha("on-tertiary-fixed-variant"),
100
+
101
+ error: withAlpha("error"),
102
+ "on-error": withAlpha("on-error"),
103
+ "error-container": withAlpha("error-container"),
104
+ "on-error-container": withAlpha("on-error-container"),
105
+
106
+ outline: withAlpha("outline"),
107
+ "outline-variant": withAlpha("outline-variant"),
108
+ "inverse-surface": withAlpha("inverse-surface"),
109
+ "inverse-on-surface": withAlpha("inverse-on-surface"),
110
+ };
111
+
3
112
  /** @type {import("tailwindcss").Config} */
4
113
  const config = {
5
114
  darkMode: ["class"],
@@ -10,68 +119,8 @@ const config = {
10
119
  ],
11
120
  theme: {
12
121
  extend: {
13
- borderRadius: {
14
- lg: "var(--radius)",
15
- md: "calc(var(--radius) - 2px)",
16
- sm: "calc(var(--radius) - 4px)",
17
- },
18
- colors: {
19
- background: "hsl(var(--background) / <alpha-value>)",
20
- foreground: "hsl(var(--foreground) / <alpha-value>)",
21
- border: "hsl(var(--border) / <alpha-value>)",
22
- input: "hsl(var(--input) / <alpha-value>)",
23
- ring: "hsl(var(--ring) / <alpha-value>)",
24
- card: {
25
- DEFAULT: "hsl(var(--card) / <alpha-value>)",
26
- foreground: "hsl(var(--card-foreground) / <alpha-value>)",
27
- border: "hsl(var(--card-border) / <alpha-value>)",
28
- },
29
- popover: {
30
- DEFAULT: "hsl(var(--popover) / <alpha-value>)",
31
- foreground: "hsl(var(--popover-foreground) / <alpha-value>)",
32
- border: "hsl(var(--popover-border) / <alpha-value>)",
33
- },
34
- primary: {
35
- DEFAULT: "hsl(var(--primary) / <alpha-value>)",
36
- foreground: "hsl(var(--primary-foreground) / <alpha-value>)",
37
- border: "var(--primary-border)",
38
- },
39
- secondary: {
40
- DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
41
- foreground: "hsl(var(--secondary-foreground) / <alpha-value>)",
42
- border: "var(--secondary-border)",
43
- },
44
- muted: {
45
- DEFAULT: "hsl(var(--muted) / <alpha-value>)",
46
- foreground: "hsl(var(--muted-foreground) / <alpha-value>)",
47
- border: "var(--muted-border)",
48
- },
49
- accent: {
50
- DEFAULT: "hsl(var(--accent) / <alpha-value>)",
51
- foreground: "hsl(var(--accent-foreground) / <alpha-value>)",
52
- border: "var(--accent-border)",
53
- },
54
- destructive: {
55
- DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
56
- foreground: "hsl(var(--destructive-foreground) / <alpha-value>)",
57
- border: "var(--destructive-border)",
58
- },
59
- chart: {
60
- "1": "hsl(var(--chart-1) / <alpha-value>)",
61
- "2": "hsl(var(--chart-2) / <alpha-value>)",
62
- "3": "hsl(var(--chart-3) / <alpha-value>)",
63
- "4": "hsl(var(--chart-4) / <alpha-value>)",
64
- "5": "hsl(var(--chart-5) / <alpha-value>)",
65
- },
66
- sidebar: {
67
- DEFAULT: "hsl(var(--sidebar) / <alpha-value>)",
68
- foreground: "hsl(var(--sidebar-foreground) / <alpha-value>)",
69
- border: "hsl(var(--sidebar-border) / <alpha-value>)",
70
- ring: "hsl(var(--sidebar-ring) / <alpha-value>)",
71
- accent: "hsl(var(--accent) / <alpha-value>)",
72
- "accent-foreground": "hsl(var(--accent-foreground) / <alpha-value>)",
73
- },
74
- },
122
+ borderRadius: themeBorderRadius,
123
+ colors: themeColors,
75
124
  keyframes: {
76
125
  "accordion-down": {
77
126
  from: { height: "0" },
@@ -50,7 +50,7 @@ async function readRuntimeEnvPort() {
50
50
  return null;
51
51
  }
52
52
 
53
- async function resolveRuntimePort(raw = process.env.PORT) {
53
+ async function resolveRuntimePort(raw: string | null | undefined = process.env.PORT) {
54
54
  let candidate = raw;
55
55
  if (candidate === undefined || candidate === null || candidate === "") {
56
56
  candidate = await readRuntimeEnvPort();
@@ -1,35 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { pathToFileURL } from "node:url";
4
-
5
- const DEFAULT_DATABASE_FILE = "./.data/app.db";
6
-
7
- export function resolveDatabaseFilePath() {
8
- const configuredPath = process.env.DATABASE_FILE?.trim();
9
- const targetPath =
10
- configuredPath && configuredPath.length > 0 ? configuredPath : DEFAULT_DATABASE_FILE;
11
-
12
- return path.resolve(process.cwd(), targetPath);
13
- }
14
-
15
- export function ensureDatabaseFilePath() {
16
- const databaseFilePath = resolveDatabaseFilePath();
17
-
18
- fs.mkdirSync(path.dirname(databaseFilePath), { recursive: true });
19
-
20
- return databaseFilePath;
21
- }
22
-
23
- export function resolveDatabaseUrl(databaseFilePath = resolveDatabaseFilePath()) {
24
- return pathToFileURL(databaseFilePath).href;
25
- }
26
-
27
- export function ensureDatabaseUrl() {
28
- const databaseFilePath = ensureDatabaseFilePath();
29
-
30
- return resolveDatabaseUrl(databaseFilePath);
31
- }
32
-
33
- export function describeDatabaseFilePath(databaseFilePath = resolveDatabaseFilePath()) {
34
- return path.relative(process.cwd(), databaseFilePath) || path.basename(databaseFilePath);
35
- }
@@ -1,20 +0,0 @@
1
- import { createClient } from "@libsql/client";
2
- import { drizzle } from "drizzle-orm/libsql";
3
- import * as schema from "../shared/schema";
4
- import { ensureDatabaseUrl } from "./database-path";
5
-
6
- const databaseUrl = ensureDatabaseUrl();
7
- type DatabaseClient = ReturnType<typeof createClient>;
8
-
9
- declare global {
10
- var __dbClient: DatabaseClient | undefined;
11
- }
12
-
13
- const sqlite = globalThis.__dbClient ?? createClient({ url: databaseUrl });
14
-
15
- if (process.env.NODE_ENV !== "production") {
16
- globalThis.__dbClient = sqlite;
17
- }
18
-
19
- export const db = drizzle(sqlite, { schema });
20
- export { databaseUrl };
@@ -1,30 +0,0 @@
1
- import { desc } from "drizzle-orm";
2
- import { messages } from "../shared/schema";
3
- import { describeDatabaseFilePath } from "./database-path";
4
- import { db } from "./db";
5
-
6
- export interface IStorage {
7
- getMessage(): Promise<string>;
8
- }
9
-
10
- export class DatabaseStorage implements IStorage {
11
- async getMessage(): Promise<string> {
12
- try {
13
- const rows = await db
14
- .select({ content: messages.content })
15
- .from(messages)
16
- .orderBy(desc(messages.id))
17
- .limit(1);
18
-
19
- return rows[0]?.content ?? "Hello from the Backend API!";
20
- } catch (error) {
21
- console.error("DatabaseStorage.getMessage() failed:", error);
22
-
23
- throw new Error(
24
- `数据库读取失败:请先执行 \`pnpm db:push\` 初始化 SQLite 数据库(${describeDatabaseFilePath()})。`,
25
- );
26
- }
27
- }
28
- }
29
-
30
- export const storage = new DatabaseStorage();