create-next-imagicma 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/template-hono/.env.example +6 -14
  4. package/template-hono/.imagicma/AGENTS.md +7 -0
  5. package/template-hono/AGENTS.md +98 -120
  6. package/template-hono/README.md +86 -118
  7. package/template-hono/client/index.html +1 -1
  8. package/template-hono/client/public/imagicma-picker-bridge.js +2 -6
  9. package/template-hono/client/public/imagicma-preview-feedback.js +0 -1
  10. package/template-hono/client/src/components/HelloClient.tsx +1 -1
  11. package/template-hono/client/src/globals.css +417 -1
  12. package/template-hono/client/src/lib/imagicma-preview-bridge.ts +1 -1
  13. package/template-hono/client/src/lib/imagicma-preview-picker.ts +28 -130
  14. package/template-hono/client/src/providers.tsx +1 -1
  15. package/template-hono/gitignore +2 -1
  16. package/template-hono/package.json +9 -9
  17. package/template-hono/pnpm-lock.yaml +646 -1173
  18. package/template-hono/server/app.ts +3 -2
  19. package/template-hono/server/controllers/greeting.controller.ts +22 -0
  20. package/template-hono/server/db/index.ts +129 -0
  21. package/template-hono/server/index.ts +3 -3
  22. package/template-hono/server/middlewares/error-handler.ts +8 -0
  23. package/template-hono/server/models/entities/message.entity.ts +13 -0
  24. package/template-hono/server/models/repositories/message.repository.ts +43 -0
  25. package/template-hono/server/models/services/greeting.service.ts +14 -0
  26. package/template-hono/server/models/types/message.ts +7 -0
  27. package/template-hono/server/routes/greeting.ts +1 -1
  28. package/template-hono/shared/constants/greeting.ts +1 -0
  29. package/template-hono/shared/contracts/routes.ts +14 -0
  30. package/template-hono/shared/routes.ts +1 -68
  31. package/template-hono/shared/schema.ts +5 -8
  32. package/template-hono/shared/types/greeting.ts +3 -0
  33. package/template-hono/tailwind.config.mjs +62 -111
  34. package/template-hono/tsconfig.json +3 -2
  35. package/template-hono/tsconfig.server.json +2 -0
  36. package/template-hono/vite.config.ts +4 -4
  37. package/template-hono/client/src/lib/ai-ui-stream.ts +0 -64
  38. package/template-hono/client/src/theme/default-theme.css +0 -482
  39. package/template-hono/drizzle.config.ts +0 -13
  40. package/template-hono/server/controllers/ai-chat-controller.ts +0 -49
  41. package/template-hono/server/controllers/greeting-controller.ts +0 -25
  42. package/template-hono/server/db/client.ts +0 -25
  43. package/template-hono/server/env.ts +0 -89
  44. package/template-hono/server/lib/ai-provider.ts +0 -74
  45. package/template-hono/server/lib/ai.ts +0 -205
  46. package/template-hono/server/middlewares/auth.ts +0 -69
  47. package/template-hono/server/middlewares/index.ts +0 -12
  48. package/template-hono/server/repositories/message-repository.ts +0 -13
  49. package/template-hono/server/routes/ai-chat.ts +0 -9
  50. package/template-hono/shared/schema/greeting.ts +0 -17
@@ -1,6 +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
+ import { registerErrorHandler } from "./middlewares/error-handler";
4
4
  import { greetingRoute } from "./routes/greeting";
5
5
 
