@coze-arch/cli 0.0.1-alpha.bcc7d9 → 0.0.1-alpha.bd55ba

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 (99) hide show
  1. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +15 -14
  2. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +9 -8
  3. package/lib/__templates__/expo/README.md +2 -2
  4. package/lib/__templates__/expo/client/eslint.config.mjs +17 -1
  5. package/lib/__templates__/expo/client/metro.config.js +3 -0
  6. package/lib/__templates__/expo/client/package.json +36 -35
  7. package/lib/__templates__/expo/client/screens/demo/index.tsx +3 -3
  8. package/lib/__templates__/expo/eslint-plugins/react-native/index.js +9 -0
  9. package/lib/__templates__/expo/eslint-plugins/react-native/rule.js +64 -0
  10. package/lib/__templates__/expo/package.json +1 -1
  11. package/lib/__templates__/expo/patches/expo@54.0.33.patch +45 -0
  12. package/lib/__templates__/expo/pnpm-lock.yaml +338 -1735
  13. package/lib/__templates__/expo/server/package.json +9 -7
  14. package/lib/__templates__/expo/server/src/index.ts +1 -0
  15. package/lib/__templates__/expo/template.config.js +56 -0
  16. package/lib/__templates__/native-static/.coze +11 -0
  17. package/lib/__templates__/native-static/index.html +33 -0
  18. package/lib/__templates__/native-static/styles/main.css +136 -0
  19. package/lib/__templates__/native-static/template.config.js +22 -0
  20. package/lib/__templates__/nextjs/package.json +3 -1
  21. package/lib/__templates__/nextjs/pnpm-lock.yaml +1051 -934
  22. package/lib/__templates__/nextjs/src/app/page.tsx +18 -60
  23. package/lib/__templates__/nextjs/template.config.js +49 -14
  24. package/lib/__templates__/taro/.coze +14 -0
  25. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +19 -0
  26. package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +14 -0
  27. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +2 -0
  28. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +151 -0
  29. package/lib/__templates__/taro/.cozeproj/scripts/init_env.sh +5 -0
  30. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -0
  31. package/lib/__templates__/taro/README.md +751 -0
  32. package/lib/__templates__/taro/_gitignore +40 -0
  33. package/lib/__templates__/taro/_npmrc +18 -0
  34. package/lib/__templates__/taro/babel.config.js +12 -0
  35. package/lib/__templates__/taro/config/dev.ts +9 -0
  36. package/lib/__templates__/taro/config/index.ts +223 -0
  37. package/lib/__templates__/taro/config/prod.ts +34 -0
  38. package/lib/__templates__/taro/eslint.config.mjs +80 -0
  39. package/lib/__templates__/taro/key/private.appid.key +0 -0
  40. package/lib/__templates__/taro/package.json +107 -0
  41. package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
  42. package/lib/__templates__/taro/pnpm-lock.yaml +23100 -0
  43. package/lib/__templates__/taro/pnpm-workspace.yaml +2 -0
  44. package/lib/__templates__/taro/project.config.json +15 -0
  45. package/lib/__templates__/taro/server/nest-cli.json +10 -0
  46. package/lib/__templates__/taro/server/package.json +40 -0
  47. package/lib/__templates__/taro/server/src/app.controller.ts +23 -0
  48. package/lib/__templates__/taro/server/src/app.module.ts +10 -0
  49. package/lib/__templates__/taro/server/src/app.service.ts +8 -0
  50. package/lib/__templates__/taro/server/src/interceptors/http-status.interceptor.ts +23 -0
  51. package/lib/__templates__/taro/server/src/main.ts +49 -0
  52. package/lib/__templates__/taro/server/tsconfig.json +24 -0
  53. package/lib/__templates__/taro/src/app.config.ts +11 -0
  54. package/lib/__templates__/taro/src/app.css +52 -0
  55. package/lib/__templates__/taro/src/app.tsx +9 -0
  56. package/lib/__templates__/taro/src/index.html +39 -0
  57. package/lib/__templates__/taro/src/network.ts +39 -0
  58. package/lib/__templates__/taro/src/pages/index/index.config.ts +3 -0
  59. package/lib/__templates__/taro/src/pages/index/index.css +1 -0
  60. package/lib/__templates__/taro/src/pages/index/index.tsx +33 -0
  61. package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
  62. package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
  63. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +201 -0
  64. package/lib/__templates__/taro/src/presets/h5-styles.ts +142 -0
  65. package/lib/__templates__/taro/src/presets/index.tsx +18 -0
  66. package/lib/__templates__/taro/stylelint.config.mjs +4 -0
  67. package/lib/__templates__/taro/template.config.js +68 -0
  68. package/lib/__templates__/taro/tsconfig.json +29 -0
  69. package/lib/__templates__/taro/types/global.d.ts +32 -0
  70. package/lib/__templates__/templates.json +75 -0
  71. package/lib/__templates__/vite/package.json +5 -1
  72. package/lib/__templates__/vite/pnpm-lock.yaml +146 -1659
  73. package/lib/__templates__/vite/src/main.ts +17 -47
  74. package/lib/__templates__/vite/template.config.js +49 -14
  75. package/lib/__templates__/vite/vite.config.ts +1 -0
  76. package/lib/__templates__/vite-vue/.coze +12 -0
  77. package/lib/__templates__/vite-vue/README.md +342 -0
  78. package/lib/__templates__/vite-vue/_gitignore +66 -0
  79. package/lib/__templates__/vite-vue/_npmrc +23 -0
  80. package/lib/__templates__/vite-vue/eslint.config.mjs +9 -0
  81. package/lib/__templates__/vite-vue/index.html +13 -0
  82. package/lib/__templates__/vite-vue/package.json +37 -0
  83. package/lib/__templates__/vite-vue/pnpm-lock.yaml +3132 -0
  84. package/lib/__templates__/vite-vue/postcss.config.mjs +6 -0
  85. package/lib/__templates__/vite-vue/scripts/build.sh +14 -0
  86. package/lib/__templates__/vite-vue/scripts/dev.sh +32 -0
  87. package/lib/__templates__/vite-vue/scripts/prepare.sh +9 -0
  88. package/lib/__templates__/vite-vue/scripts/start.sh +15 -0
  89. package/lib/__templates__/vite-vue/src/App.vue +38 -0
  90. package/lib/__templates__/vite-vue/src/index.css +29 -0
  91. package/lib/__templates__/vite-vue/src/main.ts +6 -0
  92. package/lib/__templates__/vite-vue/src/vite-env.d.ts +8 -0
  93. package/lib/__templates__/vite-vue/tailwind.config.js +9 -0
  94. package/lib/__templates__/vite-vue/template.config.js +127 -0
  95. package/lib/__templates__/vite-vue/tsconfig.json +17 -0
  96. package/lib/__templates__/vite-vue/vite.config.ts +28 -0
  97. package/lib/cli.js +373 -82
  98. package/package.json +2 -1
  99. package/lib/__templates__/expo/patches/expo@54.0.32.patch +0 -28
