create-your-stack 0.0.1
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/README.md +15 -0
- package/bin/create-your-stack +235 -0
- package/index.ts +1 -0
- package/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# create-your-stack
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun run index.ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This project was created using `bun init` in bun v1.3.0. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import "../index.ts";
|
|
3
|
+
#!/usr/bin/env bash
|
|
4
|
+
set -Eeuo pipefail
|
|
5
|
+
|
|
6
|
+
trap 'echo "โ Error on line $LINENO. Exiting."; exit 1' ERR
|
|
7
|
+
|
|
8
|
+
DRY_RUN=false
|
|
9
|
+
USE_CLERK=true
|
|
10
|
+
USE_CONVEX=true
|
|
11
|
+
USE_UNIWIND=true
|
|
12
|
+
|
|
13
|
+
PROJECT_NAME=""
|
|
14
|
+
|
|
15
|
+
while [[ $# -gt 0 ]]; do
|
|
16
|
+
case "$1" in
|
|
17
|
+
--dry-run)
|
|
18
|
+
DRY_RUN=true
|
|
19
|
+
;;
|
|
20
|
+
--no-clerk)
|
|
21
|
+
USE_CLERK=false
|
|
22
|
+
;;
|
|
23
|
+
--no-convex)
|
|
24
|
+
USE_CONVEX=false
|
|
25
|
+
;;
|
|
26
|
+
--no-uniwind)
|
|
27
|
+
USE_UNIWIND=false
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
if [[ -z "$PROJECT_NAME" ]]; then
|
|
31
|
+
PROJECT_NAME="$1"
|
|
32
|
+
else
|
|
33
|
+
echo "Unknown option: $1"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
;;
|
|
37
|
+
esac
|
|
38
|
+
shift
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
if [[ -z "$PROJECT_NAME" ]]; then
|
|
42
|
+
echo "โ Please provide a project name."
|
|
43
|
+
echo "Usage: create-your-stack my-new-app [--dry-run] [--no-clerk] [--no-convex] [--no-uniwind]"
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
run() {
|
|
48
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
49
|
+
echo "[DRY RUN] $*"
|
|
50
|
+
else
|
|
51
|
+
eval "$@"
|
|
52
|
+
fi
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
echo "๐ Initializing new Expo project: $PROJECT_NAME with Bun..."
|
|
56
|
+
|
|
57
|
+
if [[ ! -d "$PROJECT_NAME" ]]; then
|
|
58
|
+
run "bunx create-expo-app@latest \"$PROJECT_NAME\""
|
|
59
|
+
else
|
|
60
|
+
echo "โ ๏ธ Project already exists. Skipping Expo initialization."
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
cd "$PROJECT_NAME"
|
|
64
|
+
|
|
65
|
+
echo "๐ฆ Installing Core Dependencies..."
|
|
66
|
+
|
|
67
|
+
run "bun add expo-router expo-constants"
|
|
68
|
+
|
|
69
|
+
if [[ "$USE_CLERK" == "true" ]]; then
|
|
70
|
+
run "bun add @clerk/clerk-expo expo-secure-store"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [[ "$USE_CONVEX" == "true" ]]; then
|
|
74
|
+
run "bun add convex"
|
|
75
|
+
run "bun add -D convex-helpers"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
run "bun add zustand react-native-mmkv"
|
|
79
|
+
|
|
80
|
+
if [[ "$USE_UNIWIND" == "true" ]]; then
|
|
81
|
+
run "bun add uniwind tailwindcss clsx tailwind-merge lucide-react-native react-native-reanimated @gorhom/bottom-sheet react-native-gesture-handler reanimated-color-picker"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
run "bun add date-fns date-fns-tz zod react-hook-form @hookform/resolvers"
|
|
85
|
+
|
|
86
|
+
echo "๐ Creating directories..."
|
|
87
|
+
run "mkdir -p lib stores components providers"
|
|
88
|
+
|
|
89
|
+
echo "๐จ Setting up global.css..."
|
|
90
|
+
run "cat <<'EOT' > global.css
|
|
91
|
+
@import 'tailwindcss';
|
|
92
|
+
@import 'uniwind';
|
|
93
|
+
|
|
94
|
+
@layer theme {
|
|
95
|
+
:root {
|
|
96
|
+
--color-background: oklch(100% 0 0);
|
|
97
|
+
--color-foreground: oklch(0% 0 0);
|
|
98
|
+
--color-primary: oklch(48.611% 0.27832 286.066);
|
|
99
|
+
--color-card: oklch(100% 0 0);
|
|
100
|
+
--color-border: oklch(92.83% 0.01 262.3);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
EOT"
|
|
104
|
+
|
|
105
|
+
echo "๐ Creating utility files..."
|
|
106
|
+
|
|
107
|
+
cat <<'EOT' > lib/cn.ts
|
|
108
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
109
|
+
import { twMerge } from 'tailwind-merge';
|
|
110
|
+
|
|
111
|
+
export function cn(...inputs: ClassValue[]) {
|
|
112
|
+
return twMerge(clsx(inputs));
|
|
113
|
+
}
|
|
114
|
+
EOT
|
|
115
|
+
|
|
116
|
+
cat <<'EOT' > lib/clerk.ts
|
|
117
|
+
import { ClerkProvider, useAuth } from '@clerk/clerk-expo';
|
|
118
|
+
import { Platform } from 'react-native';
|
|
119
|
+
import { ConvexProviderWithClerk } from 'convex/react-clerk';
|
|
120
|
+
import { ConvexReactClient } from 'convex/react';
|
|
121
|
+
import * as SecureStore from 'expo-secure-store';
|
|
122
|
+
import Constants from 'expo-constants';
|
|
123
|
+
|
|
124
|
+
const convexUrl = __DEV__
|
|
125
|
+
? process.env.EXPO_PUBLIC_CONVEX_URL
|
|
126
|
+
: Constants.expoConfig?.extra?.convexUrlProd || process.env.EXPO_PUBLIC_CONVEX_URL_PROD
|
|
127
|
+
|
|
128
|
+
const publishableKey = __DEV__
|
|
129
|
+
? process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY
|
|
130
|
+
: Constants.expoConfig?.extra?.clerkPublishableLive || process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_LIVE
|
|
131
|
+
|
|
132
|
+
if (!publishableKey) {
|
|
133
|
+
throw new Error("Missing Clerk publishable key");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!convexUrl) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
'Missing Convex URL. Please set EXPO_PUBLIC_CONVEX_URL_PROD or EXPO_PUBLIC_CONVEX_URL in your .env'
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const convex = new ConvexReactClient(convexUrl as string, {
|
|
143
|
+
unsavedChangesWarning: false,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Token cache for Clerk authentication persistence
|
|
147
|
+
const tokenCache = Platform.OS === 'web' ? {
|
|
148
|
+
async getToken(key: string) {
|
|
149
|
+
try {
|
|
150
|
+
return localStorage.getItem(key);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
console.error('Error getting token:', err);
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
async saveToken(key: string, value: string) {
|
|
157
|
+
try {
|
|
158
|
+
localStorage.setItem(key, value);
|
|
159
|
+
} catch (err) {
|
|
160
|
+
console.error('Error saving token:', err);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
} : {
|
|
165
|
+
async getToken(key: string) {
|
|
166
|
+
try {
|
|
167
|
+
return SecureStore.getItemAsync(key);
|
|
168
|
+
} catch (err) {
|
|
169
|
+
console.error('Error getting token:', err);
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
async saveToken(key: string, value: string) {
|
|
174
|
+
try {
|
|
175
|
+
return SecureStore.setItemAsync(key, value);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error('Error saving token:', err);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export { ClerkProvider, useAuth, ConvexProviderWithClerk, convex, publishableKey, tokenCache };
|
|
184
|
+
EOT
|
|
185
|
+
|
|
186
|
+
echo "โ๏ธ Creating metro.config.js..."
|
|
187
|
+
cat <<'EOT' > metro.config.js
|
|
188
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
189
|
+
const { withUniwindConfig } = require("uniwind/metro");
|
|
190
|
+
|
|
191
|
+
const config = getDefaultConfig(__dirname);
|
|
192
|
+
module.exports = withUniwindConfig(config, { input: "./global.css" });
|
|
193
|
+
EOT
|
|
194
|
+
|
|
195
|
+
echo "๐ Injecting global.css into _layout..."
|
|
196
|
+
for layout in app/_layout.tsx app/_layout.js; do
|
|
197
|
+
if [[ -f "$layout" ]] && ! grep -q "global.css" "$layout"; then
|
|
198
|
+
tmp="${layout}.tmp"
|
|
199
|
+
echo "import '../global.css';" > "$tmp"
|
|
200
|
+
cat "$layout" >> "$tmp"
|
|
201
|
+
mv "$tmp" "$layout"
|
|
202
|
+
fi
|
|
203
|
+
done
|
|
204
|
+
|
|
205
|
+
echo "๐งช Creating .env.local..."
|
|
206
|
+
run "cat <<'EOT' > .env.local
|
|
207
|
+
CONVEX_DEPLOYMENT=
|
|
208
|
+
CONVEX_PROD_DEPLOYMENT=
|
|
209
|
+
|
|
210
|
+
EXPO_PUBLIC_CONVEX_URL=
|
|
211
|
+
EXPO_PUBLIC_CONVEX_URL_PROD=
|
|
212
|
+
|
|
213
|
+
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
|
214
|
+
EXPO_PUBLIC_CLERK_PUBLISHABLE_LIVE=
|
|
215
|
+
EXPO_PUBLIC_CLERK_JWT_ISSUER_DOMAIN=
|
|
216
|
+
|
|
217
|
+
EXPO_PUBLIC_APP_URL=http://localhost:8081
|
|
218
|
+
EXPO_PUBLIC_DEPLOY_URL_PROD=
|
|
219
|
+
EXPO_PUBLIC_DEPLOY_URL_DEV=
|
|
220
|
+
EOT"
|
|
221
|
+
|
|
222
|
+
if [[ "$USE_CONVEX" == "true" ]]; then
|
|
223
|
+
echo "๐ ๏ธ Initializing Convex (once)..."
|
|
224
|
+
if [[ ! -d ".convex" ]]; then
|
|
225
|
+
run "bunx convex dev --once"
|
|
226
|
+
else
|
|
227
|
+
echo "โ ๏ธ Convex already initialized. Skipping."
|
|
228
|
+
fi
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
echo "โ
Project '$PROJECT_NAME' is ready!"
|
|
232
|
+
echo "๐ Next steps:"
|
|
233
|
+
echo " 1. cd $PROJECT_NAME"
|
|
234
|
+
echo " 2. Fill in .env.local"
|
|
235
|
+
echo " 3. bun run start"
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Hello via Bun!");
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-your-stack",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"module": "index.ts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-your-stack": "bin/create-your-stack"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"index.ts",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/bun": "latest"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"typescript": "^5"
|
|
19
|
+
}
|
|
20
|
+
}
|