@coze-arch/cli 0.0.1-beta.5

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 (126) hide show
  1. package/README.md +142 -0
  2. package/bin/main +2 -0
  3. package/lib/__templates__/expo/.coze +7 -0
  4. package/lib/__templates__/expo/.cozeproj/scripts/deploy_build.sh +109 -0
  5. package/lib/__templates__/expo/.cozeproj/scripts/deploy_run.sh +257 -0
  6. package/lib/__templates__/expo/README.md +13 -0
  7. package/lib/__templates__/expo/_gitignore +11 -0
  8. package/lib/__templates__/expo/app.json +63 -0
  9. package/lib/__templates__/expo/babel.config.js +9 -0
  10. package/lib/__templates__/expo/client/app/(tabs)/_layout.tsx +43 -0
  11. package/lib/__templates__/expo/client/app/(tabs)/home.tsx +1 -0
  12. package/lib/__templates__/expo/client/app/(tabs)/index.tsx +7 -0
  13. package/lib/__templates__/expo/client/app/+not-found.tsx +79 -0
  14. package/lib/__templates__/expo/client/app/_layout.tsx +33 -0
  15. package/lib/__templates__/expo/client/assets/fonts/SpaceMono-Regular.ttf +0 -0
  16. package/lib/__templates__/expo/client/assets/images/adaptive-icon.png +0 -0
  17. package/lib/__templates__/expo/client/assets/images/default-avatar.png +0 -0
  18. package/lib/__templates__/expo/client/assets/images/favicon.png +0 -0
  19. package/lib/__templates__/expo/client/assets/images/icon.png +0 -0
  20. package/lib/__templates__/expo/client/assets/images/partial-react-logo.png +0 -0
  21. package/lib/__templates__/expo/client/assets/images/react-logo.png +0 -0
  22. package/lib/__templates__/expo/client/assets/images/react-logo@2x.png +0 -0
  23. package/lib/__templates__/expo/client/assets/images/react-logo@3x.png +0 -0
  24. package/lib/__templates__/expo/client/assets/images/splash-icon.png +0 -0
  25. package/lib/__templates__/expo/client/components/Screen.tsx +330 -0
  26. package/lib/__templates__/expo/client/components/SmartDateInput.tsx +238 -0
  27. package/lib/__templates__/expo/client/constants/theme.ts +118 -0
  28. package/lib/__templates__/expo/client/contexts/AuthContext.tsx +142 -0
  29. package/lib/__templates__/expo/client/hooks/useColorScheme.ts +1 -0
  30. package/lib/__templates__/expo/client/hooks/useTheme.ts +13 -0
  31. package/lib/__templates__/expo/client/index.js +11 -0
  32. package/lib/__templates__/expo/client/screens/home/index.tsx +54 -0
  33. package/lib/__templates__/expo/client/screens/home/styles.ts +332 -0
  34. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +80 -0
  35. package/lib/__templates__/expo/client/utils/index.ts +55 -0
  36. package/lib/__templates__/expo/eslint-formatter-simple.mjs +49 -0
  37. package/lib/__templates__/expo/eslint.config.mjs +98 -0
  38. package/lib/__templates__/expo/metro.config.js +53 -0
  39. package/lib/__templates__/expo/package.json +100 -0
  40. package/lib/__templates__/expo/pnpm-lock.yaml +13978 -0
  41. package/lib/__templates__/expo/src/index.ts +12 -0
  42. package/lib/__templates__/expo/template.config.js +49 -0
  43. package/lib/__templates__/expo/tsconfig.json +24 -0
  44. package/lib/__templates__/nextjs/.coze +11 -0
  45. package/lib/__templates__/nextjs/.vscode/settings.json +121 -0
  46. package/lib/__templates__/nextjs/README.md +36 -0
  47. package/lib/__templates__/nextjs/_gitignore +99 -0
  48. package/lib/__templates__/nextjs/_npmrc +22 -0
  49. package/lib/__templates__/nextjs/eslint.config.mjs +18 -0
  50. package/lib/__templates__/nextjs/next-env.d.ts +6 -0
  51. package/lib/__templates__/nextjs/next.config.ts +7 -0
  52. package/lib/__templates__/nextjs/package.json +32 -0
  53. package/lib/__templates__/nextjs/pnpm-lock.yaml +4061 -0
  54. package/lib/__templates__/nextjs/postcss.config.mjs +7 -0
  55. package/lib/__templates__/nextjs/public/file.svg +1 -0
  56. package/lib/__templates__/nextjs/public/globe.svg +1 -0
  57. package/lib/__templates__/nextjs/public/next.svg +1 -0
  58. package/lib/__templates__/nextjs/public/vercel.svg +1 -0
  59. package/lib/__templates__/nextjs/public/window.svg +1 -0
  60. package/lib/__templates__/nextjs/scripts/build.sh +14 -0
  61. package/lib/__templates__/nextjs/scripts/dev.sh +51 -0
  62. package/lib/__templates__/nextjs/scripts/start.sh +15 -0
  63. package/lib/__templates__/nextjs/src/app/favicon.ico +0 -0
  64. package/lib/__templates__/nextjs/src/app/globals.css +26 -0
  65. package/lib/__templates__/nextjs/src/app/layout.tsx +34 -0
  66. package/lib/__templates__/nextjs/src/app/page.tsx +66 -0
  67. package/lib/__templates__/nextjs/template.config.js +55 -0
  68. package/lib/__templates__/nextjs/tsconfig.json +34 -0
  69. package/lib/__templates__/react-rsbuild/.coze +11 -0
  70. package/lib/__templates__/react-rsbuild/.vscode/settings.json +121 -0
  71. package/lib/__templates__/react-rsbuild/README.md +61 -0
  72. package/lib/__templates__/react-rsbuild/_gitignore +97 -0
  73. package/lib/__templates__/react-rsbuild/_npmrc +22 -0
  74. package/lib/__templates__/react-rsbuild/package.json +31 -0
  75. package/lib/__templates__/react-rsbuild/pnpm-lock.yaml +997 -0
  76. package/lib/__templates__/react-rsbuild/rsbuild.config.ts +13 -0
  77. package/lib/__templates__/react-rsbuild/scripts/build.sh +14 -0
  78. package/lib/__templates__/react-rsbuild/scripts/dev.sh +51 -0
  79. package/lib/__templates__/react-rsbuild/scripts/start.sh +15 -0
  80. package/lib/__templates__/react-rsbuild/src/App.tsx +60 -0
  81. package/lib/__templates__/react-rsbuild/src/index.css +21 -0
  82. package/lib/__templates__/react-rsbuild/src/index.html +12 -0
  83. package/lib/__templates__/react-rsbuild/src/index.tsx +16 -0
  84. package/lib/__templates__/react-rsbuild/tailwind.config.js +9 -0
  85. package/lib/__templates__/react-rsbuild/template.config.js +54 -0
  86. package/lib/__templates__/react-rsbuild/tsconfig.json +17 -0
  87. package/lib/__templates__/rsbuild/.coze +11 -0
  88. package/lib/__templates__/rsbuild/.vscode/settings.json +7 -0
  89. package/lib/__templates__/rsbuild/README.md +61 -0
  90. package/lib/__templates__/rsbuild/_gitignore +97 -0
  91. package/lib/__templates__/rsbuild/_npmrc +22 -0
  92. package/lib/__templates__/rsbuild/package.json +24 -0
  93. package/lib/__templates__/rsbuild/pnpm-lock.yaml +888 -0
  94. package/lib/__templates__/rsbuild/rsbuild.config.ts +12 -0
  95. package/lib/__templates__/rsbuild/scripts/build.sh +14 -0
  96. package/lib/__templates__/rsbuild/scripts/dev.sh +51 -0
  97. package/lib/__templates__/rsbuild/scripts/start.sh +15 -0
  98. package/lib/__templates__/rsbuild/src/index.css +21 -0
  99. package/lib/__templates__/rsbuild/src/index.html +12 -0
  100. package/lib/__templates__/rsbuild/src/index.ts +5 -0
  101. package/lib/__templates__/rsbuild/src/main.ts +65 -0
  102. package/lib/__templates__/rsbuild/tailwind.config.js +9 -0
  103. package/lib/__templates__/rsbuild/template.config.js +54 -0
  104. package/lib/__templates__/rsbuild/tsconfig.json +16 -0
  105. package/lib/__templates__/templates.json +100 -0
  106. package/lib/__templates__/vite/.coze +11 -0
  107. package/lib/__templates__/vite/.vscode/settings.json +7 -0
  108. package/lib/__templates__/vite/README.md +61 -0
  109. package/lib/__templates__/vite/_gitignore +66 -0
  110. package/lib/__templates__/vite/_npmrc +22 -0
  111. package/lib/__templates__/vite/index.html +13 -0
  112. package/lib/__templates__/vite/package.json +24 -0
  113. package/lib/__templates__/vite/pnpm-lock.yaml +1249 -0
  114. package/lib/__templates__/vite/postcss.config.js +6 -0
  115. package/lib/__templates__/vite/scripts/build.sh +14 -0
  116. package/lib/__templates__/vite/scripts/dev.sh +51 -0
  117. package/lib/__templates__/vite/scripts/start.sh +15 -0
  118. package/lib/__templates__/vite/src/index.css +21 -0
  119. package/lib/__templates__/vite/src/index.ts +5 -0
  120. package/lib/__templates__/vite/src/main.ts +65 -0
  121. package/lib/__templates__/vite/tailwind.config.js +9 -0
  122. package/lib/__templates__/vite/template.config.js +55 -0
  123. package/lib/__templates__/vite/tsconfig.json +16 -0
  124. package/lib/__templates__/vite/vite.config.ts +15 -0
  125. package/lib/cli.js +1575 -0
  126. package/package.json +70 -0