6
6
  type CreateAppOptions = {
@@ -10,6 +10,8 @@ type CreateAppOptions = {
10
10
  export function createApp({ serveClient = false }: CreateAppOptions = {}) {
11
11
  const app = new Hono();
12
12
 
13
+ registerErrorHandler(app);
14
+
13
15
  app.get("/__health", (c) => {
14
16
  return c.json({
15
17
  status: "ok",
@@ -20,7 +22,6 @@ export function createApp({ serveClient = false }: CreateAppOptions = {}) {
20
22
  });
21
23
 
22
24
  app.route("/", greetingRoute);
23
- app.route("/", aiChatRoute);
24
25
 
25
26
  if (serveClient) {
26
27
  const serveClientFiles = serveStatic({ root: "./dist/client" });
@@ -0,0 +1,22 @@
1
+ import type { Context } from "hono";
2
+ import { api } from "../../shared/routes";
3
+ import { greetingService } from "../models/services/greeting.service";
4
+
5
+ export async function getGreeting(c: Context) {
6
+ try {
7
+ const body = {
8
+ message: await greetingService.getGreetingMessage(),
9
+ };
10
+
11
+ api.greeting.get.responses[200].parse(body);
12
+
13
+ return c.json(body);
14
+ } catch (error) {
15
+ console.error("GET /api/greeting failed:", error);
16
+
17
+ const message =
18
+ error instanceof Error ? error.message : "Internal Server Error";
19
+
20
+ return c.json({ message }, 500);
21
+ }
22
+ }
@@ -0,0 +1,129 @@
1
+ import "reflect-metadata";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { DataSource, type DataSourceOptions } from "typeorm";
5
+ import { MessageEntity } from "../models/entities/message.entity";
6
+
7
+ declare global {
8
+ var __appDataSource: Promise<DataSource> | undefined;
9
+ var __appDataSourceKey: string | undefined;
10
+ }
11
+
12
+ const DEFAULT_DATABASE_FILE = "./.data/app.db";
13
+
14
+ type DatabaseConfig =
15
+ | {
16
+ type: "sqlite";
17
+ databaseFilePath: string;
18
+ }
19
+ | {
20
+ type: "postgres";
21
+ databaseUrl: string;
22
+ };
23
+
24
+ export class DatabaseConfigurationError extends Error {
25
+ constructor(message: string) {
26
+ super(message);
27
+ this.name = "DatabaseConfigurationError";
28
+ }
29
+ }
30
+
31
+ function resolveDatabaseConfig(): DatabaseConfig {
32
+ const databaseType = process.env.DB_TYPE?.trim().toLowerCase() || "sqlite";
33
+
34
+ if (databaseType === "sqlite") {
35
+ const configuredPath = process.env.DATABASE_FILE?.trim();
36
+ const databaseFilePath = path.resolve(
37
+ process.cwd(),
38
+ configuredPath && configuredPath.length > 0 ? configuredPath : DEFAULT_DATABASE_FILE,
39
+ );
40
+
41
+ fs.mkdirSync(path.dirname(databaseFilePath), { recursive: true });
42
+
43
+ return {
44
+ type: "sqlite",
45
+ databaseFilePath,
46
+ };
47
+ }
48
+
49
+ if (databaseType === "postgres") {
50
+ const databaseUrl = process.env.DATABASE_URL?.trim();
51
+
52
+ if (!databaseUrl) {
53
+ throw new DatabaseConfigurationError(
54
+ "DATABASE_URL 未设置:当 DB_TYPE=postgres 时,请在 .env.local 中配置 Postgres 连接串。",
55
+ );
56
+ }
57
+
58
+ return {
59
+ type: "postgres",
60
+ databaseUrl,
61
+ };
62
+ }
63
+
64
+ throw new DatabaseConfigurationError(
65
+ `无效 DB_TYPE=${JSON.stringify(process.env.DB_TYPE)},仅支持 sqlite 或 postgres。`,
66
+ );
67
+ }
68
+
69
+ const databaseConfig = resolveDatabaseConfig();
70
+ const dataSourceKey =
71
+ databaseConfig.type === "sqlite"
72
+ ? `sqlite:${databaseConfig.databaseFilePath}`
73
+ : `postgres:${databaseConfig.databaseUrl}`;
74
+
75
+ function createDataSourceOptions(): DataSourceOptions {
76
+ const entities = [MessageEntity];
77
+ const baseOptions = {
78
+ entities,
79
+ synchronize: true,
80
+ logging: false,
81
+ };
82
+
83
+ if (databaseConfig.type === "sqlite") {
84
+ return {
85
+ ...baseOptions,
86
+ type: "better-sqlite3",
87
+ database: databaseConfig.databaseFilePath,
88
+ };
89
+ }
90
+
91
+ return {
92
+ ...baseOptions,
93
+ type: "postgres",
94
+ url: databaseConfig.databaseUrl,
95
+ };
96
+ }
97
+
98
+ async function initializeDataSource() {
99
+ const dataSource = new DataSource(createDataSourceOptions());
100
+ return dataSource.initialize();
101
+ }
102
+
103
+ export function getDataSource() {
104
+ if (globalThis.__appDataSourceKey !== dataSourceKey) {
105
+ globalThis.__appDataSource = undefined;
106
+ globalThis.__appDataSourceKey = dataSourceKey;
107
+ }
108
+
109
+ if (!globalThis.__appDataSource) {
110
+ globalThis.__appDataSource = initializeDataSource().catch((error) => {
111
+ globalThis.__appDataSource = undefined;
112
+ throw error;
113
+ });
114
+ }
115
+
116
+ return globalThis.__appDataSource;
117
+ }
118
+
119
+ export function getDatabaseReadHelpMessage() {
120
+ if (databaseConfig.type === "sqlite") {
121
+ const relativePath =
122
+ path.relative(process.cwd(), databaseConfig.databaseFilePath) ||
123
+ path.basename(databaseConfig.databaseFilePath);
124
+
125
+ return `请确认 SQLite 数据库路径可写(${relativePath})。`;
126
+ }
127
+
128
+ return "请确认已设置 DATABASE_URL,并且 Postgres 服务可连接。";
129
+ }
@@ -79,10 +79,10 @@ async function readRuntimeEnvPort() {
79
79
  return null;
80
80
  }
81
81
 
82
- async function resolveRuntimePort(raw: string | null | undefined = process.env.PORT) {
83
- let candidate = raw;
82
+ async function resolveRuntimePort(raw = process.env.PORT) {
83
+ let candidate: string | undefined = raw;
84
84
  if (candidate === undefined || candidate === null || candidate === "") {
85
- candidate = await readRuntimeEnvPort();
85
+ candidate = (await readRuntimeEnvPort()) ?? undefined;
86
86
  }
87
87
 
88
88
  if (candidate === undefined || candidate === null || candidate === "") {
@@ -0,0 +1,8 @@
1
+ import type { Hono } from "hono";
2
+
3
+ export function registerErrorHandler(app: Hono) {
4
+ app.onError((error, c) => {
5
+ console.error("Unhandled request error:", error);
6
+ return c.json({ message: "Internal Server Error" }, 500);
7
+ });
8
+ }
@@ -0,0 +1,13 @@
1
+ import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
2
+
3
+ @Entity({ name: "messages" })
4
+ export class MessageEntity {
5
+ @PrimaryGeneratedColumn()
6
+ id!: number;
7
+
8
+ @Column({ type: "text" })
9
+ content!: string;
10
+
11
+ @Column({ name: "is_read", type: "boolean", default: false })
12
+ isRead!: boolean;
13
+ }
@@ -0,0 +1,43 @@
1
+ import {
2
+ DatabaseConfigurationError,
3
+ getDataSource,
4
+ getDatabaseReadHelpMessage,
5
+ } from "../../db";
6
+ import { MessageEntity } from "../entities/message.entity";
7
+ import type { Message } from "../types/message";
8
+
9
+ export interface MessageRepository {
10
+ findLatestMessage(): Promise<Message | null>;
11
+ }
12
+
13
+ function toMessage(entity: MessageEntity): Message {
14
+ return {
15
+ id: entity.id,
16
+ content: entity.content,
17
+ isRead: entity.isRead,
18
+ };
19
+ }
20
+
21
+ export class DatabaseMessageRepository implements MessageRepository {
22
+ async findLatestMessage(): Promise<Message | null> {
23
+ try {
24
+ const dataSource = await getDataSource();
25
+ const rows = await dataSource.getRepository(MessageEntity).find({
26
+ order: { id: "DESC" },
27
+ take: 1,
28
+ });
29
+
30
+ return rows[0] ? toMessage(rows[0]) : null;
31
+ } catch (error) {
32
+ console.error("DatabaseMessageRepository.findLatestMessage() failed:", error);
33
+
34
+ if (error instanceof DatabaseConfigurationError) {
35
+ throw error;
36
+ }
37
+
38
+ throw new Error(`数据库读取失败:${getDatabaseReadHelpMessage()}`);
39
+ }
40
+ }
41
+ }
42
+
43
+ export const messageRepository = new DatabaseMessageRepository();
@@ -0,0 +1,14 @@
1
+ import { messageRepository, type MessageRepository } from "../repositories/message.repository";
2
+
3
+ const DEFAULT_GREETING_MESSAGE = "Hello from the Backend API!";
4
+
5
+ export class GreetingService {
6
+ constructor(private readonly messageRepository: MessageRepository) {}
7
+
8
+ async getGreetingMessage(): Promise<string> {
9
+ const latestMessage = await this.messageRepository.findLatestMessage();
10
+ return latestMessage?.content ?? DEFAULT_GREETING_MESSAGE;
11
+ }
12
+ }
13
+
14
+ export const greetingService = new GreetingService(messageRepository);
@@ -0,0 +1,7 @@
1
+ export interface Message {
2
+ id: number;
3
+ content: string;
4
+ isRead: boolean;
5
+ }
6
+
7
+ export type InsertMessage = Pick<Message, "content" | "isRead">;
@@ -1,6 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import { api } from "../../shared/routes";
3
- import { getGreeting } from "../controllers/greeting-controller";
3
+ import { getGreeting } from "../controllers/greeting.controller";
4
4
 
5
5
  const greetingRoute = new Hono();
6
6
 
@@ -0,0 +1 @@
1
+ export const GREETING_ROUTE_PATH = "/api/greeting";
@@ -0,0 +1,14 @@
1
+ import { GREETING_ROUTE_PATH } from "../constants/greeting";
2
+ import { GreetingResponseSchema } from "../schema";
3
+
4
+ export const api = {
5
+ greeting: {
6
+ get: {
7
+ method: "GET",
8
+ path: GREETING_ROUTE_PATH,
9
+ responses: {
10
+ 200: GreetingResponseSchema,
11
+ },
12
+ },
13
+ },
14
+ } as const;
@@ -1,68 +1 @@
1
- import { z } from "zod";
2
-
3
- const aiTextPartSchema = z.object({
4
- type: z.literal("text"),
5
- text: z.string().min(1),
6
- });
7
-
8
- const aiFilePartSchema = z.object({
9
- type: z.literal("file"),
10
- filename: z.string().min(1).optional(),
11
- mediaType: z.string().min(1),
12
- url: z.string().min(1),
13
- });
14
-
15
- const aiMessagePartSchema = z.discriminatedUnion("type", [
16
- aiTextPartSchema,
17
- aiFilePartSchema,
18
- ]);
19
-
20
- const aiMessageSchema = z.object({
21
- id: z.string().min(1).optional(),
22
- role: z.enum(["system", "user", "assistant"]),
23
- parts: z.array(aiMessagePartSchema).min(1),
24
- });
25
-
26
- export const aiChatRequestSchema = z.object({
27
- messages: z.array(aiMessageSchema).min(1),
28
- });
29
-
30
- export const aiErrorResponseSchema = z.object({
31
- error: z.object({
32
- code: z.string(),
33
- message: z.string(),
34
- }),
35
- });
36
-
37
- export const api = {
38
- greeting: {
39
- get: {
40
- method: "GET",
41
- path: "/api/greeting",
42
- responses: {
43
- 200: z.object({ message: z.string() }),
44
- },
45
- },
46
- },
47
- ai: {
48
- chat: {
49
- post: {
50
- method: "POST",
51
- path: "/api/ai/chat",
52
- request: {
53
- body: aiChatRequestSchema,
54
- },
55
- responses: {
56
- 400: aiErrorResponseSchema,
57
- 500: aiErrorResponseSchema,
58
- },
59
- },
60
- },
61
- },
62
- };
63
-
64
- export type AITextPart = z.infer<typeof aiTextPartSchema>;
65
- export type AIFilePart = z.infer<typeof aiFilePartSchema>;
66
- export type AIMessagePart = z.infer<typeof aiMessagePartSchema>;
67
- export type AIMessage = z.infer<typeof aiMessageSchema>;
68
- export type AIChatRequest = z.infer<typeof aiChatRequestSchema>;
1
+ export { api } from "./contracts/routes";
@@ -1,9 +1,6 @@
1
- export {
2
- insertMessageSchema,
3
- messages,
4
- } from "./schema/greeting";
1
+ import { z } from "zod";
2
+ import type { GreetingResponse } from "./types/greeting";
5
3
 
6
- export type {
7
- InsertMessage,
8
- Message,
9
- } from "./schema/greeting";
4
+ export const GreetingResponseSchema: z.ZodType<GreetingResponse> = z.object({
5
+ message: z.string(),
6
+ });
@@ -0,0 +1,3 @@
1
+ export interface GreetingResponse {
2
+ message: string;
3
+ }
@@ -1,114 +1,5 @@
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
-
112
3
  /** @type {import("tailwindcss").Config} */
113
4
  const config = {
114
5
  darkMode: ["class"],
@@ -119,8 +10,68 @@ const config = {
119
10
  ],
120
11
  theme: {
121
12
  extend: {
122
- borderRadius: themeBorderRadius,
123
- colors: themeColors,
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
+ },
124
75
  keyframes: {
125
76
  "accordion-down": {
126
77
  from: { height: "0" },
@@ -7,6 +7,8 @@
7
7
  "strict": true,
8
8
  "noEmit": true,
9
9
  "esModuleInterop": true,
10
+ "experimentalDecorators": true,
11
+ "emitDecoratorMetadata": true,
10
12
  "module": "esnext",
11
13
  "moduleResolution": "bundler",
12
14
  "resolveJsonModule": true,
@@ -26,8 +28,7 @@
26
28
  "shared/**/*.tsx",
27
29
  "server/**/*.ts",
28
30
  "types/**/*.d.ts",
29
- "vite.config.ts",
30
- "drizzle.config.ts"
31
+ "vite.config.ts"
31
32
  ],
32
33
  "exclude": ["node_modules", "dist"]
33
34
  }
@@ -5,6 +5,8 @@
5
5
  "moduleResolution": "Node",
6
6
  "strict": true,
7
7
  "esModuleInterop": true,
8
+ "experimentalDecorators": true,
9
+ "emitDecoratorMetadata": true,
8
10
  "skipLibCheck": true,
9
11
  "outDir": "dist",
10
12
  "rootDir": ".",
@@ -50,10 +50,10 @@ async function readRuntimeEnvPort() {
50
50
  return null;
51
51
  }
52
52
 
53
- async function resolveRuntimePort(raw: string | null | undefined = process.env.PORT) {
54
- let candidate = raw;
53
+ async function resolveRuntimePort(raw = process.env.PORT) {
54
+ let candidate: string | undefined = raw;
55
55
  if (candidate === undefined || candidate === null || candidate === "") {
56
- candidate = await readRuntimeEnvPort();
56
+ candidate = (await readRuntimeEnvPort()) ?? undefined;
57
57
  }
58
58
 
59
59
  if (candidate === undefined || candidate === null || candidate === "") {
@@ -126,7 +126,7 @@ export default defineConfig(async ({ command }) => {
126
126
  : {
127
127
  host: "0.0.0.0",
128
128
  port: runtimePort,
129
- allowedHosts: ["localhost", "127.0.0.1", ".preview.imagicma.cn", ".preview.agentma.cn", ".preview.agentma.com", ".preview.nanocoda.com"],
129
+ allowedHosts: ["localhost", "127.0.0.1", ".preview.imagicma.cn", ".preview.agentma.cn", ".preview.agentma.com"],
130
130
  strictPort: true,
131
131
  hmr: { overlay: false },
132
132
  },