Skip to content

Commit 7293555

Browse files
fix(cli): update uniwind and heroui-native deps
1 parent 979a04a commit 7293555

File tree

6 files changed

+182
-134
lines changed

6 files changed

+182
-134
lines changed

apps/cli/src/helpers/core/post-installation.ts

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ export async function displayPostInstallInstructions(
5959
? getLintingInstructions(runCmd)
6060
: "";
6161
const nativeInstructions =
62-
frontend?.includes("native-bare") ||
63-
frontend?.includes("native-uniwind") ||
64-
frontend?.includes("native-unistyles")
62+
(frontend?.includes("native-bare") ||
63+
frontend?.includes("native-uniwind") ||
64+
frontend?.includes("native-unistyles")) &&
65+
backend !== "none"
6566
? getNativeInstructions(isConvex, isBackendSelf, frontend || [])
6667
: "";
6768
const pwaInstructions =
@@ -156,34 +157,43 @@ export async function displayPostInstallInstructions(
156157
}
157158
}
158159

159-
output += `${pc.bold("Your project will be available at:")}\n`;
160+
const hasStandaloneBackend = backend !== "none";
161+
const hasAnyService =
162+
hasWeb ||
163+
hasStandaloneBackend ||
164+
addons?.includes("starlight") ||
165+
addons?.includes("fumadocs");
160166

161-
if (hasWeb) {
162-
output += `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n`;
163-
} else if (!hasNative && !addons?.includes("starlight")) {
164-
output += `${pc.yellow(
165-
"NOTE:",
166-
)} You are creating a backend-only app\n (no frontend selected)\n`;
167-
}
167+
if (hasAnyService) {
168+
output += `${pc.bold("Your project will be available at:")}\n`;
168169

169-
if (!isConvex && !isBackendSelf) {
170-
output += `${pc.cyan("•")} Backend API: http://localhost:3000\n`;
170+
if (hasWeb) {
171+
output += `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n`;
172+
} else if (!hasNative && !addons?.includes("starlight")) {
173+
output += `${pc.yellow(
174+
"NOTE:",
175+
)} You are creating a backend-only app\n (no frontend selected)\n`;
176+
}
177+
178+
if (!isConvex && !isBackendSelf && hasStandaloneBackend) {
179+
output += `${pc.cyan("•")} Backend API: http://localhost:3000\n`;
171180

172-
if (api === "orpc") {
173-
output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/api-reference\n`;
181+
if (api === "orpc") {
182+
output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/api-reference\n`;
183+
}
174184
}
175-
}
176185

177-
if (isBackendSelf && api === "orpc") {
178-
output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:${webPort}/api/rpc/api-reference\n`;
179-
}
186+
if (isBackendSelf && api === "orpc") {
187+
output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:${webPort}/api/rpc/api-reference\n`;
188+
}
180189

181-
if (addons?.includes("starlight")) {
182-
output += `${pc.cyan("•")} Docs: http://localhost:4321\n`;
183-
}
190+
if (addons?.includes("starlight")) {
191+
output += `${pc.cyan("•")} Docs: http://localhost:4321\n`;
192+
}
184193

185-
if (addons?.includes("fumadocs")) {
186-
output += `${pc.cyan("•")} Fumadocs: http://localhost:4000\n`;
194+
if (addons?.includes("fumadocs")) {
195+
output += `${pc.cyan("•")} Fumadocs: http://localhost:4000\n`;
196+
}
187197
}
188198

189199
if (nativeInstructions) output += `\n${nativeInstructions.trim()}\n`;

apps/cli/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export const DirectoryConflictSchema = z
131131
export type DirectoryConflict = z.infer<typeof DirectoryConflictSchema>;
132132

133133
export const TemplateSchema = z
134-
.enum(["mern", "pern", "t3", "none"])
134+
.enum(["mern", "pern", "t3", "uniwind", "none"])
135135
.describe("Predefined project template");
136136
export type Template = z.infer<typeof TemplateSchema>;
137137

apps/cli/src/utils/templates.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ export const TEMPLATE_PRESETS: Record<Template, CreateInput | null> = {
4646
webDeploy: "none",
4747
serverDeploy: "none",
4848
},
49+
uniwind: {
50+
database: "none",
51+
orm: "none",
52+
backend: "none",
53+
runtime: "none",
54+
frontend: ["native-uniwind"],
55+
api: "none",
56+
auth: "none",
57+
payments: "none",
58+
addons: ["none"],
59+
examples: ["none"],
60+
dbSetup: "none",
61+
webDeploy: "none",
62+
serverDeploy: "none",
63+
},
4964
none: null,
5065
};
5166

