@coze-arch/cli 0.0.1-alpha.8e1417 → 0.0.1-alpha.98e280
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.
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +6 -10
- package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +2 -2
- package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +2 -2
- package/lib/__templates__/expo/_gitignore +1 -1
- package/lib/__templates__/expo/_npmrc +4 -2
- package/lib/__templates__/expo/{client/app.json → app.json} +4 -4
- package/lib/__templates__/expo/babel.config.js +19 -0
- package/lib/__templates__/expo/client/app/(tabs)/_layout.tsx +43 -0
- package/lib/__templates__/expo/client/app/(tabs)/home.tsx +1 -0
- package/lib/__templates__/expo/client/app/(tabs)/index.tsx +7 -0
- package/lib/__templates__/expo/client/app/+not-found.tsx +79 -0
- package/lib/__templates__/expo/client/components/ThemedText.tsx +33 -0
- package/lib/__templates__/expo/client/components/ThemedView.tsx +38 -0
- package/lib/__templates__/expo/client/constants/theme.ts +850 -0
- package/lib/__templates__/expo/client/index.js +12 -0
- package/lib/__templates__/expo/client/{src/screens → screens}/home/index.tsx +1 -0
- package/lib/__templates__/expo/metro.config.js +121 -0
- package/lib/__templates__/expo/package.json +9 -4
- package/lib/__templates__/expo/pnpm-lock.yaml +0 -230
- package/lib/__templates__/expo/tsconfig.json +24 -1
- package/lib/cli.js +1 -1
- package/package.json +3 -1
- package/lib/__templates__/expo/client/metro.config.js +0 -51
- package/lib/__templates__/expo/client/package.json +0 -92
- package/lib/__templates__/expo/client/src/app/index.ts +0 -1
- package/lib/__templates__/expo/client/src/constants/theme.ts +0 -128
- package/lib/__templates__/expo/client/tsconfig.json +0 -24
- package/lib/__templates__/expo/pnpm-workspace.yaml +0 -3
- package/lib/__templates__/expo/server/package.json +0 -17
- /package/lib/__templates__/expo/client/{src/app → app}/_layout.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/fonts/SpaceMono-Regular.ttf +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/adaptive-icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/default-avatar.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/favicon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/partial-react-logo.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo@2x.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo@3x.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/splash-icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/Screen.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/SmartDateInput.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/contexts → contexts}/AuthContext.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/hooks → hooks}/useColorScheme.ts +0 -0
- /package/lib/__templates__/expo/client/{src/hooks → hooks}/useTheme.ts +0 -0
- /package/lib/__templates__/expo/client/{src/screens → screens}/home/styles.ts +0 -0
- /package/lib/__templates__/expo/client/{src/utils → utils}/index.ts +0 -0
- /package/lib/__templates__/expo/{client/eslint-formatter-simple.mjs → eslint-formatter-simple.mjs} +0 -0
- /package/lib/__templates__/expo/{client/eslint.config.mjs → eslint.config.mjs} +0 -0
- /package/lib/__templates__/expo/{server/src → src}/index.ts +0 -0
|
@@ -130,18 +130,13 @@ wait_port_connectable() {
|
|
|
130
130
|
|
|
131
131
|
start_expo() {
|
|
132
132
|
local offline="${1:-0}"
|
|
133
|
-
|
|
134
|
-
pushd ./client
|
|
135
|
-
|
|
136
133
|
if [ "$offline" = "1" ]; then
|
|
137
|
-
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" nohup npx expo start --port "$EXPO_PORT" >
|
|
134
|
+
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" nohup npx expo start --port "$EXPO_PORT" > logs/expo.log 2>&1 &
|
|
138
135
|
else
|
|
139
|
-
EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" nohup npx expo start --port "$EXPO_PORT" >
|
|
136
|
+
EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" nohup npx expo start --port "$EXPO_PORT" > logs/expo.log 2>&1 &
|
|
140
137
|
fi
|
|
141
138
|
EXPO_PID=$!
|
|
142
139
|
echo "$EXPO_PID"
|
|
143
|
-
|
|
144
|
-
popd
|
|
145
140
|
}
|
|
146
141
|
|
|
147
142
|
detect_expo_fetch_failed() {
|
|
@@ -186,8 +181,8 @@ ensure_port EXPO_PORT "$EXPO_PORT"
|
|
|
186
181
|
|
|
187
182
|
# ==================== 启动 Server 服务 ====================
|
|
188
183
|
write_log "INFO" "==================== 启动 server 服务 ===================="
|
|
189
|
-
write_log "INFO" "正在执行:npm run
|
|
190
|
-
PORT="$SERVER_PORT" nohup npm run
|
|
184
|
+
write_log "INFO" "正在执行:npm run server"
|
|
185
|
+
PORT="$SERVER_PORT" nohup npm run server > logs/app.log 2>&1 &
|
|
191
186
|
SERVER_PID=$!
|
|
192
187
|
if [ -z "${SERVER_PID}" ]; then
|
|
193
188
|
write_log "ERROR" "无法获取 server 后台进程 PID"
|
|
@@ -195,7 +190,8 @@ fi
|
|
|
195
190
|
write_log "INFO" "server 服务已启动,进程 ID:${SERVER_PID:-unknown}"
|
|
196
191
|
|
|
197
192
|
write_log "INFO" "==================== 启动 Expo 项目 ===================="
|
|
198
|
-
write_log "INFO" "
|
|
193
|
+
write_log "INFO" "正在执行:npx expo start --port ${EXPO_PORT}"
|
|
194
|
+
write_log "INFO" "开始启动 Expo 服务"
|
|
199
195
|
EXPO_PID=$(start_expo 0)
|
|
200
196
|
if detect_expo_fetch_failed 8; then
|
|
201
197
|
write_log "WARN" "Expo 启动检测到网络错误:TypeError: fetch failed,启用离线模式重试"
|
|
@@ -40,8 +40,8 @@ fi
|
|
|
40
40
|
info "==================== 依赖安装完成!====================\n"
|
|
41
41
|
|
|
42
42
|
info "==================== dist打包 ===================="
|
|
43
|
-
info "开始执行:
|
|
44
|
-
(cd "$ROOT_DIR" &&
|
|
43
|
+
info "开始执行:pnpm run server:build"
|
|
44
|
+
(cd "$ROOT_DIR" && pnpm run server:build) || error "dist打包失败"
|
|
45
45
|
info "==================== dist打包完成!====================\n"
|
|
46
46
|
|
|
47
47
|
info "下一步:执行 ./prod_run.sh 启动服务"
|
|
@@ -30,6 +30,6 @@ check_command() {
|
|
|
30
30
|
check_command "pnpm"
|
|
31
31
|
check_command "npm"
|
|
32
32
|
|
|
33
|
-
info "开始执行:
|
|
34
|
-
(cd "$ROOT_DIR" && PORT="$PORT"
|
|
33
|
+
info "开始执行:pnpm run server:prod"
|
|
34
|
+
(cd "$ROOT_DIR" && PORT="$PORT" pnpm run server:prod) || error "服务启动失败"
|
|
35
35
|
info "服务启动完成!\n"
|
|
@@ -8,13 +8,15 @@ network-concurrency=16
|
|
|
8
8
|
fetch-retries=3
|
|
9
9
|
fetch-timeout=60000
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# 严格使用 peer dependencies
|
|
12
12
|
strict-peer-dependencies=false
|
|
13
|
+
|
|
14
|
+
# 自动生成 lockfile
|
|
13
15
|
auto-install-peers=true
|
|
14
16
|
|
|
15
17
|
# lockfile 配置
|
|
16
18
|
lockfile=true
|
|
17
19
|
prefer-frozen-lockfile=true
|
|
18
20
|
|
|
19
|
-
#
|
|
21
|
+
# 如果 lockfile 存在但过期,更新而不是失败
|
|
20
22
|
resolution-mode=highest
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"slug": "${slug}",
|
|
5
5
|
"version": "1.0.0",
|
|
6
6
|
"orientation": "portrait",
|
|
7
|
-
"icon": "./assets/images/icon.png",
|
|
7
|
+
"icon": "./client/assets/images/icon.png",
|
|
8
8
|
"scheme": "myapp",
|
|
9
9
|
"userInterfaceStyle": "automatic",
|
|
10
10
|
"newArchEnabled": true,
|
|
@@ -13,21 +13,21 @@
|
|
|
13
13
|
},
|
|
14
14
|
"android": {
|
|
15
15
|
"adaptiveIcon": {
|
|
16
|
-
"foregroundImage": "./assets/images/adaptive-icon.png",
|
|
16
|
+
"foregroundImage": "./client/assets/images/adaptive-icon.png",
|
|
17
17
|
"backgroundColor": "#ffffff"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"web": {
|
|
21
21
|
"bundler": "metro",
|
|
22
22
|
"output": "single",
|
|
23
|
-
"favicon": "./assets/images/favicon.png"
|
|
23
|
+
"favicon": "./client/assets/images/favicon.png"
|
|
24
24
|
},
|
|
25
25
|
"plugins": [
|
|
26
26
|
"expo-router",
|
|
27
27
|
[
|
|
28
28
|
"expo-splash-screen",
|
|
29
29
|
{
|
|
30
|
-
"image": "./assets/images/splash-icon.png",
|
|
30
|
+
"image": "./client/assets/images/splash-icon.png",
|
|
31
31
|
"imageWidth": 200,
|
|
32
32
|
"resizeMode": "contain",
|
|
33
33
|
"backgroundColor": "#ffffff"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = function (api) {
|
|
2
|
+
api.cache(true);
|
|
3
|
+
return {
|
|
4
|
+
presets: ["babel-preset-expo"],
|
|
5
|
+
plugins: [
|
|
6
|
+
[
|
|
7
|
+
"module-resolver",
|
|
8
|
+
{
|
|
9
|
+
root: ["./"],
|
|
10
|
+
alias: {
|
|
11
|
+
"@": "./client",
|
|
12
|
+
},
|
|
13
|
+
extensions: [".ios.js", ".android.js", ".js", ".ts", ".tsx", ".json"],
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
"react-native-reanimated/plugin",
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Tabs } from 'expo-router';
|
|
2
|
+
import { FontAwesome6 } from '@expo/vector-icons';
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
4
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
5
|
+
|
|
6
|
+
export default function TabLayout() {
|
|
7
|
+
const insets = useSafeAreaInsets();
|
|
8
|
+
const { theme } = useTheme();
|
|
9
|
+
const tabBarHeight = 56 + Math.max(insets.bottom, 8);
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<Tabs
|
|
13
|
+
backBehavior='history'
|
|
14
|
+
screenOptions={{
|
|
15
|
+
headerShown: false,
|
|
16
|
+
tabBarActiveTintColor: theme.tabIconSelected,
|
|
17
|
+
tabBarInactiveTintColor: theme.tabIconDefault,
|
|
18
|
+
tabBarStyle: {
|
|
19
|
+
backgroundColor: theme.backgroundRoot,
|
|
20
|
+
borderTopColor: theme.backgroundSecondary,
|
|
21
|
+
borderTopWidth: 1,
|
|
22
|
+
height: tabBarHeight,
|
|
23
|
+
paddingBottom: Math.max(insets.bottom, 8),
|
|
24
|
+
paddingTop: 6,
|
|
25
|
+
},
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
<Tabs.Screen
|
|
29
|
+
name='index'
|
|
30
|
+
options={{ href: null }}
|
|
31
|
+
/>
|
|
32
|
+
<Tabs.Screen
|
|
33
|
+
name='home'
|
|
34
|
+
options={{
|
|
35
|
+
title: '首页',
|
|
36
|
+
tabBarIcon: ({ color }) => (
|
|
37
|
+
<FontAwesome6 name='house' size={20} color={color} />
|
|
38
|
+
),
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
</Tabs>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "@/screens/home";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useRouter } from 'expo-router';
|
|
2
|
+
import { StyleSheet, View, Text, Pressable, Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export default function NotFoundScreen() {
|
|
5
|
+
const router = useRouter();
|
|
6
|
+
|
|
7
|
+
const goBack = () => {
|
|
8
|
+
if (router.canGoBack()) {
|
|
9
|
+
router.back();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<View style={styles.container}>
|
|
15
|
+
<Text style={styles.heading}>404</Text>
|
|
16
|
+
<Text style={styles.textStyle}>页面未找到</Text>
|
|
17
|
+
<Text style={styles.subTextStyle}>
|
|
18
|
+
抱歉!您访问的页面不存在,当前页面功能待完善。
|
|
19
|
+
</Text>
|
|
20
|
+
<Pressable onPress={goBack} style={styles.button}>
|
|
21
|
+
<Text style={styles.buttonText}>返回上一页</Text>
|
|
22
|
+
</Pressable>
|
|
23
|
+
</View>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const styles = StyleSheet.create({
|
|
28
|
+
container: {
|
|
29
|
+
flex: 1,
|
|
30
|
+
alignItems: 'center',
|
|
31
|
+
justifyContent: 'center',
|
|
32
|
+
backgroundColor: '#f3f5ff',
|
|
33
|
+
padding: 16,
|
|
34
|
+
},
|
|
35
|
+
heading: {
|
|
36
|
+
fontSize: 120,
|
|
37
|
+
fontWeight: '900',
|
|
38
|
+
color: '#4a5568',
|
|
39
|
+
textShadowColor: 'rgba(0, 0, 0, 0.05)',
|
|
40
|
+
textShadowOffset: { width: 0, height: 4 },
|
|
41
|
+
textShadowRadius: 8,
|
|
42
|
+
},
|
|
43
|
+
textStyle: {
|
|
44
|
+
fontSize: 24,
|
|
45
|
+
fontWeight: '500',
|
|
46
|
+
marginTop: -16,
|
|
47
|
+
marginBottom: 16,
|
|
48
|
+
color: '#4a5568',
|
|
49
|
+
},
|
|
50
|
+
subTextStyle: {
|
|
51
|
+
fontSize: 16,
|
|
52
|
+
color: '#718096',
|
|
53
|
+
marginBottom: 32,
|
|
54
|
+
maxWidth: 400,
|
|
55
|
+
textAlign: 'center',
|
|
56
|
+
},
|
|
57
|
+
button: {
|
|
58
|
+
paddingVertical: 12,
|
|
59
|
+
paddingHorizontal: 24,
|
|
60
|
+
backgroundColor: '#6366f1',
|
|
61
|
+
borderRadius: 9999,
|
|
62
|
+
...Platform.select({
|
|
63
|
+
ios: {
|
|
64
|
+
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
|
65
|
+
shadowOffset: { width: 0, height: 10 },
|
|
66
|
+
shadowOpacity: 1,
|
|
67
|
+
shadowRadius: 15,
|
|
68
|
+
},
|
|
69
|
+
android: {
|
|
70
|
+
elevation: 5,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
buttonText: {
|
|
75
|
+
fontSize: 16,
|
|
76
|
+
fontWeight: '600',
|
|
77
|
+
color: '#ffffff',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text, TextProps, TextStyle } from 'react-native';
|
|
3
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
4
|
+
import { Typography } from '@/constants/theme';
|
|
5
|
+
|
|
6
|
+
type TypographyVariant = keyof typeof Typography;
|
|
7
|
+
|
|
8
|
+
interface ThemedTextProps extends TextProps {
|
|
9
|
+
variant?: TypographyVariant;
|
|
10
|
+
color?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ThemedText({
|
|
14
|
+
variant = 'body',
|
|
15
|
+
color,
|
|
16
|
+
style,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: ThemedTextProps) {
|
|
20
|
+
const { theme } = useTheme();
|
|
21
|
+
const typographyStyle = Typography[variant];
|
|
22
|
+
|
|
23
|
+
const textStyle: TextStyle = {
|
|
24
|
+
...typographyStyle,
|
|
25
|
+
color: color ?? theme.textPrimary,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Text style={[textStyle, style]} {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</Text>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, ViewProps, ViewStyle } from 'react-native';
|
|
3
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
4
|
+
|
|
5
|
+
type BackgroundLevel = 'root' | 'default' | 'secondary' | 'tertiary';
|
|
6
|
+
|
|
7
|
+
interface ThemedViewProps extends ViewProps {
|
|
8
|
+
level?: BackgroundLevel;
|
|
9
|
+
backgroundColor?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const backgroundMap: Record<BackgroundLevel, string> = {
|
|
13
|
+
root: 'backgroundRoot',
|
|
14
|
+
default: 'backgroundDefault',
|
|
15
|
+
secondary: 'backgroundSecondary',
|
|
16
|
+
tertiary: 'backgroundTertiary',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function ThemedView({
|
|
20
|
+
level = 'root',
|
|
21
|
+
backgroundColor,
|
|
22
|
+
style,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: ThemedViewProps) {
|
|
26
|
+
const { theme } = useTheme();
|
|
27
|
+
const bgColor = backgroundColor ?? (theme as any)[backgroundMap[level]];
|
|
28
|
+
|
|
29
|
+
const viewStyle: ViewStyle = {
|
|
30
|
+
backgroundColor: bgColor,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<View style={[viewStyle, style]} {...props}>
|
|
35
|
+
{children}
|
|
36
|
+
</View>
|
|
37
|
+
);
|
|
38
|
+
}
|