@ramonclaudio/create-vexpo 0.1.0 → 0.1.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 +10 -10
- package/dist/index.js +8 -7
- package/dist/templates/default/.eas/workflows/asc-events.yml +9 -6
- package/dist/templates/default/.eas/workflows/deploy-production.yml +28 -15
- package/dist/templates/default/.eas/workflows/e2e-tests.yml +3 -2
- package/dist/templates/default/.eas/workflows/pr-preview.yml +12 -21
- package/dist/templates/default/.eas/workflows/release.yml +3 -7
- package/dist/templates/default/.eas/workflows/rollback.yml +54 -28
- package/dist/templates/default/.eas/workflows/rollout.yml +27 -33
- package/dist/templates/default/.eas/workflows/rotate-apple-jwt.yml +1 -5
- package/dist/templates/default/.eas/workflows/testflight.yml +3 -7
- package/dist/templates/default/.github/workflows/check.yml +20 -12
- package/dist/templates/default/.maestro/launch.yaml +19 -10
- package/dist/templates/default/AGENTS.md +25 -8
- package/dist/templates/default/DESIGN.md +14 -10
- package/dist/templates/default/README.md +83 -78
- package/dist/templates/default/SETUP.md +159 -152
- package/dist/templates/default/__tests__/convex/_auth-harness.test.ts +112 -0
- package/dist/templates/default/__tests__/convex/_harness.ts +132 -0
- package/dist/templates/default/__tests__/convex/appAttest.test.ts +172 -0
- package/dist/templates/default/__tests__/convex/appAttestStore.test.ts +48 -0
- package/dist/templates/default/__tests__/convex/pushTokens-remove.test.ts +106 -0
- package/dist/templates/default/__tests__/convex/pushTokens-upsert.test.ts +146 -0
- package/dist/templates/default/__tests__/convex/users-deleteAccount.test.ts +140 -0
- package/dist/templates/default/__tests__/convex/users-deleteAvatar.test.ts +104 -0
- package/dist/templates/default/__tests__/convex/users-getMe.test.ts +98 -0
- package/dist/templates/default/__tests__/convex/users-getUser.test.ts +120 -0
- package/dist/templates/default/__tests__/convex/users-hardDeleteExpired.test.ts +67 -0
- package/dist/templates/default/__tests__/convex/users-restoreAccount.test.ts +96 -0
- package/dist/templates/default/__tests__/convex/users-updateAvatar.test.ts +92 -0
- package/dist/templates/default/__tests__/convex/users-updateProfile.test.ts +126 -0
- package/dist/templates/default/__tests__/convex/webhook.test.ts +31 -0
- package/dist/templates/default/__tests__/lib/deep-link.test.ts +51 -6
- package/dist/templates/default/__tests__/lib/schemas.test.ts +205 -0
- package/dist/templates/default/__tests__/lib/text-style.test.ts +31 -0
- package/dist/templates/default/_env.example +7 -7
- package/dist/templates/default/_gitattributes +1 -1
- package/dist/templates/default/_gitignore +17 -2
- package/dist/templates/default/_npmrc +7 -0
- package/dist/templates/default/_oxlintrc.json +1 -1
- package/dist/templates/default/app-store/accessibility.config.json +20 -0
- package/dist/templates/default/app-store/privacy.config.json +27 -0
- package/dist/templates/default/app.config.ts +105 -33
- package/dist/templates/default/app.json +1 -9
- package/dist/templates/default/convex/_generated/api.d.ts +12 -0
- package/dist/templates/default/convex/admin.ts +0 -13
- package/dist/templates/default/convex/appAttest.ts +467 -0
- package/dist/templates/default/convex/appAttestStore.ts +141 -0
- package/dist/templates/default/convex/apple.ts +53 -0
- package/dist/templates/default/convex/auth.ts +6 -45
- package/dist/templates/default/convex/constants.ts +2 -7
- package/dist/templates/default/convex/crons.ts +12 -5
- package/dist/templates/default/convex/email.ts +4 -24
- package/dist/templates/default/convex/env.ts +0 -4
- package/dist/templates/default/convex/errors.ts +0 -7
- package/dist/templates/default/convex/functions.ts +0 -26
- package/dist/templates/default/convex/http.ts +3 -5
- package/dist/templates/default/convex/log.ts +2 -25
- package/dist/templates/default/convex/pushSender.ts +145 -0
- package/dist/templates/default/convex/pushTokens.ts +110 -13
- package/dist/templates/default/convex/rateLimit.ts +8 -39
- package/dist/templates/default/convex/schema.ts +48 -5
- package/dist/templates/default/convex/tsconfig.json +1 -0
- package/dist/templates/default/convex/users.ts +143 -61
- package/dist/templates/default/convex/validators.ts +1 -38
- package/dist/templates/default/convex/webhook.ts +1 -31
- package/dist/templates/default/convex.json +1 -2
- package/dist/templates/default/metro.config.js +9 -1
- package/dist/templates/default/package.json +67 -70
- package/dist/templates/default/plugins/README.md +5 -1
- package/dist/templates/default/scripts/README.md +9 -9
- package/dist/templates/default/scripts/_run.mjs +3 -20
- package/dist/templates/default/scripts/clean.ts +81 -69
- package/dist/templates/default/scripts/gen-update-cert.mjs +98 -0
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/(home)/index.tsx +21 -6
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/(home,search)/_layout.tsx +9 -8
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/(search)/index.tsx +26 -24
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/_layout.tsx +3 -4
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/_layout.tsx +10 -6
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/index.tsx +81 -51
- package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/preferences.tsx +72 -12
- package/dist/templates/default/src/app/(app)/_layout.tsx +147 -0
- package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/_layout.tsx +4 -5
- package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/forgot-password.tsx +15 -9
- package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/reset-password.tsx +88 -14
- package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/sign-in.tsx +65 -35
- package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/sign-up.tsx +131 -196
- package/dist/templates/default/src/app/(app)/debug.tsx +479 -0
- package/dist/templates/default/{app → src/app}/(app)/help.tsx +76 -64
- package/dist/templates/default/{app → src/app}/(app)/linked.tsx +21 -27
- package/dist/templates/default/{app → src/app}/(app)/privacy.tsx +35 -8
- package/dist/templates/default/src/app/(app)/profile/change-password.tsx +264 -0
- package/dist/templates/default/{app/(app)/profile.tsx → src/app/(app)/profile/index.tsx} +179 -255
- package/dist/templates/default/src/app/(app)/restore-account.tsx +192 -0
- package/dist/templates/default/src/app/(app)/sessions.tsx +287 -0
- package/dist/templates/default/src/app/(app)/welcome.tsx +194 -0
- package/dist/templates/default/src/app/+native-intent.tsx +25 -0
- package/dist/templates/default/src/app/+not-found.tsx +43 -0
- package/dist/templates/default/{app → src/app}/_layout.tsx +28 -37
- package/dist/templates/default/src/components/auth/apple-button.tsx +51 -0
- package/dist/templates/default/{components → src/components}/auth/otp-verification.tsx +79 -58
- package/dist/templates/default/{components → src/components}/auth/password-field.tsx +74 -18
- package/dist/templates/default/src/components/auth/segmented-toggle.tsx +71 -0
- package/dist/templates/default/src/components/ui/content-unavailable.tsx +81 -0
- package/dist/templates/default/src/components/ui/convex-error.tsx +21 -0
- package/dist/templates/default/src/components/ui/error-boundary.tsx +89 -0
- package/dist/templates/default/{components → src/components}/ui/loading-screen.tsx +5 -4
- package/dist/templates/default/{components → src/components}/ui/material.tsx +50 -17
- package/dist/templates/default/src/components/ui/offline-banner.tsx +59 -0
- package/dist/templates/default/{components → src/components}/ui/prominent-button.tsx +8 -11
- package/dist/templates/default/{components → src/components}/ui/skeleton.tsx +31 -13
- package/dist/templates/default/src/components/ui/status-text.tsx +64 -0
- package/dist/templates/default/src/components/ui/update-banner.tsx +85 -0
- package/dist/templates/default/{constants → src/constants}/layout.ts +0 -6
- package/dist/templates/default/{constants → src/constants}/theme.ts +49 -64
- package/dist/templates/default/{constants → src/constants}/ui.ts +13 -4
- package/dist/templates/default/src/hooks/use-debounce.ts +12 -0
- package/dist/templates/default/src/hooks/use-deep-link.ts +51 -0
- package/dist/templates/default/src/hooks/use-delete-account.ts +35 -0
- package/dist/templates/default/src/hooks/use-motion-screen-options.ts +13 -0
- package/dist/templates/default/src/hooks/use-network.ts +34 -0
- package/dist/templates/default/{hooks → src/hooks}/use-notifications.ts +39 -30
- package/dist/templates/default/src/hooks/use-reduce-transparency.ts +30 -0
- package/dist/templates/default/{hooks → src/hooks}/use-theme.ts +0 -5
- package/dist/templates/default/src/lib/appAttest.ts +78 -0
- package/dist/templates/default/src/lib/assets.ts +9 -0
- package/dist/templates/default/src/lib/deep-link.ts +82 -0
- package/dist/templates/default/{lib → src/lib}/dev-menu.ts +0 -4
- package/dist/templates/default/{lib → src/lib}/device.ts +1 -13
- package/dist/templates/default/{lib → src/lib}/dynamic-font.ts +13 -10
- package/dist/templates/default/src/lib/dynamic-symbol-size.ts +33 -0
- package/dist/templates/default/src/lib/masks.ts +21 -0
- package/dist/templates/default/src/lib/native-state.ts +20 -0
- package/dist/templates/default/{lib → src/lib}/notifications.ts +7 -45
- package/dist/templates/default/{lib → src/lib}/preferences.ts +0 -2
- package/dist/templates/default/{lib → src/lib}/schemas.ts +19 -16
- package/dist/templates/default/src/lib/text-style.ts +20 -0
- package/dist/templates/default/{lib → src/lib}/updates.ts +0 -7
- package/dist/templates/default/store.config.json +1 -1
- package/dist/templates/default/tsconfig.json +3 -1
- package/dist/templates/default/vitest.config.ts +8 -1
- package/package.json +5 -5
- package/dist/templates/default/app/(app)/_layout.tsx +0 -73
- package/dist/templates/default/app/(app)/debug.tsx +0 -389
- package/dist/templates/default/app/(app)/sessions.tsx +0 -191
- package/dist/templates/default/app/(app)/welcome.tsx +0 -140
- package/dist/templates/default/app/+native-intent.tsx +0 -14
- package/dist/templates/default/app/+not-found.tsx +0 -51
- package/dist/templates/default/bun.lock +0 -1860
- package/dist/templates/default/components/auth/segmented-toggle.tsx +0 -47
- package/dist/templates/default/components/ui/convex-error.tsx +0 -32
- package/dist/templates/default/components/ui/error-boundary.tsx +0 -57
- package/dist/templates/default/components/ui/offline-banner.tsx +0 -58
- package/dist/templates/default/components/ui/status-text.tsx +0 -49
- package/dist/templates/default/components/ui/update-banner.tsx +0 -82
- package/dist/templates/default/fingerprint.config.js +0 -9
- package/dist/templates/default/hooks/use-debounce.ts +0 -20
- package/dist/templates/default/hooks/use-deep-link.ts +0 -43
- package/dist/templates/default/hooks/use-network.ts +0 -11
- package/dist/templates/default/lib/assets.ts +0 -17
- package/dist/templates/default/lib/deep-link.ts +0 -71
- package/dist/templates/default/patches/PR-368.patch +0 -91
- package/dist/templates/default/patches/convex-dev-better-auth-0.12.2.tgz +0 -0
- /package/dist/templates/default/{hooks → src/hooks}/use-navigation-tracking.ts +0 -0
- /package/dist/templates/default/{hooks → src/hooks}/use-onboarding.ts +0 -0
- /package/dist/templates/default/{hooks → src/hooks}/use-reduced-motion.ts +0 -0
- /package/dist/templates/default/{hooks → src/hooks}/use-updates.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/a11y.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/app.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/auth-client.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/convex-auth.tsx +0 -0
- /package/dist/templates/default/{lib → src/lib}/env.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/haptics.ts +0 -0
- /package/dist/templates/default/{lib → src/lib}/storage.ts +0 -0
|
@@ -1,39 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validator Utilities
|
|
3
|
-
*
|
|
4
|
-
* Function argument and return-type validators.
|
|
5
|
-
* Schema-level field validators live in schema.ts.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
1
|
import { literals } from "convex-helpers/validators";
|
|
9
2
|
import { v } from "convex/values";
|
|
10
3
|
|
|
11
|
-
/**
|
|
12
|
-
* Paginated response structure.
|
|
13
|
-
* Spread into a v.object() alongside the page shape.
|
|
14
|
-
*/
|
|
15
4
|
export const paginatedResponseFields = {
|
|
16
5
|
continueCursor: v.string(),
|
|
17
6
|
isDone: v.boolean(),
|
|
18
7
|
};
|
|
19
8
|
|
|
20
|
-
//
|
|
21
|
-
// User Profile Validators
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* User profile fields accepted by updateProfile.
|
|
26
|
-
* Name changes go through Better Auth (authClient.updateUser) directly.
|
|
27
|
-
*/
|
|
9
|
+
// Name changes go through Better Auth (authClient.updateUser) directly.
|
|
28
10
|
export const userProfileUpdateFields = {
|
|
29
11
|
bio: v.optional(v.string()),
|
|
30
12
|
};
|
|
31
13
|
|
|
32
|
-
/**
|
|
33
|
-
* Public user profile returned by api.users.getUser and in listUsers pages.
|
|
34
|
-
* Merges app-owned fields (bio, avatar storage resolved to URL) with Better
|
|
35
|
-
* Auth identity fields (name, username).
|
|
36
|
-
*/
|
|
37
14
|
export const publicUserProfileValidator = v.object({
|
|
38
15
|
_id: v.id("users"),
|
|
39
16
|
_creationTime: v.number(),
|
|
@@ -43,29 +20,15 @@ export const publicUserProfileValidator = v.object({
|
|
|
43
20
|
bio: v.optional(v.string()),
|
|
44
21
|
});
|
|
45
22
|
|
|
46
|
-
/**
|
|
47
|
-
* Paginated user list response.
|
|
48
|
-
*/
|
|
49
23
|
export const paginatedUsersValidator = v.object({
|
|
50
24
|
page: v.array(publicUserProfileValidator),
|
|
51
25
|
...paginatedResponseFields,
|
|
52
26
|
});
|
|
53
27
|
|
|
54
|
-
// ============================================================================
|
|
55
|
-
// Mobile Validators
|
|
56
|
-
// ============================================================================
|
|
57
|
-
|
|
58
28
|
export const deviceTypeValidator = literals("ios");
|
|
59
29
|
|
|
60
|
-
// ============================================================================
|
|
61
|
-
// Validation Helpers
|
|
62
|
-
// ============================================================================
|
|
63
|
-
|
|
64
30
|
const BIO_MAX_LENGTH = 500;
|
|
65
31
|
|
|
66
|
-
/**
|
|
67
|
-
* Validate a bio field.
|
|
68
|
-
*/
|
|
69
32
|
export function validateBio(bio: string): { valid: boolean; error?: string } {
|
|
70
33
|
if (bio.length > BIO_MAX_LENGTH) {
|
|
71
34
|
return { valid: false, error: `Bio must be ${BIO_MAX_LENGTH} characters or less` };
|
|
@@ -1,32 +1,12 @@
|
|
|
1
|
-
// Webhook handler factory for Convex HTTP routes.
|
|
2
|
-
//
|
|
3
|
-
// Every webhook source we accept (EAS Build/Submit, Resend delivery events,
|
|
4
|
-
// future Stripe / GitHub) follows the same shape: a signed POST with a
|
|
5
|
-
// shared secret, JSON body, signature in a header. Centralising the
|
|
6
|
-
// boilerplate here means each route gets:
|
|
7
|
-
//
|
|
8
|
-
// - Body-size cap (defend against runaway upload eating the function budget)
|
|
9
|
-
// - Constant-time signature verification (HMAC, configurable algorithm)
|
|
10
|
-
// - Optional replay protection (timestamp window check)
|
|
11
|
-
// - Per-request correlation ID + structured access log with timing
|
|
12
|
-
// - Uniform JSON error responses with a `requestId` for grepping
|
|
13
|
-
//
|
|
14
|
-
// The handler the caller supplies receives the parsed JSON body, raw text
|
|
15
|
-
// body (in case re-hashing is needed), and the request ID. It returns a
|
|
16
|
-
// `Response`; the factory wraps timing + logging around it.
|
|
17
|
-
|
|
18
1
|
import type { GenericActionCtx } from "convex/server";
|
|
19
2
|
|
|
20
|
-
import { log, newRequestId } from "./log
|
|
3
|
+
import { log, newRequestId } from "./log";
|
|
21
4
|
|
|
22
5
|
export type SignatureAlgorithm = "sha1" | "sha256";
|
|
23
6
|
|
|
24
7
|
export type WithWebhookOptions = {
|
|
25
|
-
/** Stable name in logs. Example: "eas-webhook", "resend-webhook". */
|
|
26
8
|
source: string;
|
|
27
|
-
/** Request header carrying the signature. Example: "expo-signature". */
|
|
28
9
|
signatureHeader: string;
|
|
29
|
-
/** Convex env var holding the shared secret. Example: "EAS_WEBHOOK_SECRET". */
|
|
30
10
|
secretEnv: string;
|
|
31
11
|
/** HMAC algorithm. EAS uses SHA-1, Stripe uses SHA-256, Resend uses Svix's HMAC-SHA256. */
|
|
32
12
|
algorithm: SignatureAlgorithm;
|
|
@@ -35,16 +15,9 @@ export type WithWebhookOptions = {
|
|
|
35
15
|
* EAS sends `sha1=<hex>`, Stripe sends `t=<ts>,v1=<hex>`, etc. Default `""`.
|
|
36
16
|
*/
|
|
37
17
|
signaturePrefix?: string;
|
|
38
|
-
/** Cap the request body size in bytes. Defaults to 1 MiB. */
|
|
39
18
|
maxBodyBytes?: number;
|
|
40
|
-
/**
|
|
41
|
-
* Optional max age of the request in seconds. If set, the handler reads
|
|
42
|
-
* the timestamp from the named header and rejects if too old. Defaults
|
|
43
|
-
* to "no replay window check."
|
|
44
|
-
*/
|
|
45
19
|
replay?: {
|
|
46
20
|
header: string;
|
|
47
|
-
/** Allowed clock skew in seconds. */
|
|
48
21
|
maxAgeSeconds: number;
|
|
49
22
|
};
|
|
50
23
|
};
|
|
@@ -136,9 +109,6 @@ export function withWebhook<T = unknown>(
|
|
|
136
109
|
status: response.status,
|
|
137
110
|
durationMs: Date.now() - start,
|
|
138
111
|
});
|
|
139
|
-
// Always attach X-Request-Id to the response so callers can correlate
|
|
140
|
-
// logs even when the handler doesn't set it explicitly. Don't clobber
|
|
141
|
-
// a value the handler already chose.
|
|
142
112
|
if (!response.headers.get("X-Request-Id")) {
|
|
143
113
|
const headers = new Headers(response.headers);
|
|
144
114
|
headers.set("X-Request-Id", requestId);
|
|
@@ -3,7 +3,15 @@ const { getDefaultConfig } = require("expo/metro-config");
|
|
|
3
3
|
/** @type {import('expo/metro-config').MetroConfig} */
|
|
4
4
|
const config = getDefaultConfig(__dirname);
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Extend, don't replace: Expo's default blockList excludes `.expo/types`
|
|
7
|
+
// (prevents spurious Fast Refresh on generated typed-routes declarations),
|
|
8
|
+
// `ios/Pods`, and Metro's `__tests__` dir. Reassigning would drop all of those.
|
|
9
|
+
config.resolver.blockList = [
|
|
10
|
+
...(Array.isArray(config.resolver.blockList)
|
|
11
|
+
? config.resolver.blockList
|
|
12
|
+
: [config.resolver.blockList]),
|
|
13
|
+
/\.env\.convex\.local$/,
|
|
14
|
+
];
|
|
7
15
|
|
|
8
16
|
config.transformer.minifierConfig = {
|
|
9
17
|
compress: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vexpo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"main": "expo-router/entry",
|
|
6
6
|
"scripts": {
|
|
@@ -20,102 +20,99 @@
|
|
|
20
20
|
"ios:dev": "expo run:ios",
|
|
21
21
|
"ios:device": "node scripts/_run.mjs scripts/clean.ts --metro && expo prebuild --clean --platform ios && expo run:ios --device --no-build-cache",
|
|
22
22
|
"prebuild": "expo prebuild --clean --platform ios",
|
|
23
|
-
"eas:dev": "
|
|
24
|
-
"eas:dev:device": "
|
|
25
|
-
"eas:tf": "
|
|
26
|
-
"eas:prod": "
|
|
27
|
-
"metadata:lint": "
|
|
28
|
-
"metadata:push": "
|
|
29
|
-
"metadata:pull": "
|
|
30
|
-
"env:pull": "
|
|
31
|
-
"env:pull:prod": "
|
|
23
|
+
"eas:dev": "npx eas build -p ios --profile development:simulator",
|
|
24
|
+
"eas:dev:device": "npx eas build -p ios --profile development:device",
|
|
25
|
+
"eas:tf": "npx eas build -p ios --profile production --auto-submit-with-profile testflight",
|
|
26
|
+
"eas:prod": "npx eas build -p ios --profile production",
|
|
27
|
+
"metadata:lint": "npx eas metadata:lint",
|
|
28
|
+
"metadata:push": "npx eas metadata:lint && npx eas metadata:push",
|
|
29
|
+
"metadata:pull": "npx eas metadata:pull",
|
|
30
|
+
"env:pull": "npx eas env:pull --environment development",
|
|
31
|
+
"env:pull:prod": "npx eas env:pull --environment production",
|
|
32
32
|
"clean": "node scripts/_run.mjs scripts/clean.ts",
|
|
33
33
|
"clean:metro": "node scripts/_run.mjs scripts/clean.ts --metro",
|
|
34
34
|
"clean:state": "node scripts/_run.mjs scripts/clean.ts --state",
|
|
35
35
|
"typecheck": "tsc --noEmit",
|
|
36
|
-
"fp": "
|
|
37
|
-
"fp:diff": "
|
|
36
|
+
"fp": "npx @expo/fingerprint fingerprint:generate",
|
|
37
|
+
"fp:diff": "npx @expo/fingerprint fingerprint:diff",
|
|
38
38
|
"lint": "oxlint",
|
|
39
39
|
"format": "oxfmt",
|
|
40
40
|
"format:check": "oxfmt --check",
|
|
41
41
|
"test": "vitest run",
|
|
42
42
|
"test:watch": "vitest",
|
|
43
|
-
"upgrade": "
|
|
44
|
-
"upgrade:stable": "
|
|
43
|
+
"upgrade": "npx expo install expo@next && npx expo install --fix",
|
|
44
|
+
"upgrade:stable": "npx expo install expo@latest && npx expo install --fix",
|
|
45
|
+
"updates:gen-cert": "node scripts/gen-update-cert.mjs"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@better-auth/expo": "1.6.
|
|
48
|
-
"@convex-dev/better-auth": "
|
|
48
|
+
"@better-auth/expo": "1.6.16",
|
|
49
|
+
"@convex-dev/better-auth": "0.12.3",
|
|
49
50
|
"@convex-dev/rate-limiter": "^0.3.2",
|
|
50
|
-
"@convex-dev/resend": "^0.2.
|
|
51
|
-
"@expo/
|
|
52
|
-
"@
|
|
53
|
-
"better-auth": "1.6.
|
|
54
|
-
"
|
|
55
|
-
"convex
|
|
56
|
-
"
|
|
57
|
-
"expo
|
|
58
|
-
"expo-
|
|
59
|
-
"expo-
|
|
60
|
-
"expo-
|
|
61
|
-
"expo-
|
|
62
|
-
"expo-
|
|
63
|
-
"expo-
|
|
64
|
-
"expo-
|
|
65
|
-
"expo-
|
|
66
|
-
"expo-
|
|
67
|
-
"expo-
|
|
68
|
-
"expo-
|
|
69
|
-
"expo-
|
|
70
|
-
"expo-image
|
|
71
|
-
"expo-
|
|
72
|
-
"expo-
|
|
73
|
-
"expo-
|
|
74
|
-
"expo-
|
|
75
|
-
"expo-
|
|
76
|
-
"expo-
|
|
77
|
-
"expo-
|
|
78
|
-
"expo-
|
|
79
|
-
"expo-
|
|
80
|
-
"expo-
|
|
81
|
-
"expo-
|
|
82
|
-
"expo-
|
|
83
|
-
"expo-
|
|
84
|
-
"expo-
|
|
85
|
-
"expo-
|
|
86
|
-
"expo-
|
|
51
|
+
"@convex-dev/resend": "^0.2.4",
|
|
52
|
+
"@expo/app-integrity": "~56.0.3",
|
|
53
|
+
"@expo/ui": "~56.0.16",
|
|
54
|
+
"better-auth": "1.6.16",
|
|
55
|
+
"cbor-x": "^1.6.4",
|
|
56
|
+
"convex": "^1.40.0",
|
|
57
|
+
"convex-helpers": "^0.1.118",
|
|
58
|
+
"expo": "~56.0.9",
|
|
59
|
+
"expo-apple-authentication": "~56.0.4",
|
|
60
|
+
"expo-application": "~56.0.3",
|
|
61
|
+
"expo-asset": "~56.0.10",
|
|
62
|
+
"expo-blur": "~56.0.3",
|
|
63
|
+
"expo-build-properties": "~56.0.17",
|
|
64
|
+
"expo-clipboard": "~56.0.4",
|
|
65
|
+
"expo-constants": "~56.0.11",
|
|
66
|
+
"expo-dev-client": "~56.0.19",
|
|
67
|
+
"expo-device": "~56.0.4",
|
|
68
|
+
"expo-font": "~56.0.4",
|
|
69
|
+
"expo-glass-effect": "~56.0.4",
|
|
70
|
+
"expo-haptics": "~56.0.3",
|
|
71
|
+
"expo-image": "~56.0.10",
|
|
72
|
+
"expo-image-picker": "~56.0.16",
|
|
73
|
+
"expo-insights": "~56.0.16",
|
|
74
|
+
"expo-linking": "~56.0.13",
|
|
75
|
+
"expo-local-authentication": "~56.0.4",
|
|
76
|
+
"expo-network": "~56.0.5",
|
|
77
|
+
"expo-notifications": "~56.0.16",
|
|
78
|
+
"expo-router": "~56.2.9",
|
|
79
|
+
"expo-secure-store": "~56.0.4",
|
|
80
|
+
"expo-sharing": "~56.0.16",
|
|
81
|
+
"expo-splash-screen": "~56.0.10",
|
|
82
|
+
"expo-sqlite": "~56.0.4",
|
|
83
|
+
"expo-status-bar": "~56.0.4",
|
|
84
|
+
"expo-symbols": "~56.0.6",
|
|
85
|
+
"expo-system-ui": "~56.0.5",
|
|
86
|
+
"expo-task-manager": "~56.0.17",
|
|
87
|
+
"expo-updates": "~56.0.18",
|
|
88
|
+
"expo-web-browser": "~56.0.5",
|
|
87
89
|
"react": "19.2.3",
|
|
90
|
+
"react-dom": "19.2.3",
|
|
88
91
|
"react-native": "0.85.3",
|
|
89
92
|
"react-native-gesture-handler": "~2.31.2",
|
|
90
93
|
"react-native-keyboard-controller": "1.21.6",
|
|
91
|
-
"react-native-reanimated": "4.3.
|
|
94
|
+
"react-native-reanimated": "4.3.1",
|
|
92
95
|
"react-native-safe-area-context": "~5.7.0",
|
|
93
|
-
"react-native-screens": "4.25.
|
|
96
|
+
"react-native-screens": "4.25.2",
|
|
94
97
|
"react-native-worklets": "0.8.3",
|
|
95
98
|
"zod": "^4.4.3"
|
|
96
99
|
},
|
|
97
100
|
"devDependencies": {
|
|
98
101
|
"@ramonclaudio/vexpo": "^0.1.0",
|
|
99
|
-
"@types/node": "^25.
|
|
100
|
-
"@types/react": "~19.2.
|
|
101
|
-
"@vitest/ui": "^4.1.
|
|
102
|
-
"convex-test": "^0.0.
|
|
103
|
-
"oxfmt": "^0.
|
|
104
|
-
"oxlint": "^1.
|
|
105
|
-
"tsx": "^4.
|
|
102
|
+
"@types/node": "^25.9.0",
|
|
103
|
+
"@types/react": "~19.2.16",
|
|
104
|
+
"@vitest/ui": "^4.1.8",
|
|
105
|
+
"convex-test": "^0.0.53",
|
|
106
|
+
"oxfmt": "^0.54.0",
|
|
107
|
+
"oxlint": "^1.68.0",
|
|
108
|
+
"tsx": "^4.22.4",
|
|
106
109
|
"typescript": "^6.0.3",
|
|
107
|
-
"vitest": "^4.1.
|
|
110
|
+
"vitest": "^4.1.8"
|
|
108
111
|
},
|
|
109
112
|
"overrides": {
|
|
110
|
-
"
|
|
111
|
-
"@expo/ui": "56.0.0-canary-20260506-03817f5"
|
|
113
|
+
"react-dom": "19.2.3"
|
|
112
114
|
},
|
|
113
115
|
"expo": {
|
|
114
|
-
"install": {
|
|
115
|
-
"exclude": [
|
|
116
|
-
"react-native-reanimated"
|
|
117
|
-
]
|
|
118
|
-
},
|
|
119
116
|
"doctor": {
|
|
120
117
|
"reactNativeDirectoryCheck": {
|
|
121
118
|
"enabled": true,
|
|
@@ -6,4 +6,8 @@ Forces automatic code signing for the Xcode project during local `prebuild`. Set
|
|
|
6
6
|
|
|
7
7
|
No-ops when `EAS_BUILD` is set, so EAS continues to use the provisioning profile from the build credentials.
|
|
8
8
|
|
|
9
|
-
Use: local `
|
|
9
|
+
Use: local `npm run ios` on a physical device without juggling provisioning profiles in Xcode.
|
|
10
|
+
|
|
11
|
+
## `with-pod-deployment-target.js`
|
|
12
|
+
|
|
13
|
+
Forces every CocoaPods target to `IPHONEOS_DEPLOYMENT_TARGET = 16.4` during `prebuild`, injected into the `Podfile` right after `react_native_post_install`. Without it, transitive pods can fall back to a lower minimum and break the iOS 16.4 floor the template targets. Re-running is safe: a marker comment makes it a no-op once applied.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# scripts
|
|
2
2
|
|
|
3
|
-
Build and maintenance scripts. Setup orchestration lives in the published `vexpo` CLI (run via `
|
|
3
|
+
Build and maintenance scripts. Setup orchestration lives in the published `vexpo` CLI (run via `npx vexpo`), not here.
|
|
4
4
|
|
|
5
5
|
## What's in this directory
|
|
6
6
|
|
|
@@ -17,18 +17,18 @@ Anything else (preflight checks, env validation, version bumps) lives in the `ve
|
|
|
17
17
|
Use the `vexpo` CLI:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
npx vexpo lite # dev-mode setup (Convex + Better Auth only)
|
|
21
|
+
npx vexpo full # full provisioning to TestFlight-ready
|
|
22
|
+
npx vexpo doctor # cross-source drift detection
|
|
23
|
+
npx vexpo env push # sync from .env.local + .env.prod to Convex/EAS
|
|
24
|
+
npx vexpo apple asc-key # validate ASC API key
|
|
25
|
+
npx vexpo apple services-id # attach SIWA capability to App ID
|
|
26
|
+
npx vexpo apple jwt # sign client_secret JWT, push to Convex
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Version bumps run through `eas build:version:set` / `eas build:version:sync` (`appVersionSource: "remote"` in `eas.json` puts EAS in charge of the version).
|
|
30
30
|
|
|
31
|
-
The CLI itself ships from [
|
|
31
|
+
The CLI itself ships from [`@ramonclaudio/vexpo` on npm](https://www.npmjs.com/package/@ramonclaudio/vexpo). Source lives at [`github.com/ramonclaudio/vexpo`](https://github.com/ramonclaudio/vexpo).
|
|
32
32
|
|
|
33
33
|
## Conventions
|
|
34
34
|
|
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 1. bun. native TS, fastest startup
|
|
8
|
-
* 2. tsx (devDep). esbuild-based TS runner, works under any node 18+
|
|
9
|
-
*
|
|
10
|
-
* Note: we don't use node's `--experimental-strip-types` because it's
|
|
11
|
-
* strip-only. it doesn't transform syntax (parameter properties, enums,
|
|
12
|
-
* namespaces, etc all error out). bun and tsx handle full TS.
|
|
13
|
-
*
|
|
14
|
-
* Then re-execs the target script with the selected runtime, forwarding
|
|
15
|
-
* argv and stdio. Exit code mirrors the child.
|
|
16
|
-
*
|
|
17
|
-
* Usage (from package.json scripts):
|
|
18
|
-
* node scripts/_run.mjs scripts/setup.ts [args...]
|
|
3
|
+
* We don't use node's `--experimental-strip-types` because it's strip-only.
|
|
4
|
+
* It doesn't transform syntax (parameter properties, enums, namespaces, etc
|
|
5
|
+
* all error out). bun and tsx handle full TS.
|
|
19
6
|
*/
|
|
20
7
|
|
|
21
8
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -46,18 +33,14 @@ function which(bin) {
|
|
|
46
33
|
}
|
|
47
34
|
|
|
48
35
|
function pickRuntime() {
|
|
49
|
-
// Already running under bun? Use it directly (fastest).
|
|
50
36
|
if (process.versions.bun) return { cmd: process.execPath, args: [target] };
|
|
51
37
|
|
|
52
|
-
// bun on PATH
|
|
53
38
|
const bun = which("bun");
|
|
54
39
|
if (bun) return { cmd: bun, args: [target] };
|
|
55
40
|
|
|
56
|
-
// tsx fallback (any node 18+)
|
|
57
41
|
const tsx = resolve(REPO, "node_modules", ".bin", "tsx");
|
|
58
42
|
if (existsSync(tsx)) return { cmd: tsx, args: [target] };
|
|
59
43
|
|
|
60
|
-
// tsx via npx as last resort
|
|
61
44
|
const npx = which("npx");
|
|
62
45
|
if (npx) return { cmd: npx, args: ["tsx", target] };
|
|
63
46
|
|