@coze-arch/cli 0.0.1-alpha.c53937 → 0.0.1-alpha.cac8f5

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 (77) hide show
  1. package/lib/__templates__/expo/.coze +3 -3
  2. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +46 -0
  3. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +220 -0
  4. package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +2 -2
  5. package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +3 -4
  6. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +45 -0
  7. package/lib/__templates__/expo/README.md +68 -7
  8. package/lib/__templates__/expo/_gitignore +1 -1
  9. package/lib/__templates__/expo/_npmrc +2 -4
  10. package/lib/__templates__/expo/client/app/_layout.tsx +14 -14
  11. package/lib/__templates__/expo/client/app/index.tsx +1 -0
  12. package/lib/__templates__/expo/client/app.config.ts +76 -0
  13. package/lib/__templates__/expo/client/components/ThemedText.tsx +33 -0
  14. package/lib/__templates__/expo/client/components/ThemedView.tsx +38 -0
  15. package/lib/__templates__/expo/client/constants/theme.ts +109 -68
  16. package/lib/__templates__/expo/client/declarations.d.ts +5 -0
  17. package/lib/__templates__/expo/{eslint.config.mjs → client/eslint.config.mjs} +14 -10
  18. package/lib/__templates__/expo/client/hooks/useColorScheme.ts +34 -1
  19. package/lib/__templates__/expo/client/hooks/useTheme.ts +26 -6
  20. package/lib/__templates__/expo/client/metro.config.js +121 -0
  21. package/lib/__templates__/expo/client/package.json +93 -0
  22. package/lib/__templates__/expo/client/screens/demo/index.tsx +25 -0
  23. package/lib/__templates__/expo/client/screens/demo/styles.ts +28 -0
  24. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +1 -0
  25. package/lib/__templates__/expo/client/tsconfig.json +24 -0
  26. package/lib/__templates__/expo/client/utils/index.ts +22 -0
  27. package/lib/__templates__/expo/eslint-plugins/fontawesome6/index.js +9 -0
  28. package/lib/__templates__/expo/eslint-plugins/fontawesome6/names.js +2486 -0
  29. package/lib/__templates__/expo/eslint-plugins/fontawesome6/rule.js +155 -0
  30. package/lib/__templates__/expo/package.json +8 -107
  31. package/lib/__templates__/expo/pnpm-lock.yaml +451 -867
  32. package/lib/__templates__/expo/pnpm-workspace.yaml +3 -0
  33. package/lib/__templates__/expo/server/build.js +21 -0
  34. package/lib/__templates__/expo/server/package.json +32 -0
  35. package/lib/__templates__/expo/server/src/index.ts +19 -0
  36. package/lib/__templates__/expo/server/tsconfig.json +24 -0
  37. package/lib/__templates__/expo/template.config.js +1 -0
  38. package/lib/__templates__/expo/tsconfig.json +1 -24
  39. package/lib/__templates__/nextjs/.coze +1 -0
  40. package/lib/__templates__/nextjs/_npmrc +1 -0
  41. package/lib/__templates__/nextjs/next.config.ts +12 -0
  42. package/lib/__templates__/nextjs/package.json +8 -2
  43. package/lib/__templates__/nextjs/pnpm-lock.yaml +1465 -1706
  44. package/lib/__templates__/nextjs/scripts/prepare.sh +9 -0
  45. package/lib/__templates__/nextjs/src/app/globals.css +109 -89
  46. package/lib/__templates__/nextjs/src/app/layout.tsx +1 -12
  47. package/lib/__templates__/nextjs/src/app/page.tsx +35 -23
  48. package/lib/__templates__/nextjs/src/components/ui/resizable.tsx +29 -22
  49. package/lib/__templates__/nextjs/src/components/ui/sidebar.tsx +228 -230
  50. package/lib/__templates__/nextjs/template.config.js +30 -0
  51. package/lib/__templates__/templates.json +61 -43
  52. package/lib/__templates__/vite/.coze +1 -0
  53. package/lib/__templates__/vite/_npmrc +1 -0
  54. package/lib/__templates__/vite/eslint.config.mjs +9 -0
  55. package/lib/__templates__/vite/package.json +10 -1
  56. package/lib/__templates__/vite/pnpm-lock.yaml +3115 -126
  57. package/lib/__templates__/vite/scripts/prepare.sh +9 -0
  58. package/lib/__templates__/vite/src/main.ts +1 -2
  59. package/lib/__templates__/vite/template.config.js +30 -4
  60. package/lib/cli.js +201 -57
  61. package/package.json +8 -3
  62. package/lib/__templates__/expo/.cozeproj/scripts/deploy_build.sh +0 -109
  63. package/lib/__templates__/expo/.cozeproj/scripts/deploy_run.sh +0 -235
  64. package/lib/__templates__/expo/app.json +0 -63
  65. package/lib/__templates__/expo/babel.config.js +0 -19
  66. package/lib/__templates__/expo/client/app/(tabs)/_layout.tsx +0 -43
  67. package/lib/__templates__/expo/client/app/(tabs)/home.tsx +0 -1
  68. package/lib/__templates__/expo/client/app/(tabs)/index.tsx +0 -7
  69. package/lib/__templates__/expo/client/app/+not-found.tsx +0 -79
  70. package/lib/__templates__/expo/client/index.js +0 -12
  71. package/lib/__templates__/expo/client/screens/home/index.tsx +0 -51
  72. package/lib/__templates__/expo/client/screens/home/styles.ts +0 -60
  73. package/lib/__templates__/expo/metro.config.js +0 -51
  74. package/lib/__templates__/expo/src/index.ts +0 -12
  75. package/lib/__templates__/nextjs/.vscode/settings.json +0 -121
  76. package/lib/__templates__/vite/.vscode/settings.json +0 -7
  77. /package/lib/__templates__/expo/{eslint-formatter-simple.mjs → client/eslint-formatter-simple.mjs} +0 -0