@@ -0,0 +1,332 @@
1
+ import { StyleSheet, Platform } from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ loadingContainer: {
5
+ flex: 1,
6
+ justifyContent: 'center',
7
+ alignItems: 'center',
8
+ },
9
+ loadingText: {
10
+ marginTop: 12,
11
+ fontSize: 14,
12
+ color: '#64748B',
13
+ },
14
+ errorContainer: {
15
+ flex: 1,
16
+ justifyContent: 'center',
17
+ alignItems: 'center',
18
+ paddingHorizontal: 24,
19
+ },
20
+ errorText: {
21
+ marginTop: 16,
22
+ fontSize: 16,
23
+ color: '#64748B',
24
+ },
25
+ retryButton: {
26
+ marginTop: 20,
27
+ paddingHorizontal: 24,
28
+ paddingVertical: 12,
29
+ backgroundColor: '#2563EB',
30
+ borderRadius: 8,
31
+ },
32
+ retryButtonText: {
33
+ color: '#FFFFFF',
34
+ fontSize: 14,
35
+ fontWeight: '600',
36
+ },
37
+ header: {
38
+ flexDirection: 'row',
39
+ justifyContent: 'space-between',
40
+ alignItems: 'center',
41
+ paddingHorizontal: 16,
42
+ // paddingBottom: 16,
43
+ backgroundColor: '#FFFFFF',
44
+ // borderBottomWidth: 1,
45
+ borderBottomColor: '#E2E8F0',
46
+ },
47
+ headerLeft: {
48
+ flexDirection: 'row',
49
+ alignItems: 'center',
50
+ gap: 10,
51
+ },
52
+ logoContainer: {
53
+ width: 32,
54
+ height: 32,
55
+ backgroundColor: '#2563EB',
56
+ borderRadius: 8,
57
+ justifyContent: 'center',
58
+ alignItems: 'center',
59
+ ...Platform.select({
60
+ ios: {
61
+ shadowColor: '#000',
62
+ shadowOffset: { width: 0, height: 1 },
63
+ shadowOpacity: 0.1,
64
+ shadowRadius: 2,
65
+ },
66
+ android: {
67
+ elevation: 2,
68
+ },
69
+ }),
70
+ },
71
+ logoText: {
72
+ fontSize: 18,
73
+ fontWeight: '700',
74
+ color: '#1E293B',
75
+ letterSpacing: -0.5,
76
+ },
77
+ userMenuContainer: {
78
+ flexDirection: 'row',
79
+ alignItems: 'center',
80
+ gap: 10,
81
+ paddingLeft: 16,
82
+ borderLeftWidth: 1,
83
+ borderLeftColor: '#E2E8F0',
84
+ },
85
+ userInfo: {
86
+ alignItems: 'flex-end',
87
+ },
88
+ userName: {
89
+ fontSize: 14,
90
+ fontWeight: '500',
91
+ color: '#1E293B',
92
+ },
93
+ userRole: {
94
+ fontSize: 12,
95
+ color: '#64748B',
96
+ },
97
+ avatar: {
98
+ width: 36,
99
+ height: 36,
100
+ borderRadius: 18,
101
+ borderWidth: 2,
102
+ borderColor: '#FFFFFF',
103
+ ...Platform.select({
104
+ ios: {
105
+ shadowColor: '#000',
106
+ shadowOffset: { width: 0, height: 1 },
107
+ shadowOpacity: 0.1,
108
+ shadowRadius: 2,
109
+ },
110
+ android: {
111
+ elevation: 2,
112
+ },
113
+ }),
114
+ },
115
+ avatarPlaceholder: {
116
+ width: 36,
117
+ height: 36,
118
+ borderRadius: 18,
119
+ justifyContent: 'center',
120
+ alignItems: 'center',
121
+ borderWidth: 2,
122
+ borderColor: '#FFFFFF',
123
+ backgroundColor: '#3B82F6',
124
+ ...Platform.select({
125
+ ios: {
126
+ shadowColor: '#000',
127
+ shadowOffset: { width: 0, height: 1 },
128
+ shadowOpacity: 0.1,
129
+ shadowRadius: 2,
130
+ },
131
+ android: {
132
+ elevation: 2,
133
+ },
134
+ }),
135
+ },
136
+ avatarInitial: {
137
+ fontSize: 14,
138
+ fontWeight: '700',
139
+ color: '#FFFFFF',
140
+ },
141
+ content: {
142
+ paddingHorizontal: 16,
143
+ paddingTop: 24,
144
+ },
145
+ welcomeSection: {
146
+ marginBottom: 24,
147
+ },
148
+ welcomeTitle: {
149
+ fontSize: 22,
150
+ fontWeight: '700',
151
+ color: '#1E293B',
152
+ marginBottom: 4,
153
+ },
154
+ welcomeSubtitle: {
155
+ fontSize: 14,
156
+ color: '#64748B',
157
+ },
158
+ statsGrid: {
159
+ flexDirection: 'row',
160
+ gap: 12,
161
+ marginBottom: 24,
162
+ },
163
+ statCard: {
164
+ flex: 1,
165
+ backgroundColor: '#FFFFFF',
166
+ borderRadius: 12,
167
+ padding: 16,
168
+ ...Platform.select({
169
+ ios: {
170
+ shadowColor: '#000',
171
+ shadowOffset: { width: 0, height: 1 },
172
+ shadowOpacity: 0.05,
173
+ shadowRadius: 3,
174
+ },
175
+ android: {
176
+ elevation: 2,
177
+ },
178
+ }),
179
+ },
180
+ statCardHeader: {
181
+ flexDirection: 'row',
182
+ justifyContent: 'space-between',
183
+ alignItems: 'flex-start',
184
+ marginBottom: 12,
185
+ },
186
+ statIconContainer: {
187
+ width: 40,
188
+ height: 40,
189
+ borderRadius: 10,
190
+ justifyContent: 'center',
191
+ alignItems: 'center',
192
+ },
193
+ statIconBlue: {
194
+ backgroundColor: '#EFF6FF',
195
+ },
196
+ statIconRed: {
197
+ backgroundColor: '#FEF2F2',
198
+ },
199
+ statIconGreen: {
200
+ backgroundColor: '#ECFDF5',
201
+ },
202
+ attentionBadge: {
203
+ backgroundColor: '#FEF2F2',
204
+ paddingHorizontal: 6,
205
+ paddingVertical: 2,
206
+ borderRadius: 10,
207
+ },
208
+ attentionBadgeText: {
209
+ fontSize: 10,
210
+ fontWeight: '500',
211
+ color: '#EF4444',
212
+ },
213
+ rateBadge: {
214
+ backgroundColor: '#ECFDF5',
215
+ paddingHorizontal: 6,
216
+ paddingVertical: 2,
217
+ borderRadius: 10,
218
+ },
219
+ rateBadgeText: {
220
+ fontSize: 10,
221
+ fontWeight: '500',
222
+ color: '#10B981',
223
+ },
224
+ statValue: {
225
+ fontSize: 28,
226
+ fontWeight: '700',
227
+ color: '#1E293B',
228
+ marginBottom: 2,
229
+ },
230
+ statLabel: {
231
+ fontSize: 13,
232
+ color: '#64748B',
233
+ },
234
+ shortcutsSection: {
235
+ gap: 12,
236
+ marginBottom: 24,
237
+ },
238
+ shortcutCard: {
239
+ flexDirection: 'row',
240
+ justifyContent: 'space-between',
241
+ alignItems: 'center',
242
+ backgroundColor: '#FFFFFF',
243
+ borderRadius: 12,
244
+ padding: 16,
245
+ ...Platform.select({
246
+ ios: {
247
+ shadowColor: '#000',
248
+ shadowOffset: { width: 0, height: 1 },
249
+ shadowOpacity: 0.05,
250
+ shadowRadius: 3,
251
+ },
252
+ android: {
253
+ elevation: 2,
254
+ },
255
+ }),
256
+ },
257
+ shortcutContent: {
258
+ flex: 1,
259
+ marginRight: 16,
260
+ },
261
+ shortcutTitle: {
262
+ fontSize: 16,
263
+ fontWeight: '600',
264
+ color: '#1E293B',
265
+ marginBottom: 6,
266
+ },
267
+ shortcutDescription: {
268
+ fontSize: 13,
269
+ color: '#64748B',
270
+ marginBottom: 10,
271
+ lineHeight: 18,
272
+ },
273
+ shortcutAction: {
274
+ flexDirection: 'row',
275
+ alignItems: 'center',
276
+ gap: 6,
277
+ },
278
+ shortcutActionText: {
279
+ fontSize: 13,
280
+ fontWeight: '500',
281
+ color: '#2563EB',
282
+ },
283
+ shortcutIconContainer: {
284
+ width: 56,
285
+ height: 56,
286
+ borderRadius: 28,
287
+ justifyContent: 'center',
288
+ alignItems: 'center',
289
+ },
290
+ shortcutIconBlue: {
291
+ backgroundColor: '#EFF6FF',
292
+ },
293
+ shortcutIconGreen: {
294
+ backgroundColor: '#ECFDF5',
295
+ },
296
+ bannerContainer: {
297
+ height: 160,
298
+ borderRadius: 12,
299
+ overflow: 'hidden',
300
+ backgroundColor: '#1E3A8A',
301
+ },
302
+ bannerOverlay: {
303
+ flex: 1,
304
+ justifyContent: 'center',
305
+ paddingHorizontal: 20,
306
+ },
307
+ bannerTitle: {
308
+ fontSize: 18,
309
+ fontWeight: '700',
310
+ color: '#FFFFFF',
311
+ marginBottom: 6,
312
+ },
313
+ bannerSubtitle: {
314
+ fontSize: 13,
315
+ color: '#BFDBFE',
316
+ marginBottom: 16,
317
+ },
318
+ bannerButton: {
319
+ alignSelf: 'flex-start',
320
+ backgroundColor: '#FFFFFF',
321
+ paddingHorizontal: 20,
322
+ paddingVertical: 10,
323
+ borderRadius: 8,
324
+ },
325
+ bannerButtonText: {
326
+ fontSize: 13,
327
+ fontWeight: '500',
328
+ color: '#2563EB',
329
+ },
330
+ });
331
+
332
+ export default styles;
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 自动检测并安装缺失的依赖
5
+ * 使用方法: node scripts/install-missing-deps.js
6
+ */
7
+
8
+ const { execSync } = require('child_process');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ console.log('🔍 检测缺失的依赖...\n');
13
+
14
+ try {
15
+ // 运行 depcheck 并获取 JSON 输出
16
+ // 注意:depcheck 发现问题时会返回非零退出码,但这不是错误
17
+ let depcheckOutput;
18
+ try {
19
+ depcheckOutput = execSync('npx depcheck --json', {
20
+ encoding: 'utf-8',
21
+ stdio: ['pipe', 'pipe', 'pipe']
22
+ });
23
+ } catch (execError) {
24
+ // depcheck 返回非零退出码时仍然有输出
25
+ if (execError.stdout) {
26
+ depcheckOutput = execError.stdout;
27
+ } else {
28
+ throw execError;
29
+ }
30
+ }
31
+
32
+ const result = JSON.parse(depcheckOutput);
33
+
34
+ // 获取缺失的依赖
35
+ const missing = result.missing || {};
36
+ const missingPackages = Object.keys(missing).filter(pkg => !pkg.startsWith('@api/') && !pkg.startsWith('@/') && pkg !== '@api');
37
+
38
+ if (missingPackages.length === 0) {
39
+ console.log('✅ 没有发现缺失的依赖!');
40
+ process.exit(0);
41
+ }
42
+
43
+ console.log('📦 发现以下缺失的依赖:');
44
+ missingPackages.forEach((pkg, index) => {
45
+ const files = missing[pkg];
46
+ console.log(` ${index + 1}. ${pkg}`);
47
+ console.log(` 被引用于: ${files.slice(0, 2).join(', ')}${files.length > 2 ? ' ...' : ''}`);
48
+ });
49
+
50
+ console.log('\n🚀 开始安装...\n');
51
+
52
+ // 使用 expo install 安装所有缺失的包
53
+ const packagesToInstall = missingPackages.join(' ');
54
+
55
+ try {
56
+ execSync(`pnpm expo install ${packagesToInstall}`, {
57
+ stdio: 'inherit'
58
+ });
59
+
60
+ console.log('\n✅ 所有缺失的依赖已安装完成!');
61
+ } catch (installError) {
62
+ console.log('\n⚠️ expo install 失败,尝试使用 npm install...\n');
63
+
64
+ execSync(`npm install ${packagesToInstall}`, {
65
+ stdio: 'inherit'
66
+ });
67
+
68
+ console.log('\n✅ 所有缺失的依赖已通过 npm 安装完成!');
69
+ }
70
+
71
+ } catch (error) {
72
+ if (error.message.includes('depcheck')) {
73
+ console.error('❌ depcheck 未安装或运行失败');
74
+ console.log('💡 尝试运行: npm install -g depcheck');
75
+ } else {
76
+ console.error('❌ 发生错误:', error.message);
77
+ }
78
+ process.exit(1);
79
+ }
80
+
@@ -0,0 +1,55 @@
1
+ // import { OpenAPI } from '@api'; // 如果使用 openapi 客户端,请取消注释并确保安装
2
+ import dayjs from 'dayjs';
3
+ import utc from 'dayjs/plugin/utc';
4
+ dayjs.extend(utc);
5
+
6
+ const API_BASE = (process.env.EXPO_PUBLIC_API_BASE ?? '').replace(/\/$/, '');
7
+
8
+ /**
9
+ * 构建文件或图片完整的URL
10
+ * @param url 相对或绝对路径
11
+ * @param w 宽度 (px) - 自动向下取整
12
+ * @param h 高度 (px)
13
+ */
14
+ export const buildAssetUrl = (url?: string | null, w?: number, h?: number): string | undefined => {
15
+ if (!url) return undefined;
16
+ if (/^https?:\/\//i.test(url)) return url; // 绝对路径直接返回
17
+
18
+ // 1. 去除 Base 尾部和 Path 头部的斜杠
19
+ const base = API_BASE;
20
+ const path = url.replace(/^\//, '');
21
+ const abs = `${base}/${path}`;
22
+
23
+ // 2. 无需缩略图则直接返回
24
+ if (!w && !h) return abs;
25
+
26
+ // 3. 构造参数,保留原有 Query (如有)
27
+ const separator = abs.includes('?') ? '&' : '?';
28
+ const query = [
29
+ w ? `w=${Math.floor(w)}` : '',
30
+ h ? `h=${Math.floor(h)}` : ''
31
+ ].filter(Boolean).join('&');
32
+ return `${abs}${separator}${query}`;
33
+ };
34
+
35
+ /**
36
+ * 将UTC时间字符串转换为本地时间字符串
37
+ * @param utcDateStr UTC时间字符串,格式如:2025-11-26T01:49:48.009573
38
+ * @returns 本地时间字符串,格式如:2025-11-26 08:49:48
39
+ */
40
+ export const convertToLocalTimeStr = (utcDateStr: string): string => {
41
+ if (!utcDateStr) {
42
+ return utcDateStr;
43
+ }
44
+ const microUtcRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{1,6}/;
45
+ if (!microUtcRegex.test(utcDateStr)) {
46
+ console.log('invalid utcDateStr:', utcDateStr);
47
+ return utcDateStr;
48
+ }
49
+ const normalized = utcDateStr.replace(/\.(\d{6})$/, (_, frac) => `.${frac.slice(0, 3)}`);
50
+ const d = dayjs.utc(normalized);
51
+ if (!d.isValid()) {
52
+ return utcDateStr;
53
+ }
54
+ return d.local().format('YYYY-MM-DD HH:mm:ss');
55
+ }
@@ -0,0 +1,49 @@
1
+ export default function (results) {
2
+
3
+ return results
4
+ .flatMap(file =>
5
+ file.messages.map(m => {
6
+ // split into lines
7
+ const lines = m.message.split('\n');
8
+
9
+ // 第一行(句子):直接用
10
+ const first = lines[0];
11
+
12
+ // 附加解释:过滤掉所有 codeframe/箭头/行号/重复路径
13
+ const details = lines
14
+ .slice(1)
15
+ .filter(l => {
16
+ // 移除空行
17
+ if (!l.trim()) return false;
18
+
19
+ // 移除 "58 | xxx" 这样的行
20
+ if (/^\s*\d+\s*\|/.test(l)) return false;
21
+
22
+ // 移除 "> 60 | ..." 这样的箭头行
23
+ if (/^\s*>/.test(l)) return false;
24
+
25
+ // 移除只有箭头提示的行,如 "| ^^^^^"
26
+ if (/^\s*\|/.test(l)) return false;
27
+
28
+ // 移除 "…" 省略号行
29
+ if (/^\s*…/.test(l)) return false;
30
+
31
+ // 移除重复路径行(eslint message 有时夹带 file:line)
32
+ if (/\.tsx:\d+:\d+/.test(l)) return false;
33
+
34
+ return true;
35
+ })
36
+ .join('\n')
37
+ .trim();
38
+
39
+ let output = `${file.filePath}:${m.line}:${m.column} ${
40
+ m.severity === 2 ? 'error' : 'warn'
41
+ } ${first}`;
42
+
43
+ if (details) output += `\n${details}\n`;
44
+
45
+ return output;
46
+ })
47
+ )
48
+ .join('\n');
49
+ };
@@ -0,0 +1,98 @@
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
+
9
+ export default [
10
+ {
11
+ ignores: [
12
+ '**/dist/**',
13
+ '**/node_modules/**',
14
+ 'api/**', // 排除自动生成的 API 代码
15
+ 'src/api/**', // 排除 src 下的自动生成 API
16
+ '.expo/**', // 排除 Expo 自动生成的文件
17
+ 'tailwind.config.js', // 排除 Tailwind 配置文件
18
+ ],
19
+ },
20
+ regexp.configs["flat/recommended"],
21
+ js.configs.recommended,
22
+ ...tseslint.configs.recommended,
23
+
24
+ // React 的推荐配置
25
+ pluginReact.configs.flat.recommended,
26
+ pluginReact.configs.flat['jsx-runtime'],
27
+ reactHooks.configs.flat.recommended,
28
+ {
29
+ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
30
+
31
+ // 语言选项:设置全局变量
32
+ languageOptions: {
33
+ globals: {
34
+ ...globals.browser,
35
+ ...globals.es2021,
36
+ '__DEV__': 'readonly',
37
+ },
38
+ },
39
+
40
+ // React 版本自动检测
41
+ settings: {
42
+ react: {
43
+ version: 'detect',
44
+ },
45
+ 'import/resolver': {
46
+ typescript: {
47
+ project: ['./tsconfig.json'],
48
+ alwaysTryTypes: true,
49
+ },
50
+ },
51
+ },
52
+
53
+ plugins: {
54
+ import: pluginImport,
55
+ },
56
+ rules: {
57
+ // 关闭代码风格规则
58
+ 'semi': 'off',
59
+ 'quotes': 'off',
60
+ 'indent': 'off',
61
+ "no-empty": ["error", { "allowEmptyCatch": true }],
62
+ "no-unused-expressions": "warn",
63
+ "no-useless-escape": "warn",
64
+ 'import/no-unresolved': 'error',
65
+ '@typescript-eslint/no-require-imports': 'off',
66
+ '@typescript-eslint/no-unused-vars': 'off',
67
+ '@typescript-eslint/no-explicit-any': 'off',
68
+ '@typescript-eslint/ban-ts-comment': 'off',
69
+ '@typescript-eslint/no-empty-object-type': 'off',
70
+ 'no-prototype-builtins': 'off',
71
+ 'react/react-in-jsx-scope': 'off',
72
+ 'react/jsx-uses-react': 'off',
73
+ },
74
+ },
75
+
76
+ {
77
+ files: [
78
+ "metro.config.js",
79
+ "scripts/**/*.js",
80
+ "expo/scripts/**/*.js",
81
+ "eslint.config.js",
82
+ "babel.config.js",
83
+ "server/**/*.js"
84
+ ],
85
+ languageOptions: {
86
+ globals: {
87
+ ...globals.node,
88
+ },
89
+ },
90
+ rules: {
91
+ // 在 .js 文件中关闭 TS 规则
92
+ '@typescript-eslint/no-require-imports': 'off',
93
+ // 在 Node.js 文件中允许 require
94
+ '@typescript-eslint/no-var-requires': 'off',
95
+ 'no-undef': 'off',
96
+ },
97
+ },
98
+ ];
@@ -0,0 +1,53 @@
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
+ /*
32
+ const apiProxy = createProxyMiddleware({
33
+ target: 'http://localhost:3000',
34
+ logLevel: 'debug',
35
+ });
36
+
37
+ config.server = {
38
+ ...config.server,
39
+ enhanceMiddleware: (metroMiddleware, metroServer) => {
40
+ return connect()
41
+ .use((req, res, next) => {
42
+ if (req.url && req.url.startsWith('/api')) {
43
+ console.log(`[Metro Proxy] Forwarding ${req.method} ${req.url}`);
44
+ return apiProxy(req, res, next);
45
+ }
46
+ next();
47
+ })
48
+ .use(metroMiddleware);
49
+ },
50
+ }
51
+ */
52
+
53
+ module.exports = config;