@@ -67,6 +82,7 @@ export function getTemplateDescription(template: Template) {
6782
mern: "MongoDB + Express + React + Node.js - Classic MERN stack",
6883
pern: "PostgreSQL + Express + React + Node.js - Popular PERN stack",
6984
t3: "T3 Stack - Next.js + tRPC + Prisma + PostgreSQL + Better Auth",
85+
uniwind: "Expo + Uniwind native app with no backend services",
7086
none: "No template - Full customization",
7187
};
7288

apps/cli/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs

Lines changed: 98 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -24,128 +24,124 @@ import { SignUp } from "@/components/sign-up";
2424
import { useQuery } from "convex/react";
2525
import { api } from "@{{projectName}}/backend/convex/_generated/api";
2626
{{/if}}
27+
{{#unless (eq backend "none")}}
2728
import { Ionicons } from "@expo/vector-icons";
29+
{{/unless}}
2830
import { Card, Chip, useThemeColor } from "heroui-native";
2931

3032
export default function Home() {
3133
{{#if (eq api "orpc")}}
32-
const healthCheck = useQuery(orpc.healthCheck.queryOptions());
34+
const healthCheck = useQuery(orpc.healthCheck.queryOptions());
3335
{{/if}}
3436
{{#if (eq api "trpc")}}
35-
const healthCheck = useQuery(trpc.healthCheck.queryOptions());
37+
const healthCheck = useQuery(trpc.healthCheck.queryOptions());
3638
{{/if}}
3739
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
38-
const { user } = useUser();
39-
const healthCheck = useQuery(api.healthCheck.get);
40-
const privateData = useQuery(api.privateData.get);
40+
const { user } = useUser();
41+
const healthCheck = useQuery(api.healthCheck.get);
42+
const privateData = useQuery(api.privateData.get);
4143
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
42-
const healthCheck = useQuery(api.healthCheck.get);
43-
const { isAuthenticated } = useConvexAuth();
44-
const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : "skip");
44+
const healthCheck = useQuery(api.healthCheck.get);
45+
const { isAuthenticated } = useConvexAuth();
46+
const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : "skip");
4547
{{else if (eq backend "convex")}}
46-
const healthCheck = useQuery(api.healthCheck.get);
48+
const healthCheck = useQuery(api.healthCheck.get);
4749
{{/if}}
48-
const mutedColor = useThemeColor("muted");
49-
const successColor = useThemeColor("success");
50-
const dangerColor = useThemeColor("danger");
50+
{{#unless (eq backend "none")}}
51+
const mutedColor = useThemeColor("muted");
52+
const successColor = useThemeColor("success");
53+
const dangerColor = useThemeColor("danger");
5154

5255
{{#if (eq backend "convex")}}
53-
const isConnected = healthCheck === "OK";
54-
const isLoading = healthCheck === undefined;
56+
const isConnected = healthCheck === "OK";
57+
const isLoading = healthCheck === undefined;
5558
{{else}}
5659
{{#unless (eq api "none")}}
57-
const isConnected = healthCheck?.data === "OK";
58-
const isLoading = healthCheck?.isLoading;
60+
const isConnected = healthCheck?.data === "OK";
61+
const isLoading = healthCheck?.isLoading;
5962
{{/unless}}
6063
{{/if}}
64+
{{/unless}}
6165

62-
return (
63-
<Container className="p-6">
64-
<View className="py-4 mb-6">
65-
<Text className="text-4xl font-bold text-foreground mb-2">
66-
BETTER T STACK
67-
</Text>
68-
</View>
69-
70-
{{#unless (and (eq backend "convex") (eq auth "better-auth"))}}
71-
<Card variant="secondary" className="p-6">
72-
<View className="flex-row items-center justify-between mb-4">
73-
<Card.Title>System Status</Card.Title>
74-
<Chip
75-
variant="secondary"
76-
color={isConnected ? "success" : "danger"}
77-
size="sm"
78-
>
79-
<Chip.Label>
80-
{isConnected ? "LIVE" : "OFFLINE"}
81-
</Chip.Label>
82-
</Chip>
83-
</View>
84-
<Card className="p-4">
85-
<View className="flex-row items-center">
86-
<View
87-
className={`w-3 h-3 rounded-full mr-3 ${
88-
isConnected ? "bg-success" : "bg-muted"
89-
}`}
90-
/>
91-
<View className="flex-1">
92-
<Text className="text-foreground font-medium mb-1">
93-
{{#if (eq backend "convex")}}
94-
Convex Backend
95-
{{else}}
96-
{{#unless (eq api "none")}}
97-
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
98-
{{/unless}}
99-
{{/if}}
100-
</Text>
101-
<Card.Description>
102-
{isLoading
103-
? "Checking connection..."
104-
: isConnected
105-
? "Connected to API"
106-
: "API Disconnected"}
107-
</Card.Description>
108-
</View>
109-
{isLoading && (
110-
<Ionicons name="hourglass-outline" size={20} color={mutedColor} />
111-
)}
112-
{!isLoading && isConnected && (
113-
<Ionicons name="checkmark-circle" size={20} color={successColor} />
114-
)}
115-
{!isLoading && !isConnected && (
116-
<Ionicons name="close-circle" size={20} color={dangerColor} />
117-
)}
118-
</View>
119-
</Card>
120-
</Card>
121-
{{/unless}}
66+
return (
67+
<Container className="p-6">
68+
<View className="py-4 mb-6">
69+
<Text className="text-4xl font-bold text-foreground mb-2">
70+
BETTER T STACK
71+
</Text>
72+
</View>
12273

123-
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
124-
<Authenticated>
125-
<Card variant="secondary" className="mt-6 p-4">
126-
<Text className="text-foreground text-base mb-2">
127-
Hello {user?.emailAddresses[0].emailAddress}
128-
</Text>
129-
<Text className="text-muted text-sm mb-4">
130-
Private Data: {privateData?.message}
74+
{{#unless (or (eq backend "none") (and (eq backend "convex") (eq auth "better-auth")))}}
75+
<Card variant="secondary" className="p-6">
76+
<View className="flex-row items-center justify-between mb-4">
77+
<Card.Title>System Status</Card.Title>
78+
<Chip variant="secondary" color={isConnected ? "success" : "danger" } size="sm">
79+
<Chip.Label>
80+
{isConnected ? "LIVE" : "OFFLINE"}
81+
</Chip.Label>
82+
</Chip>
83+
</View>
84+
<Card className="p-4">
85+
<View className="flex-row items-center">
86+
<View className={`w-3 h-3 rounded-full mr-3 ${ isConnected ? "bg-success" : "bg-muted" }`} />
87+
<View className="flex-1">
88+
<Text className="text-foreground font-medium mb-1">
89+
{{#if (eq backend "convex")}}
90+
Convex Backend
91+
{{else}}
92+
{{#unless (eq api "none")}}
93+
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
94+
{{/unless}}
95+
{{/if}}
13196
</Text>
132-
<SignOutButton />
133-
</Card>
134-
</Authenticated>
135-
<Unauthenticated>
136-
<View className="mt-6 gap-4">
137-
<Link href="/(auth)/sign-in" asChild>
138-
<Text className="text-primary font-semibold">Sign in</Text>
139-
</Link>
140-
<Link href="/(auth)/sign-up" asChild>
141-
<Text className="text-primary font-semibold">Sign up</Text>
142-
</Link>
97+
<Card.Description>
98+
{isLoading
99+
? "Checking connection..."
100+
: isConnected
101+
? "Connected to API"
102+
: "API Disconnected"}
103+
</Card.Description>
143104
</View>
144-
</Unauthenticated>
145-
<AuthLoading>
146-
<Text className="text-muted">Loading...</Text>
147-
</AuthLoading>
148-
{{/if}}
149-
</Container>
150-
);
105+
{isLoading && (
106+
<Ionicons name="hourglass-outline" size={20} color={mutedColor} />
107+
)}
108+
{!isLoading && isConnected && (
109+
<Ionicons name="checkmark-circle" size={20} color={successColor} />
110+
)}
111+
{!isLoading && !isConnected && (
112+
<Ionicons name="close-circle" size={20} color={dangerColor} />
113+
)}
114+
</View>
115+
</Card>
116+
</Card>
117+
{{/unless}}
118+
119+
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
120+
<Authenticated>
121+
<Card variant="secondary" className="mt-6 p-4">
122+
<Text className="text-foreground text-base mb-2">
123+
Hello {user?.emailAddresses[0].emailAddress}
124+
</Text>
125+
<Text className="text-muted text-sm mb-4">
126+
Private Data: {privateData?.message}
127+
</Text>
128+
<SignOutButton />
129+
</Card>
130+
</Authenticated>
131+
<Unauthenticated>
132+
<View className="mt-6 gap-4">
133+
<Link href="/(auth)/sign-in" asChild>
134+
<Text className="text-primary font-semibold">Sign in</Text>
135+
</Link>
136+
<Link href="/(auth)/sign-up" asChild>
137+
<Text className="text-primary font-semibold">Sign up</Text>
138+
</Link>
139+
</View>
140+
</Unauthenticated>
141+
<AuthLoading>
142+
<Text className="text-muted">Loading...</Text>
143+
</AuthLoading>
144+
{{/if}}
145+
</Container>
146+
);
151147
}

apps/cli/templates/frontend/native/uniwind/package.json.hbs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"dependencies": {
1414
"@expo/metro-runtime": "~6.1.2",
1515
"@expo/vector-icons": "^15.0.3",
16-
"@gorhom/bottom-sheet": "^5",
16+
"@gorhom/bottom-sheet": "^5.2.6",
1717
"@react-navigation/drawer": "^7.3.9",
1818
"@react-navigation/elements": "^2.8.1",
1919
{{#if (includes examples "ai")}}
@@ -29,22 +29,22 @@
2929
"expo-router": "~6.0.14",
3030
"expo-secure-store": "~15.0.7",
3131
"expo-status-bar": "~3.0.8",
32-
"heroui-native": "^1.0.0-beta.1",
32+
"heroui-native": "1.0.0-beta.3",
3333
"react": "19.1.0",
3434
"react-dom": "19.1.0",
3535
"react-native": "0.81.5",
3636
"react-native-gesture-handler": "~2.28.0",
3737
"react-native-keyboard-controller": "1.18.5",
38-
"react-native-reanimated": "~4.1.0",
38+
"react-native-reanimated": "~4.1.5",
3939
"react-native-safe-area-context": "5.6.0",
4040
"react-native-screens": "~4.16.0",
4141
"react-native-svg": "15.12.1",
4242
"react-native-web": "^0.21.0",
4343
"react-native-worklets": "0.5.1",
44-
"tailwind-merge": "^3.3.1",
45-
"tailwind-variants": "^3.1.0",
46-
"tailwindcss": "~4.1.16",
47-
"uniwind": "^1.0.0"
44+
"tailwind-merge": "^3.4.0",
45+
"tailwind-variants": "3.1.1",
46+
"tailwindcss": "~4.1.17",
47+
"uniwind": "^1.0.4"
4848
},
4949
"devDependencies": {
5050
"@types/node": "^24.10.0",

0 commit comments

Comments
 (0)