@@ -1,40 +1,35 @@
1
- import { Platform } from "react-native";
2
-
3
- const tintColorLight = "#007AFF";
4
- const tintColorDark = "#0A84FF";
5
-
6
1
  export const Colors = {
7
2
  light: {
8
- text: "#11181C",
9
- textPrimary: "#11181C",
10
- textSecondary: "#687076",
11
- textMuted: "#9BA1A6",
12
- buttonText: "#FFFFFF",
13
- tabIconDefault: "#687076",
14
- tabIconSelected: tintColorLight,
15
- primary: tintColorLight,
16
- link: "#007AFF",
17
- backgroundRoot: "#FFFFFF", // Elevation 0
18
- backgroundDefault: "#F2F2F2", // Elevation 1
19
- backgroundSecondary: "#E6E6E6", // Elevation 2
20
- backgroundTertiary: "#D9D9D9", // Elevation 3
21
- border: "#E6E6E6",
3
+ textPrimary: "#1C1917",
4
+ textSecondary: "#78716c",
5
+ textMuted: "#9CA3AF",
6
+ primary: "#4F46E5", // Indigo-600 - 品牌主色,代表科技与智能
7
+ accent: "#8B5CF6", // Violet-500 - 辅助色,代表创造力
8
+ success: "#10B981", // Emerald-500
9
+ error: "#EF4444",
10
+ backgroundRoot: "#FAFAFA",
11
+ backgroundDefault: "#FFFFFF",
12
+ backgroundTertiary: "#F9FAFB", // 更浅的背景色,用于去线留白
13
+ buttonPrimaryText: "#FFFFFF",
14
+ tabIconSelected: "#4F46E5",
15
+ border: "#E5E7EB",
16
+ borderLight: "#F3F4F6",
22
17
  },
23
18
  dark: {
24
- text: "#ECEDEE",
25
- textPrimary: "#ECEDEE",
26
- textSecondary: "#9BA1A6",
19
+ textPrimary: "#FAFAF9",
20
+ textSecondary: "#A8A29E",
27
21
  textMuted: "#6F767E",
28
- buttonText: "#FFFFFF",
29
- tabIconDefault: "#9BA1A6",
30
- tabIconSelected: tintColorDark,
31
- primary: tintColorDark,
32
- link: "#0A84FF",
33
- backgroundRoot: "#1F2123", // Elevation 0
34
- backgroundDefault: "#2A2C2E", // Elevation 1
35
- backgroundSecondary: "#353739", // Elevation 2
36
- backgroundTertiary: "#404244", // Elevation 3
37
- border: "#353739",
22
+ primary: "#818CF8", // Indigo-400 - 暗色模式品牌主色
23
+ accent: "#A78BFA", // Violet-400
24
+ success: "#34D399",
25
+ error: "#F87171",
26
+ backgroundRoot: "#09090B", // 更深的背景色
27
+ backgroundDefault: "#1C1C1E",
28
+ backgroundTertiary: "#1F1F22", // 暗色模式去线留白背景
29
+ buttonPrimaryText: "#09090B",
30
+ tabIconSelected: "#818CF8",
31
+ border: "#3F3F46",
32
+ borderLight: "#27272A",
38
33
  },
39
34
  };