@@ -1,7 +1,7 @@
1
1
  ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
2
2
  PREVIEW_DIR="${COZE_PREVIEW_DIR:-/source/preview}"
3
3
  LOG_DIR="${COZE_LOG_DIR:-$ROOT_DIR/logs}"
4
- LOG_FILE="$LOG_DIR/app.log"
4
+ LOG_CLIENT_FILE="$LOG_DIR/client.log"
5
5
  mkdir -p "$LOG_DIR"
6
6
 
7
7
  # ==================== 配置项 ====================
@@ -89,14 +89,17 @@ ensure_port() {
89
89
  pipe_to_log() {
90
90
  local source="${1:-CLIENT}"
91
91
  local raw_log="${2:-}"
92
- local line timestamp ts msg record
92
+ local line clean_line timestamp
93
93
  while IFS= read -r line || [ -n "$line" ]; do
94
+ clean_line=$(printf '%s' "$line" | sed 's/\x1b\[[0-9;]*[mA-Za-z]//g')
95
+ if echo "$clean_line" | grep -qE '(^(Web|iOS|Android) node_modules/.*expo-router.*entry\.js.*%|^(Web|iOS|Android) Bundled [0-9]+ms node_modules/.*expo-router.*entry\.js|Logs will appear in the browser)'; then
96
+ continue
97
+ fi
94
98
  if [ -n "$raw_log" ]; then
95
- echo "$line" >> "$raw_log"
99
+ timestamp=$(date '+%Y-%m-%d %H:%M:%S')
100
+ echo "[$timestamp] $clean_line" >> "$raw_log"
96
101
  fi
97
- line=$(echo "[$source] $line" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\x1b\[[0-9;]*m//g')
98
- msg="${line}"
99
- echo "$msg"
102
+ printf '[%s] %s\n' "$source" "$clean_line"
100
103
  done
101
104
  }
102
105
 
@@ -115,11 +118,11 @@ start_expo() {
115
118
  pushd "$ROOT_DIR/client"
116
119
 
117
120
  if [ "$offline" = "1" ]; then
118
- ( EXPO_OFFLINE=1 EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
119
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$ROOT_DIR/logs/client.log" ) &
121
+ ( EXPO_OFFLINE=1 EXPO_NO_DEPENDENCY_VALIDATION=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
122
+ nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$LOG_CLIENT_FILE" ) &
120
123
  else
121
- ( EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
122
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$ROOT_DIR/logs/client.log" ) &
124
+ ( EXPO_NO_DEPENDENCY_VALIDATION=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
125
+ nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$LOG_CLIENT_FILE" ) &
123
126
  fi
124
127
  EXPO_PID=$!
125
128
  disown $EXPO_PID 2>/dev/null || true
@@ -130,9 +133,9 @@ start_expo() {
130
133
  detect_expo_fetch_failed() {
131
134
  local timeout="${1:-8}"
132
135
  local waited=0
133
- local log_file="$ROOT_DIR/logs/client.log"
136
+ local log_file="$LOG_CLIENT_FILE"
134
137
  while [ "$waited" -lt "$timeout" ]; do
135
- if [ -f "$log_file" ] && grep -q "TypeError: fetch failed" "$log_file" 2>/dev/null; then
138
+ if [ -f "$log_file" ] && tail -n 100 "$log_file" 2>/dev/null | grep -q "TypeError: fetch failed"; then
136
139
  return 0
137
140
  fi
138
141
  sleep 1
@@ -166,8 +169,6 @@ check_command "pnpm"
166
169
  check_command "lsof"
167
170
  check_command "bash"
168
171
 
169
- echo "准备日志目录:$ROOT_DIR/logs"
170
- mkdir -p "$ROOT_DIR/logs"
171
172
  # 端口占用预检查与处理
172
173
  ensure_port SERVER_PORT "$SERVER_PORT"
173
174
  ensure_port EXPO_PORT "$EXPO_PORT"
@@ -2,8 +2,8 @@
2
2
 
3
3
  ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
4
4
  SERVER_DIR="$ROOT_DIR/server"
5
- LOG_DIR="$ROOT_DIR/logs"
6
- LOG_FILE="$LOG_DIR/server.log"
5
+ LOG_DIR="${COZE_LOG_DIR:-$ROOT_DIR/logs}"
6
+ LOG_SERVER_FILE="$LOG_DIR/server.log"
7
7
  SERVER_PORT="${SERVER_PORT:-9091}"
8
8
 
9
9
  mkdir -p "$LOG_DIR"
@@ -11,13 +11,14 @@ mkdir -p "$LOG_DIR"
11
11
  pipe_to_log() {
12
12
  local source="${1:-SERVER}"
13
13
  local raw_log="${2:-}"
14
- local line
14
+ local line clean_line timestamp
15
15
  while IFS= read -r line || [ -n "$line" ]; do
16
+ clean_line=$(printf '%s' "$line" | sed 's/\x1b\[[0-9;]*[mA-Za-z]//g')
16
17
  if [ -n "$raw_log" ]; then
17
- echo "$line" >> "$raw_log"
18
+ timestamp=$(date '+%Y-%m-%d %H:%M:%S')
19
+ echo "[$timestamp] $clean_line" >> "$raw_log"
18
20
  fi
19
- line=$(echo "[$source] $line" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\x1b\[[0-9;]*m//g')
20
- echo "$line"
21
+ printf '[%s] %s\n' "$source" "$clean_line"
21
22
  done
22
23
  }
23
24
 
@@ -36,10 +37,10 @@ kill_old_server() {
36
37
  echo "==================== Server Dev Run ===================="
37
38
  echo "Server 目录:$SERVER_DIR"
38
39
  echo "Server 端口:$SERVER_PORT"
39
- echo "日志文件:$LOG_FILE"
40
+ echo "日志文件:$LOG_SERVER_FILE"
40
41
 
41
42
  kill_old_server
42
43
 
43
44
  echo "启动 server 服务..."
44
45
  cd "$SERVER_DIR"
45
- NODE_ENV=development PORT="$SERVER_PORT" npx tsx ./src/index.ts 2>&1 | pipe_to_log "SERVER" "$LOG_FILE"
46
+ NODE_ENV=development PORT="$SERVER_PORT" npx tsx watch ./src/index.ts 2>&1 | pipe_to_log "SERVER" "$LOG_SERVER_FILE"
@@ -15,11 +15,11 @@
15
15
  | └── package.json # 服务端 package.json
16
16
  ├── client/ # React Native 前端代码
17
17
  │ ├── app/ # Expo Router 路由目录(仅路由配置)
18
- │ │ ├── _layout.tsx # 根布局文件(必需)
18
+ │ │ ├── _layout.tsx # 根布局文件(必需,务必阅读)
19
19
  │ │ ├── home.tsx # 首页
20
20
  │ │ └── index.tsx # re-export home.tsx
21
21
  │ ├── screens/ # 页面实现目录(与 app/ 路由对应)
22
- │ │ └── home/
22
+ │ │ └── demo/ # demo 示例页面
23
23
  │ │ ├── index.tsx # 页面组件实现
24
24
  │ │ └── styles.ts # 页面样式
25
25
  │ ├── components/ # 可复用组件
@@ -6,7 +6,8 @@ import reactHooks from 'eslint-plugin-react-hooks';
6
6
  import regexp from 'eslint-plugin-regexp';
7
7
  import pluginImport from 'eslint-plugin-import';
8
8
  import fontawesome6 from '../eslint-plugins/fontawesome6/index.js';
9
- import reanimated from '../eslint-plugins/reanimated/index.js'
9
+ import reanimated from '../eslint-plugins/reanimated/index.js';
10
+ import reactnative from '../eslint-plugins/react-native/index.js';
10
11
 
11
12
  export default [
12
13
  {
@@ -18,6 +19,7 @@ export default [
18
19
  '.expo/**', // 排除 Expo 自动生成的文件
19
20
  'tailwind.config.js', // 排除 Tailwind 配置文件
20
21
  '**/*.d.ts',
22
+ 'eslint.config.*',
21
23
  ],
22
24
  },
23
25
  regexp.configs["flat/recommended"],
@@ -57,6 +59,7 @@ export default [
57
59
  import: pluginImport,
58
60
  fontawesome6,
59
61
  reanimated,
62
+ reactnative,
60
63
  },
61
64
  rules: {
62
65
  // 关闭代码风格规则
@@ -77,6 +80,19 @@ export default [
77
80
  'react/jsx-uses-react': 'off',
78
81
  'fontawesome6/valid-name': 'error',
79
82
  'reanimated/ban-mix-use': 'error',
83
+ // 禁止使用 via.placeholder.com 服务
84
+ 'no-restricted-syntax': [
85
+ 'error',
86
+ {
87
+ 'selector': 'Literal[value=/via\\.placeholder\\.com/]',
88
+ 'message': 'via.placeholder.com 服务不可用,禁止在代码中使用',
89
+ },
90
+ {
91
+ 'selector': 'TemplateLiteral > TemplateElement[value.raw=/via\\.placeholder\\.com/]',
92
+ 'message': 'via.placeholder.com 服务不可用,禁止在代码中使用',
93
+ },
94
+ ],
95
+ 'reactnative/wrap-horizontal-scrollview-inside-view': ['error'],
80
96
  },
81
97
  },
82
98
 
@@ -26,6 +26,9 @@ config.resolver.blockList = [
26
26
  // 4. 通用规则
27
27
  /.*\/__tests__\/.*/, // 排除所有测试目录
28
28
  /.*\.git\/.*/, // 排除 Git 目录
29
+
30
+ // 5. pnpm 临时目录(避免 ENOENT 错误)
31
+ /.*node_modules\/\.pnpm\/.*_tmp_\d+.*/,
29
32
  ];
30
33
 
31
34
  const BACKEND_TARGET = 'http://localhost:9091';
@@ -15,37 +15,38 @@
15
15
  "preset": "jest-expo"
16
16
  },
17
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",
18
+ "@expo/metro-runtime": "~6.1.2",
19
+ "@expo/vector-icons": "^15.0.3",
20
+ "@react-native-async-storage/async-storage": "2.2.0",
21
+ "@react-native-community/datetimepicker": "8.4.4",
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.1",
25
25
  "@react-navigation/bottom-tabs": "^7.2.0",
26
26
  "@react-navigation/native": "^7.0.14",
27
27
  "dayjs": "^1.11.19",
28
- "expo": "54.0.32",
29
- "expo-auth-session": "^7.0.9",
30
- "expo-av": "~16.0.6",
31
- "expo-blur": "~15.0.6",
28
+ "expo": "54.0.33",
29
+ "expo-auth-session": "~7.0.10",
30
+ "expo-av": "~16.0.8",
31
+ "expo-blur": "~15.0.8",
32
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
- "js-base64": "^3.7.7",
43
- "expo-router": "~6.0.0",
44
- "expo-splash-screen": "~31.0.8",
45
- "expo-status-bar": "~3.0.7",
46
- "expo-symbols": "~1.0.6",
33
+ "expo-constants": "~18.0.13",
34
+ "expo-crypto": "~15.0.8",
35
+ "expo-file-system": "~19.0.21",
36
+ "expo-font": "~14.0.11",
37
+ "expo-haptics": "~15.0.8",
38
+ "expo-image": "~3.0.11",
39
+ "expo-image-picker": "~17.0.10",
40
+ "expo-linear-gradient": "~15.0.8",
41
+ "expo-linking": "~8.0.11",
42
+ "expo-location": "~19.0.8",
43
+ "expo-router": "~6.0.23",
44
+ "expo-splash-screen": "~31.0.13",
45
+ "expo-status-bar": "~3.0.9",
46
+ "expo-symbols": "~1.0.8",
47
47
  "expo-system-ui": "~6.0.9",
48
48
  "expo-web-browser": "~15.0.10",
49
+ "js-base64": "^3.7.7",
49
50
  "react": "19.1.0",
50
51
  "react-dom": "19.1.0",
51
52
  "react-native": "0.81.5",
@@ -53,25 +54,26 @@
53
54
  "react-native-gesture-handler": "~2.28.0",
54
55
  "react-native-keyboard-aware-scroll-view": "^0.9.5",
55
56
  "react-native-modal-datetime-picker": "18.0.0",
56
- "react-native-reanimated": "~4.1.0",
57
+ "react-native-reanimated": "~4.1.1",
57
58
  "react-native-safe-area-context": "~5.6.0",
58
59
  "react-native-screens": "~4.16.0",
59
- "react-native-svg": "15.15.0",
60
+ "react-native-svg": "15.12.1",
60
61
  "react-native-toast-message": "^2.3.3",
61
- "react-native-web": "^0.21.2",
62
- "react-native-webview": "~13.15.0",
62
+ "react-native-web": "~0.21.0",
63
+ "react-native-webview": "13.15.0",
63
64
  "react-native-worklets": "0.5.1",
64
65
  "zod": "^4.2.1"
65
66
  },
66
67
  "devDependencies": {
67
68
  "@babel/core": "^7.25.2",
68
- "babel-plugin-module-resolver": "^5.0.2",
69
- "babel-preset-expo": "^54.0.9",
70
69
  "@eslint/js": "^9.27.0",
71
70
  "@types/jest": "^29.5.12",
72
71
  "@types/react": "~19.1.0",
73
72
  "@types/react-test-renderer": "19.1.0",
73
+ "babel-plugin-module-resolver": "^5.0.2",
74
+ "babel-preset-expo": "^54.0.9",
74
75
  "chalk": "^4.1.2",
76
+ "connect": "^3.7.0",
75
77
  "depcheck": "^1.4.7",
76
78
  "esbuild": "0.27.2",
77
79
  "eslint": "^9.39.2",
@@ -82,13 +84,12 @@
82
84
  "eslint-plugin-react-hooks": "^7.0.1",
83
85
  "eslint-plugin-regexp": "^2.10.0",
84
86
  "globals": "^16.1.0",
87
+ "http-proxy-middleware": "^3.0.5",
85
88
  "jest": "^29.2.1",
86
- "jest-expo": "~54.0.10",
89
+ "jest-expo": "~54.0.17",
87
90
  "react-test-renderer": "19.1.0",
88
91
  "tsx": "^4.21.0",
89
92
  "typescript": "^5.8.3",
90
- "typescript-eslint": "^8.32.1",
91
- "connect": "^3.7.0",
92
- "http-proxy-middleware": "^3.0.5"
93
+ "typescript-eslint": "^8.32.1"
93
94
  }
94
95
  }
@@ -15,10 +15,10 @@ export default function DemoPage() {
15
15
  >
16
16
  <Image
17
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"
18
+ source="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-coding/icon/coze-coding.gif"
19
19
  ></Image>
20
- <Text style={{...styles.title, color: theme.textPrimary}}>APP 开发中</Text>
21
- <Text style={{...styles.description, color: theme.textSecondary}}>即将为您呈现应用界面</Text>
20
+ <Text style={{...styles.title, color: theme.textPrimary}}>应用开发中</Text>
21
+ <Text style={{...styles.description, color: theme.textSecondary}}>请稍候,界面即将呈现</Text>
22
22
  </View>
23
23
  </Screen>
24
24
  );
@@ -0,0 +1,9 @@
1
+ const wrapScrollViewInView = require('./rule')
2
+
3
+ const plugin = {
4
+ rules: {
5
+ 'wrap-horizontal-scrollview-inside-view': wrapScrollViewInView,
6
+ },
7
+ };
8
+
9
+ module.exports = plugin
@@ -0,0 +1,64 @@
1
+ module.exports = {
2
+ meta: {
3
+ type: 'problem',
4
+ docs: {
5
+ description: '禁止带有 horizontal: true 属性的 ScrollView 单独使用',
6
+ recommended: false,
7
+ },
8
+ schema: [],
9
+ messages: {
10
+ noSiblings: '禁止带有 props.horizontal: true 的 ScrollView 单独使用,需要在 ScrollView 外层使用一个单独的 View 组件进行包裹',
11
+ },
12
+ },
13
+ create(context) {
14
+ return {
15
+ JSXElement(node) {
16
+ const isScrollView = node.openingElement.name.name === 'ScrollView';
17
+
18
+ if (!isScrollView) {
19
+ return;
20
+ }
21
+
22
+ const hasHorizontalProp = node.openingElement.attributes.some(attr => {
23
+ if (attr.type === 'JSXAttribute' && attr.name.name === 'horizontal') {
24
+ if (!attr.value) {
25
+ return true;
26
+ }
27
+ if (
28
+ attr.value.type === 'JSXExpressionContainer' &&
29
+ attr.value.expression.value === true
30
+ ) {
31
+ return true; // horizontal={true}
32
+ }
33
+ if (attr.value.type === 'Literal' && attr.value.value === true) {
34
+ return true; // horizontal={true} 的另一种形式
35
+ }
36
+ }
37
+ return false;
38
+ });
39
+
40
+ if (!hasHorizontalProp) {
41
+ return;
42
+ }
43
+
44
+ const parent = node.parent;
45
+
46
+ if (
47
+ parent.type === 'JSXFragment' ||
48
+ parent.type === 'JSXElement'
49
+ ) {
50
+ const siblings = parent.children.filter(
51
+ child => child.type === 'JSXElement' && child !== node
52
+ );
53
+
54
+ if (siblings.length > 0) {
55
+ context.report({
56
+ node,
57
+ messageId: 'noSiblings',
58
+ });
59
+ }
60
+ }
61
+ },
62
+ };
63
+ },
64
+ }
@@ -19,7 +19,7 @@
19
19
  "esbuild": "0.27.2"
20
20
  },
21
21
  "patchedDependencies": {
22
- "expo@54.0.32": "patches/expo@54.0.32.patch"
22
+ "expo@54.0.33": "patches/expo@54.0.33.patch"
23
23
  }
24
24
  }
25
25
  }
@@ -0,0 +1,45 @@
1
+ diff --git a/src/async-require/hmr.ts b/src/async-require/hmr.ts
2
+ index 33ce50ee2950c40d2b0553b148710f1e24e44f3d..3d78cb02dd7e96ac9727a2935d8178f2c7e95982 100644
3
+ --- a/src/async-require/hmr.ts
4
+ +++ b/src/async-require/hmr.ts
5
+ @@ -216,6 +216,40 @@ const HMRClient: HMRClientNativeInterface = {
6
+
7
+ client.on('update-done', () => {
8
+ hideLoading();
9
+ + if (process.env.EXPO_PUBLIC_COZE_PROJECT_ID && typeof window !== 'undefined' && window.location) {
10
+ + if((window as any).__updateTimeoutId) {
11
+ + clearTimeout((window as any).__updateTimeoutId);
12
+ + }
13
+ + const updateDoneTime = Date.now();
14
+ + (window as any).__updateDoneTime = updateDoneTime;
15
+ + (window as any).__updateTimeoutId = setTimeout(() => {
16
+ + const lastUpdateTime = (window as any).__updateDoneTime;
17
+ + if (lastUpdateTime !== updateDoneTime) return;
18
+ + const checkServerAndReload = (retriesLeft: number) => {
19
+ + if ((window as any).__updateDoneTime !== updateDoneTime) return;
20
+ + fetch(`/favicon.ico?_t=${Date.now()}`)
21
+ + .then((response) => {
22
+ + if (response.status === 200) {
23
+ + console.warn('[HMR] Server is ready (200), reloading now.');
24
+ + window.location.reload();
25
+ + } else {
26
+ + throw new Error(`Server status: ${response.status}`);
27
+ + }
28
+ + }).catch((error) => {
29
+ + console.warn(`[HMR] Check failed (${error.message}). Retries left: ${retriesLeft}`);
30
+ + if (retriesLeft > 0) {
31
+ + setTimeout(() => {
32
+ + checkServerAndReload(retriesLeft - 1);
33
+ + }, 5000);
34
+ + } else {
35
+ + console.error('[HMR] Server unreachable after 6 attempts. Abort reload.');
36
+ + }
37
+ + });
38
+ + };
39
+ + checkServerAndReload(6);
40
+ + }, 35_000);
41
+ + }
42
+ + console.log('[HMR] Update done.');
43
+ });
44
+
45
+ client.on('error', (data: { type: string; message: string }) => {