40
35
 
@@ -48,22 +43,31 @@ export const Spacing = {
48
43
  "3xl": 32,
49
44
  "4xl": 40,
50
45
  "5xl": 48,
51
- inputHeight: 48,
52
- buttonHeight: 52,
46
+ "6xl": 64,
53
47
  };
54
48
 
55
49
  export const BorderRadius = {
56
- xs: 8,
57
- sm: 12,
58
- md: 18,
59
- lg: 24,
60
- xl: 30,
61
- "2xl": 40,
62
- "3xl": 50,
63
- full: 9999,
50
+ lg: 16,
64
51
  };
65
52
 
66
53
  export const Typography = {
54
+ display: {
55
+ fontSize: 112,
56
+ lineHeight: 112,
57
+ fontWeight: "200" as const,
58
+ letterSpacing: -4,
59
+ },
60
+ displayLarge: {
61
+ fontSize: 112,
62
+ lineHeight: 112,
63
+ fontWeight: "200" as const,
64
+ letterSpacing: -2,
65
+ },
66
+ displayMedium: {
67
+ fontSize: 48,
68
+ lineHeight: 56,
69
+ fontWeight: "200" as const,
70
+ },
67
71
  h1: {
68
72
  fontSize: 32,
69
73
  lineHeight: 40,
@@ -77,52 +81,89 @@ export const Typography = {
77
81
  h3: {
78
82
  fontSize: 24,
79
83
  lineHeight: 32,
80
- fontWeight: "600" as const,
84
+ fontWeight: "300" as const,
81
85
  },
82
86
  h4: {
83
87
  fontSize: 20,
84
88
  lineHeight: 28,
85
89
  fontWeight: "600" as const,
86
90
  },
91
+ title: {
92
+ fontSize: 18,
93
+ lineHeight: 24,
94
+ fontWeight: "700" as const,
95
+ },
87
96
  body: {
88
97
  fontSize: 16,
89
98
  lineHeight: 24,
90
99
  fontWeight: "400" as const,
91
100
  },
101
+ bodyMedium: {
102
+ fontSize: 16,
103
+ lineHeight: 24,
104
+ fontWeight: "500" as const,
105
+ },
92
106
  small: {
93
107
  fontSize: 14,
94
108
  lineHeight: 20,
95
109
  fontWeight: "400" as const,
96
110
  },
111
+ smallMedium: {
112
+ fontSize: 14,
113
+ lineHeight: 20,
114
+ fontWeight: "500" as const,
115
+ },
116
+ caption: {
117
+ fontSize: 12,
118
+ lineHeight: 16,
119
+ fontWeight: "400" as const,
120
+ },
121
+ captionMedium: {
122
+ fontSize: 12,
123
+ lineHeight: 16,
124
+ fontWeight: "500" as const,
125
+ },
126
+ label: {
127
+ fontSize: 14,
128
+ lineHeight: 20,
129
+ fontWeight: "500" as const,
130
+ letterSpacing: 2,
131
+ textTransform: "uppercase" as const,
132
+ },
133
+ labelSmall: {
134
+ fontSize: 12,
135
+ lineHeight: 16,
136
+ fontWeight: "500" as const,
137
+ letterSpacing: 1,
138
+ textTransform: "uppercase" as const,
139
+ },
140
+ labelTitle: {
141
+ fontSize: 14,
142
+ lineHeight: 20,
143
+ fontWeight: "700" as const,
144
+ letterSpacing: 2,
145
+ textTransform: "uppercase" as const,
146
+ },
97
147
  link: {
98
148
  fontSize: 16,
99
149
  lineHeight: 24,
100
150
  fontWeight: "400" as const,
101
151
  },
152
+ stat: {
153
+ fontSize: 30,
154
+ lineHeight: 36,
155
+ fontWeight: "300" as const,
156
+ },
157
+ tiny: {
158
+ fontSize: 10,
159
+ lineHeight: 14,
160
+ fontWeight: "400" as const,
161
+ },
162
+ navLabel: {
163
+ fontSize: 10,
164
+ lineHeight: 14,
165
+ fontWeight: "500" as const,
166
+ },
102
167
  };
103
168
 
104
- export const Fonts = Platform.select({
105
- ios: {
106
- /** iOS `UIFontDescriptorSystemDesignDefault` */
107
- sans: "system-ui",
108
- /** iOS `UIFontDescriptorSystemDesignSerif` */
109
- serif: "ui-serif",
110
- /** iOS `UIFontDescriptorSystemDesignRounded` */
111
- rounded: "ui-rounded",
112
- /** iOS `UIFontDescriptorSystemDesignMonospaced` */
113
- mono: "ui-monospace",
114
- },
115
- default: {
116
- sans: "normal",
117
- serif: "serif",
118
- rounded: "normal",
119
- mono: "monospace",
120
- },
121
- web: {
122
- sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
123
- serif: "Georgia, 'Times New Roman', serif",
124
- rounded:
125
- "'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif",
126
- mono: "SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
127
- },
128
- });
169
+ export type Theme = typeof Colors.light;
@@ -0,0 +1,5 @@
1
+ // declarations.d.ts
2
+
3
+ declare module 'expo-file-system/legacy' {
4
+ export * from 'expo-file-system';
5
+ }
@@ -1,10 +1,11 @@
1
- import js from "@eslint/js";
2
- import globals from "globals";
3
- import tseslint from "typescript-eslint";
4
- import pluginReact from "eslint-plugin-react";
5
- import reactHooks from "eslint-plugin-react-hooks";
6
- import regexp from "eslint-plugin-regexp";
7
- import pluginImport from "eslint-plugin-import";
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import tseslint from 'typescript-eslint';
4
+ import pluginReact from 'eslint-plugin-react';
5
+ import reactHooks from 'eslint-plugin-react-hooks';
6
+ import regexp from 'eslint-plugin-regexp';
7
+ import pluginImport from 'eslint-plugin-import';
8
+ import fontawesome6 from '../eslint-plugins/fontawesome6/index.js';
8
9
 
9
10
  export default [
10
11
  {
@@ -15,19 +16,20 @@ export default [
15
16
  'src/api/**', // 排除 src 下的自动生成 API
16
17
  '.expo/**', // 排除 Expo 自动生成的文件
17
18
  'tailwind.config.js', // 排除 Tailwind 配置文件
19
+ '**/*.d.ts',
18
20
  ],
19
21
  },
20
22
  regexp.configs["flat/recommended"],
21
23
  js.configs.recommended,
22
24
  ...tseslint.configs.recommended,
23
-
25
+
24
26
  // React 的推荐配置
25
27
  pluginReact.configs.flat.recommended,
26
28
  pluginReact.configs.flat['jsx-runtime'],
27
29
  reactHooks.configs.flat.recommended,
28
30
  {
29
31
  files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
30
-
32
+
31
33
  // 语言选项:设置全局变量
32
34
  languageOptions: {
33
35
  globals: {
@@ -52,6 +54,7 @@ export default [
52
54
 
53
55
  plugins: {
54
56
  import: pluginImport,
57
+ fontawesome6,
55
58
  },
56
59
  rules: {
57
60
  // 关闭代码风格规则
@@ -70,6 +73,7 @@ export default [
70
73
  'no-prototype-builtins': 'off',
71
74
  'react/react-in-jsx-scope': 'off',
72
75
  'react/jsx-uses-react': 'off',
76
+ 'fontawesome6/valid-name': 'error',
73
77
  },
74
78
  },
75
79
 
@@ -91,7 +95,7 @@ export default [
91
95
  // 在 .js 文件中关闭 TS 规则
92
96
  '@typescript-eslint/no-require-imports': 'off',
93
97
  // 在 Node.js 文件中允许 require
94
- '@typescript-eslint/no-var-requires': 'off',
98
+ '@typescript-eslint/no-var-requires': 'off',
95
99
  'no-undef': 'off',
96
100
  },
97
101
  },
@@ -1 +1,34 @@
1
- export { useColorScheme } from "react-native";
1
+ import { useEffect, useState } from 'react';
2
+ import { ColorSchemeName, useColorScheme as useReactNativeColorScheme, Platform } from 'react-native';
3
+
4
+ export function useColorScheme() {
5
+ const systemColorScheme = useReactNativeColorScheme();
6
+ const [colorScheme, setColorScheme] = useState<ColorSchemeName>(systemColorScheme);
7
+
8
+ useEffect(() => {
9
+ setColorScheme(systemColorScheme);
10
+ }, [systemColorScheme])
11
+
12
+ useEffect(() => {
13
+ function handleMessage(e: MessageEvent<{ event: string; colorScheme: ColorSchemeName; } | undefined>) {
14
+ if (e.data?.event === 'coze.workbench.colorScheme') {
15
+ const cs = e.data.colorScheme;
16
+ if (typeof cs === 'string') {
17
+ setColorScheme(cs);
18
+ }
19
+ }
20
+ }
21
+
22
+ if (Platform.OS === 'web') {
23
+ window.addEventListener('message', handleMessage, false);
24
+ }
25
+
26
+ return () => {
27
+ if (Platform.OS === 'web') {
28
+ window.removeEventListener('message', handleMessage, false);
29
+ }
30
+ }
31
+ }, []);
32
+
33
+ return colorScheme;
34
+ }
@@ -1,13 +1,33 @@
1
- import { Colors } from "@/constants/theme";
2
- import { useColorScheme } from "@/hooks/useColorScheme";
1
+ import { Colors } from '@/constants/theme';
2
+ import { useColorScheme } from '@/hooks/useColorScheme';
3
3
 
4
- export function useTheme() {
5
- const colorScheme = useColorScheme();
6
- const isDark = colorScheme === "dark";
7
- const theme = Colors[(colorScheme as "light" | "dark") ?? "light"];
4
+ enum COLOR_SCHEME_CHOICE {
5
+ FOLLOW_SYSTEM = 'follow-system', // 跟随系统自动变化
6
+ DARK = 'dark', // 固定为 dark 主题,不随系统变化
7
+ LIGHT = 'light', // 固定为 light 主题,不随系统变化
8
+ };
9
+
10
+ const userPreferColorScheme: COLOR_SCHEME_CHOICE = COLOR_SCHEME_CHOICE.FOLLOW_SYSTEM;
11
+
12
+ function getTheme(colorScheme?: 'dark' | 'light' | null) {
13
+ const isDark = colorScheme === 'dark';
14
+ const theme = Colors[colorScheme ?? 'light'];
8
15
 
9
16
  return {
10
17
  theme,
11
18
  isDark,
12
19
  };
13
20
  }
21
+
22
+ function useTheme() {
23
+ const systemColorScheme = useColorScheme()
24
+ const colorScheme = userPreferColorScheme === COLOR_SCHEME_CHOICE.FOLLOW_SYSTEM ?
25
+ systemColorScheme :
26
+ userPreferColorScheme;
27
+
28
+ return getTheme(colorScheme);
29
+ }
30
+
31
+ export {
32
+ useTheme,
33
+ }
@@ -0,0 +1,121 @@
1
+ const { getDefaultConfig } = require('expo/metro-config');
2
+ const { createProxyMiddleware } = require('http-proxy-middleware');
3
+ const connect = require('connect');
4
+
5
+ const config = getDefaultConfig(__dirname);
6
+
7
+ // 安全地获取 Expo 的默认排除列表
8
+ const existingBlockList = [].concat(config.resolver.blockList || []);
9
+
10
+ config.resolver.blockList = [
11
+ ...existingBlockList,
12
+ /.*\/\.expo\/.*/, // Expo 的缓存和构建产物目录
13
+
14
+ // 1. 原生代码 (Java/C++/Objective-C)
15
+ /.*\/react-native\/ReactAndroid\/.*/,
16
+ /.*\/react-native\/ReactCommon\/.*/,
17
+
18
+ // 2. 纯开发和调试工具
19
+ // 这些工具只在开发电脑上运行,不会被打包到应用中
20
+ /.*\/@typescript-eslint\/eslint-plugin\/.*/,
21
+
22
+ // 3. 构建时数据
23
+ // 这个数据库只在打包过程中使用,应用运行时不需要
24
+ /.*\/caniuse-lite\/data\/.*/,
25
+
26
+ // 4. 通用规则
27
+ /.*\/__tests__\/.*/, // 排除所有测试目录
28
+ /.*\.git\/.*/, // 排除 Git 目录
29
+ ];
30
+
31
+ const BACKEND_TARGET = 'http://localhost:9091';
32
+
33
+ const apiProxy = createProxyMiddleware({
34
+ target: BACKEND_TARGET,
35
+ changeOrigin: true,
36
+ logLevel: 'debug',
37
+ proxyTimeout: 86400000,
38
+ onProxyReq: (proxyReq, req) => {
39
+ const accept = req.headers.accept || '';
40
+ if (accept.includes('text/event-stream')) {
41
+ proxyReq.setHeader('accept-encoding', 'identity');
42
+ }
43
+ },
44
+ onProxyRes: (proxyRes, req, res) => {
45
+ const contentType = proxyRes.headers['content-type'] || '';
46
+ if (contentType.includes('text/event-stream') || contentType.includes('application/stream')) {
47
+ res.setHeader('Cache-Control', 'no-cache');
48
+ res.setHeader('Connection', 'keep-alive');
49
+ res.setHeader('X-Accel-Buffering', 'no');
50
+ if (typeof res.flushHeaders === 'function') {
51
+ try { res.flushHeaders(); } catch {}
52
+ }
53
+ }
54
+ },
55
+ });
56
+
57
+ const streamProxy = createProxyMiddleware({
58
+ target: BACKEND_TARGET,
59
+ changeOrigin: true,
60
+ logLevel: 'debug',
61
+ ws: true,
62
+ proxyTimeout: 86400000,
63
+ onProxyReq: (proxyReq, req) => {
64
+ const upgrade = req.headers.upgrade;
65
+ const accept = req.headers.accept || '';
66
+ if (upgrade && upgrade.toLowerCase() === 'websocket') {
67
+ proxyReq.setHeader('Connection', 'upgrade');
68
+ proxyReq.setHeader('Upgrade', req.headers.upgrade);
69
+ } else if (accept.includes('text/event-stream')) {
70
+ proxyReq.setHeader('accept-encoding', 'identity');
71
+ proxyReq.setHeader('Connection', 'keep-alive');
72
+ }
73
+ },
74
+ onProxyRes: (proxyRes, req, res) => {
75
+ const contentType = proxyRes.headers['content-type'] || '';
76
+ if (contentType.includes('text/event-stream') || contentType.includes('application/stream')) {
77
+ res.setHeader('Cache-Control', 'no-cache');
78
+ res.setHeader('Connection', 'keep-alive');
79
+ res.setHeader('X-Accel-Buffering', 'no');
80
+ if (typeof res.flushHeaders === 'function') {
81
+ try { res.flushHeaders(); } catch {}
82
+ }
83
+ }
84
+ },
85
+ });
86
+
87
+ const shouldProxyToBackend = (url) => {
88
+ if (!url) return false;
89
+ if (/^\/api\/v\d+\//.test(url)) {
90
+ return true;
91
+ }
92
+ return false;
93
+ };
94
+
95
+ const isWebSocketRequest = (req) =>
96
+ !!(req.headers.upgrade && req.headers.upgrade.toLowerCase() === 'websocket');
97
+ const isSSERequest = (req) => {
98
+ const accept = req.headers.accept || '';
99
+ return accept.includes('text/event-stream');
100
+ };
101
+
102
+ config.server = {
103
+ ...config.server,
104
+ enhanceMiddleware: (metroMiddleware, metroServer) => {
105
+ return connect()
106
+ .use((req, res, next) => {
107
+ if (shouldProxyToBackend(req.url)) {
108
+ console.log(`[Metro Proxy] Forwarding ${req.method} ${req.url}`);
109
+
110
+ if (isWebSocketRequest(req) || isSSERequest(req)) {
111
+ return streamProxy(req, res, next);
112
+ }
113
+ return apiProxy(req, res, next);
114
+ }
115
+ next();
116
+ })
117
+ .use(metroMiddleware);
118
+ },
119
+ };
120
+
121
+ module.exports = config;
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "expo-app",
3
+ "description": "<%= appName %>",
4
+ "main": "expo-router/entry",
5
+ "private": true,
6
+ "scripts": {
7
+ "check-deps": "npx depcheck",
8
+ "postinstall": "npm run install-missing",
9
+ "install-missing": "node ./scripts/install-missing-deps.js",
10
+ "lint": "expo lint",
11
+ "start": "expo start --web --clear",
12
+ "test": "jest --watchAll"
13
+ },
14
+ "jest": {
15
+ "preset": "jest-expo"
16
+ },
17
+ "dependencies": {
18
+ "@expo/metro-runtime": "^6.1.2",
19
+ "@expo/vector-icons": "^15.0.0",
20
+ "@react-native-async-storage/async-storage": "^2.2.0",
21
+ "@react-native-community/datetimepicker": "^8.5.0",
22
+ "@react-native-community/slider": "^5.0.1",
23
+ "@react-native-masked-view/masked-view": "^0.3.2",
24
+ "@react-native-picker/picker": "^2.11.0",
25
+ "@react-navigation/bottom-tabs": "^7.2.0",
26
+ "@react-navigation/native": "^7.0.14",
27
+ "dayjs": "^1.11.19",
28
+ "expo": "^54.0.7",
29
+ "expo-auth-session": "^7.0.9",
30
+ "expo-av": "~16.0.6",
31
+ "expo-blur": "~15.0.6",
32
+ "expo-camera": "~17.0.10",
33
+ "expo-constants": "~18.0.8",
34
+ "expo-crypto": "^15.0.7",
35
+ "expo-font": "~14.0.7",
36
+ "expo-haptics": "~15.0.6",
37
+ "expo-image-picker": "~17.0.7",
38
+ "expo-linear-gradient": "~15.0.6",
39
+ "expo-linking": "~8.0.7",
40
+ "expo-location": "~19.0.7",
41
+ "expo-image": "^3.0.11",
42
+ "expo-router": "~6.0.0",
43
+ "expo-splash-screen": "~31.0.8",
44
+ "expo-status-bar": "~3.0.7",
45
+ "expo-symbols": "~1.0.6",
46
+ "expo-system-ui": "~6.0.9",
47
+ "expo-web-browser": "~15.0.10",
48
+ "react": "19.1.0",
49
+ "react-dom": "19.1.0",
50
+ "react-native": "0.81.5",
51
+ "react-native-chart-kit": "^6.12.0",
52
+ "react-native-gesture-handler": "~2.28.0",
53
+ "react-native-keyboard-aware-scroll-view": "^0.9.5",
54
+ "react-native-modal-datetime-picker": "18.0.0",
55
+ "react-native-reanimated": "~4.1.0",
56
+ "react-native-safe-area-context": "~5.6.0",
57
+ "react-native-screens": "~4.16.0",
58
+ "react-native-svg": "15.15.0",
59
+ "react-native-toast-message": "^2.3.3",
60
+ "react-native-web": "^0.21.2",
61
+ "react-native-webview": "~13.15.0",
62
+ "react-native-worklets": "0.5.1",
63
+ "zod": "^4.2.1"
64
+ },
65
+ "devDependencies": {
66
+ "@babel/core": "^7.25.2",
67
+ "babel-plugin-module-resolver": "^5.0.2",
68
+ "babel-preset-expo": "^54.0.9",
69
+ "@eslint/js": "^9.27.0",
70
+ "@types/jest": "^29.5.12",
71
+ "@types/react": "~19.1.0",
72
+ "@types/react-test-renderer": "19.1.0",
73
+ "chalk": "^4.1.2",
74
+ "depcheck": "^1.4.7",
75
+ "esbuild": "0.27.2",
76
+ "eslint": "^9.39.2",
77
+ "eslint-formatter-compact": "^9.0.1",
78
+ "eslint-import-resolver-typescript": "^4.4.4",
79
+ "eslint-plugin-import": "^2.32.0",
80
+ "eslint-plugin-react": "^7.37.5",
81
+ "eslint-plugin-react-hooks": "^7.0.1",
82
+ "eslint-plugin-regexp": "^2.10.0",
83
+ "globals": "^16.1.0",
84
+ "jest": "^29.2.1",
85
+ "jest-expo": "~54.0.10",
86
+ "react-test-renderer": "19.1.0",
87
+ "tsx": "^4.21.0",
88
+ "typescript": "^5.8.3",
89
+ "typescript-eslint": "^8.32.1",
90
+ "connect": "^3.7.0",
91
+ "http-proxy-middleware": "^3.0.5"
92
+ }
93
+ }
@@ -0,0 +1,25 @@
1
+ import { View, Text } from 'react-native';
2
+ import { Image } from 'expo-image';
3
+
4
+ import { useTheme } from '@/hooks/useTheme';
5
+ import { Screen } from '@/components/Screen';
6
+ import { styles } from './styles';
7
+
8
+ export default function DemoPage() {
9
+ const { theme, isDark } = useTheme();
10
+
11
+ return (
12
+ <Screen backgroundColor={theme.backgroundRoot} statusBarStyle={isDark ? 'light' : 'dark'}>
13
+ <View
14
+ style={styles.container}
15
+ >
16
+ <Image
17
+ style={styles.logo}
18
+ source="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-coding/expo/coze-loading.gif"
19
+ ></Image>
20
+ <Text style={{...styles.title, color: theme.textPrimary}}>APP 开发中</Text>
21
+ <Text style={{...styles.description, color: theme.textSecondary}}>即将为您呈现应用界面</Text>
22
+ </View>
23
+ </Screen>
24
+ );
25
+ }
@@ -0,0 +1,28 @@
1
+ import { Spacing } from '@/constants/theme';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ export const styles = StyleSheet.create({
5
+ container: {
6
+ position: 'absolute',
7
+ top: 0,
8
+ left: 0,
9
+ width: '100%',
10
+ height: '100%',
11
+ display: 'flex',
12
+ flexDirection: 'column',
13
+ alignItems: 'center',
14
+ justifyContent: 'center',
15
+ },
16
+ logo: {
17
+ width: 130,
18
+ height: 109,
19
+ },
20
+ title: {
21
+ fontSize: 16,
22
+ fontWeight: 'bold',
23
+ },
24
+ description: {
25
+ fontSize: 14,
26
+ marginTop: Spacing.sm,
27
+ },
28
+ });
@@ -38,6 +38,7 @@ try {
38
38
  const ignoreFilePatterns = [
39
39
  /template\.config\.(ts|js)$/, // 模板配置文件
40
40
  /\.template\./, // 其他模板文件
41
+ /declarations\.d\.ts$/, // 项目配置文件
41
42
  ];
42
43
 
43
44
  // 过滤包:排除内部别名和只被模板文件引用的包
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": {
4
+ "skipLibCheck": true,
5
+ "jsx": "react-jsx",
6
+ "baseUrl": ".",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "paths": {
10
+ "@/*": ["./*"]
11
+ }
12
+ },
13
+ "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"],
14
+ "exclude": [
15
+ "node_modules",
16
+ "**/*.spec.ts",
17
+ "**/*.test.ts",
18
+ "**/*.spec.tsx",
19
+ "**/*.test.tsx",
20
+ "dist",
21
+ "build",
22
+ ".expo"
23
+ ]
24
+ }