@ramonclaudio/create-vexpo 0.1.0 → 0.1.2

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 (174) hide show
  1. package/README.md +10 -10
  2. package/dist/index.js +8 -7
  3. package/dist/templates/default/.eas/workflows/asc-events.yml +9 -6
  4. package/dist/templates/default/.eas/workflows/deploy-production.yml +28 -15
  5. package/dist/templates/default/.eas/workflows/e2e-tests.yml +3 -2
  6. package/dist/templates/default/.eas/workflows/pr-preview.yml +12 -21
  7. package/dist/templates/default/.eas/workflows/release.yml +3 -7
  8. package/dist/templates/default/.eas/workflows/rollback.yml +54 -28
  9. package/dist/templates/default/.eas/workflows/rollout.yml +27 -33
  10. package/dist/templates/default/.eas/workflows/rotate-apple-jwt.yml +1 -5
  11. package/dist/templates/default/.eas/workflows/testflight.yml +3 -7
  12. package/dist/templates/default/.github/workflows/check.yml +20 -12
  13. package/dist/templates/default/.maestro/launch.yaml +19 -10
  14. package/dist/templates/default/AGENTS.md +25 -8
  15. package/dist/templates/default/DESIGN.md +14 -10
  16. package/dist/templates/default/README.md +83 -78
  17. package/dist/templates/default/SETUP.md +159 -152
  18. package/dist/templates/default/__tests__/convex/_auth-harness.test.ts +112 -0
  19. package/dist/templates/default/__tests__/convex/_harness.ts +132 -0
  20. package/dist/templates/default/__tests__/convex/appAttest.test.ts +172 -0
  21. package/dist/templates/default/__tests__/convex/appAttestStore.test.ts +48 -0
  22. package/dist/templates/default/__tests__/convex/pushTokens-remove.test.ts +106 -0
  23. package/dist/templates/default/__tests__/convex/pushTokens-upsert.test.ts +146 -0
  24. package/dist/templates/default/__tests__/convex/users-deleteAccount.test.ts +140 -0
  25. package/dist/templates/default/__tests__/convex/users-deleteAvatar.test.ts +104 -0
  26. package/dist/templates/default/__tests__/convex/users-getMe.test.ts +98 -0
  27. package/dist/templates/default/__tests__/convex/users-getUser.test.ts +120 -0
  28. package/dist/templates/default/__tests__/convex/users-hardDeleteExpired.test.ts +67 -0
  29. package/dist/templates/default/__tests__/convex/users-restoreAccount.test.ts +96 -0
  30. package/dist/templates/default/__tests__/convex/users-updateAvatar.test.ts +92 -0
  31. package/dist/templates/default/__tests__/convex/users-updateProfile.test.ts +126 -0
  32. package/dist/templates/default/__tests__/convex/webhook.test.ts +31 -0
  33. package/dist/templates/default/__tests__/lib/deep-link.test.ts +51 -6
  34. package/dist/templates/default/__tests__/lib/schemas.test.ts +205 -0
  35. package/dist/templates/default/__tests__/lib/text-style.test.ts +31 -0
  36. package/dist/templates/default/_env.example +7 -7
  37. package/dist/templates/default/_gitattributes +1 -1
  38. package/dist/templates/default/_gitignore +17 -2
  39. package/dist/templates/default/_npmrc +7 -0
  40. package/dist/templates/default/_oxlintrc.json +1 -1
  41. package/dist/templates/default/app-store/accessibility.config.json +20 -0
  42. package/dist/templates/default/app-store/privacy.config.json +27 -0
  43. package/dist/templates/default/app.config.ts +105 -33
  44. package/dist/templates/default/app.json +1 -9
  45. package/dist/templates/default/convex/_generated/api.d.ts +12 -0
  46. package/dist/templates/default/convex/admin.ts +0 -13
  47. package/dist/templates/default/convex/appAttest.ts +467 -0
  48. package/dist/templates/default/convex/appAttestStore.ts +141 -0
  49. package/dist/templates/default/convex/apple.ts +53 -0
  50. package/dist/templates/default/convex/auth.ts +6 -45
  51. package/dist/templates/default/convex/constants.ts +2 -7
  52. package/dist/templates/default/convex/crons.ts +12 -5
  53. package/dist/templates/default/convex/email.ts +4 -24
  54. package/dist/templates/default/convex/env.ts +0 -4
  55. package/dist/templates/default/convex/errors.ts +0 -7
  56. package/dist/templates/default/convex/functions.ts +0 -26
  57. package/dist/templates/default/convex/http.ts +3 -5
  58. package/dist/templates/default/convex/log.ts +2 -25
  59. package/dist/templates/default/convex/pushSender.ts +145 -0
  60. package/dist/templates/default/convex/pushTokens.ts +110 -13
  61. package/dist/templates/default/convex/rateLimit.ts +8 -39
  62. package/dist/templates/default/convex/schema.ts +48 -5
  63. package/dist/templates/default/convex/tsconfig.json +1 -0
  64. package/dist/templates/default/convex/users.ts +143 -61
  65. package/dist/templates/default/convex/validators.ts +1 -38
  66. package/dist/templates/default/convex/webhook.ts +1 -31
  67. package/dist/templates/default/convex.json +1 -2
  68. package/dist/templates/default/metro.config.js +9 -1
  69. package/dist/templates/default/package.json +67 -70
  70. package/dist/templates/default/plugins/README.md +5 -1
  71. package/dist/templates/default/scripts/README.md +9 -9
  72. package/dist/templates/default/scripts/_run.mjs +3 -20
  73. package/dist/templates/default/scripts/clean.ts +81 -69
  74. package/dist/templates/default/scripts/gen-update-cert.mjs +98 -0
  75. package/dist/templates/default/{app → src/app}/(app)/(tabs)/(home)/index.tsx +21 -6
  76. package/dist/templates/default/{app → src/app}/(app)/(tabs)/(home,search)/_layout.tsx +9 -8
  77. package/dist/templates/default/{app → src/app}/(app)/(tabs)/(search)/index.tsx +26 -24
  78. package/dist/templates/default/{app → src/app}/(app)/(tabs)/_layout.tsx +3 -4
  79. package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/_layout.tsx +10 -6
  80. package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/index.tsx +81 -51
  81. package/dist/templates/default/{app → src/app}/(app)/(tabs)/settings/preferences.tsx +72 -12
  82. package/dist/templates/default/src/app/(app)/_layout.tsx +147 -0
  83. package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/_layout.tsx +4 -5
  84. package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/forgot-password.tsx +15 -9
  85. package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/reset-password.tsx +88 -14
  86. package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/sign-in.tsx +65 -35
  87. package/dist/templates/default/{app/(auth) → src/app/(app)/auth}/sign-up.tsx +131 -196
  88. package/dist/templates/default/src/app/(app)/debug.tsx +479 -0
  89. package/dist/templates/default/{app → src/app}/(app)/help.tsx +76 -64
  90. package/dist/templates/default/{app → src/app}/(app)/linked.tsx +21 -27
  91. package/dist/templates/default/{app → src/app}/(app)/privacy.tsx +35 -8
  92. package/dist/templates/default/src/app/(app)/profile/change-password.tsx +264 -0
  93. package/dist/templates/default/{app/(app)/profile.tsx → src/app/(app)/profile/index.tsx} +179 -255
  94. package/dist/templates/default/src/app/(app)/restore-account.tsx +192 -0
  95. package/dist/templates/default/src/app/(app)/sessions.tsx +287 -0
  96. package/dist/templates/default/src/app/(app)/welcome.tsx +194 -0
  97. package/dist/templates/default/src/app/+native-intent.tsx +25 -0
  98. package/dist/templates/default/src/app/+not-found.tsx +43 -0
  99. package/dist/templates/default/{app → src/app}/_layout.tsx +28 -37
  100. package/dist/templates/default/src/components/auth/apple-button.tsx +51 -0
  101. package/dist/templates/default/{components → src/components}/auth/otp-verification.tsx +79 -58
  102. package/dist/templates/default/{components → src/components}/auth/password-field.tsx +74 -18
  103. package/dist/templates/default/src/components/auth/segmented-toggle.tsx +71 -0
  104. package/dist/templates/default/src/components/ui/content-unavailable.tsx +81 -0
  105. package/dist/templates/default/src/components/ui/convex-error.tsx +21 -0
  106. package/dist/templates/default/src/components/ui/error-boundary.tsx +89 -0
  107. package/dist/templates/default/{components → src/components}/ui/loading-screen.tsx +5 -4
  108. package/dist/templates/default/{components → src/components}/ui/material.tsx +50 -17
  109. package/dist/templates/default/src/components/ui/offline-banner.tsx +59 -0
  110. package/dist/templates/default/{components → src/components}/ui/prominent-button.tsx +8 -11
  111. package/dist/templates/default/{components → src/components}/ui/skeleton.tsx +31 -13
  112. package/dist/templates/default/src/components/ui/status-text.tsx +64 -0
  113. package/dist/templates/default/src/components/ui/update-banner.tsx +85 -0
  114. package/dist/templates/default/{constants → src/constants}/layout.ts +0 -6
  115. package/dist/templates/default/{constants → src/constants}/theme.ts +49 -64
  116. package/dist/templates/default/{constants → src/constants}/ui.ts +13 -4
  117. package/dist/templates/default/src/hooks/use-debounce.ts +12 -0
  118. package/dist/templates/default/src/hooks/use-deep-link.ts +51 -0
  119. package/dist/templates/default/src/hooks/use-delete-account.ts +35 -0
  120. package/dist/templates/default/src/hooks/use-motion-screen-options.ts +13 -0
  121. package/dist/templates/default/src/hooks/use-network.ts +34 -0
  122. package/dist/templates/default/{hooks → src/hooks}/use-notifications.ts +39 -30
  123. package/dist/templates/default/src/hooks/use-reduce-transparency.ts +30 -0
  124. package/dist/templates/default/{hooks → src/hooks}/use-theme.ts +0 -5
  125. package/dist/templates/default/src/lib/appAttest.ts +78 -0
  126. package/dist/templates/default/src/lib/assets.ts +9 -0
  127. package/dist/templates/default/src/lib/deep-link.ts +82 -0
  128. package/dist/templates/default/{lib → src/lib}/dev-menu.ts +0 -4
  129. package/dist/templates/default/{lib → src/lib}/device.ts +1 -13
  130. package/dist/templates/default/{lib → src/lib}/dynamic-font.ts +13 -10
  131. package/dist/templates/default/src/lib/dynamic-symbol-size.ts +33 -0
  132. package/dist/templates/default/src/lib/masks.ts +21 -0
  133. package/dist/templates/default/src/lib/native-state.ts +20 -0
  134. package/dist/templates/default/{lib → src/lib}/notifications.ts +7 -45
  135. package/dist/templates/default/{lib → src/lib}/preferences.ts +0 -2
  136. package/dist/templates/default/{lib → src/lib}/schemas.ts +19 -16
  137. package/dist/templates/default/src/lib/text-style.ts +20 -0
  138. package/dist/templates/default/{lib → src/lib}/updates.ts +0 -7
  139. package/dist/templates/default/store.config.json +1 -1
  140. package/dist/templates/default/tsconfig.json +3 -1
  141. package/dist/templates/default/vitest.config.ts +8 -1
  142. package/package.json +5 -5
  143. package/dist/templates/default/app/(app)/_layout.tsx +0 -73
  144. package/dist/templates/default/app/(app)/debug.tsx +0 -389
  145. package/dist/templates/default/app/(app)/sessions.tsx +0 -191
  146. package/dist/templates/default/app/(app)/welcome.tsx +0 -140
  147. package/dist/templates/default/app/+native-intent.tsx +0 -14
  148. package/dist/templates/default/app/+not-found.tsx +0 -51
  149. package/dist/templates/default/bun.lock +0 -1860
  150. package/dist/templates/default/components/auth/segmented-toggle.tsx +0 -47
  151. package/dist/templates/default/components/ui/convex-error.tsx +0 -32
  152. package/dist/templates/default/components/ui/error-boundary.tsx +0 -57
  153. package/dist/templates/default/components/ui/offline-banner.tsx +0 -58
  154. package/dist/templates/default/components/ui/status-text.tsx +0 -49
  155. package/dist/templates/default/components/ui/update-banner.tsx +0 -82
  156. package/dist/templates/default/fingerprint.config.js +0 -9
  157. package/dist/templates/default/hooks/use-debounce.ts +0 -20
  158. package/dist/templates/default/hooks/use-deep-link.ts +0 -43
  159. package/dist/templates/default/hooks/use-network.ts +0 -11
  160. package/dist/templates/default/lib/assets.ts +0 -17
  161. package/dist/templates/default/lib/deep-link.ts +0 -71
  162. package/dist/templates/default/patches/PR-368.patch +0 -91
  163. package/dist/templates/default/patches/convex-dev-better-auth-0.12.2.tgz +0 -0
  164. /package/dist/templates/default/{hooks → src/hooks}/use-navigation-tracking.ts +0 -0
  165. /package/dist/templates/default/{hooks → src/hooks}/use-onboarding.ts +0 -0
  166. /package/dist/templates/default/{hooks → src/hooks}/use-reduced-motion.ts +0 -0
  167. /package/dist/templates/default/{hooks → src/hooks}/use-updates.ts +0 -0
  168. /package/dist/templates/default/{lib → src/lib}/a11y.ts +0 -0
  169. /package/dist/templates/default/{lib → src/lib}/app.ts +0 -0
  170. /package/dist/templates/default/{lib → src/lib}/auth-client.ts +0 -0
  171. /package/dist/templates/default/{lib → src/lib}/convex-auth.tsx +0 -0
  172. /package/dist/templates/default/{lib → src/lib}/env.ts +0 -0
  173. /package/dist/templates/default/{lib → src/lib}/haptics.ts +0 -0
  174. /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.ts";
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);
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "bundler": {
3
3
  "includeSourcesContent": false
4
- },
5
- "typescriptCompiler": "tsgo"
4
+ }
6
5
  }
@@ -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
- config.resolver.blockList = [/\.env\.convex\.local$/];
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.0",
3
+ "version": "0.1.2",
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": "bunx eas build -p ios --profile development:simulator",
24
- "eas:dev:device": "bunx eas build -p ios --profile development:device",
25
- "eas:tf": "bunx eas build -p ios --profile production --auto-submit-with-profile testflight",
26
- "eas:prod": "bunx eas build -p ios --profile production",
27
- "metadata:lint": "bunx eas metadata:lint",
28
- "metadata:push": "bunx eas metadata:lint && bunx eas metadata:push",
29
- "metadata:pull": "bunx eas metadata:pull",
30
- "env:pull": "bunx eas env:pull --environment development",
31
- "env:pull:prod": "bunx eas env:pull --environment production",
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": "bunx @expo/fingerprint fingerprint:generate",
37
- "fp:diff": "bunx @expo/fingerprint fingerprint: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": "bunx expo install expo@canary && bunx expo install --fix",
44
- "upgrade:stable": "bunx expo install expo@latest && bunx expo install --fix"
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.9",
48
- "@convex-dev/better-auth": "file:./patches/convex-dev-better-auth-0.12.2.tgz",
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.3",
51
- "@expo/ui": "56.0.0-canary-20260506-03817f5",
52
- "@react-navigation/native": "7.2.3",
53
- "better-auth": "1.6.9",
54
- "convex": "^1.37.0",
55
- "convex-helpers": "^0.1.116",
56
- "expo": "56.0.0-canary-20260506-03817f5",
57
- "expo-apple-authentication": "56.0.0-canary-20260506-03817f5",
58
- "expo-application": "56.0.0-canary-20260506-03817f5",
59
- "expo-asset": "56.0.0-canary-20260506-03817f5",
60
- "expo-blur": "56.0.0-canary-20260506-03817f5",
61
- "expo-build-properties": "56.0.0-canary-20260506-03817f5",
62
- "expo-clipboard": "56.0.0-canary-20260506-03817f5",
63
- "expo-constants": "56.0.0-canary-20260506-03817f5",
64
- "expo-dev-client": "56.0.0-canary-20260506-03817f5",
65
- "expo-device": "56.0.0-canary-20260506-03817f5",
66
- "expo-font": "56.0.0-canary-20260506-03817f5",
67
- "expo-glass-effect": "56.0.0-canary-20260506-03817f5",
68
- "expo-haptics": "56.0.0-canary-20260506-03817f5",
69
- "expo-image": "56.0.0-canary-20260506-03817f5",
70
- "expo-image-picker": "56.0.0-canary-20260506-03817f5",
71
- "expo-insights": "56.0.0-canary-20260506-03817f5",
72
- "expo-linking": "56.0.0-canary-20260506-03817f5",
73
- "expo-local-authentication": "56.0.0-canary-20260506-03817f5",
74
- "expo-network": "56.0.0-canary-20260506-03817f5",
75
- "expo-notifications": "56.0.0-canary-20260506-03817f5",
76
- "expo-router": "56.0.0-canary-20260506-03817f5",
77
- "expo-secure-store": "56.0.0-canary-20260506-03817f5",
78
- "expo-sharing": "56.0.0-canary-20260506-03817f5",
79
- "expo-splash-screen": "56.0.0-canary-20260506-03817f5",
80
- "expo-sqlite": "56.0.0-canary-20260506-03817f5",
81
- "expo-status-bar": "56.0.0-canary-20260506-03817f5",
82
- "expo-symbols": "56.0.0-canary-20260506-03817f5",
83
- "expo-system-ui": "56.0.0-canary-20260506-03817f5",
84
- "expo-task-manager": "56.0.0-canary-20260506-03817f5",
85
- "expo-updates": "56.0.0-canary-20260506-03817f5",
86
- "expo-web-browser": "56.0.0-canary-20260506-03817f5",
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.0",
94
+ "react-native-reanimated": "4.3.1",
92
95
  "react-native-safe-area-context": "~5.7.0",
93
- "react-native-screens": "4.25.0-beta.1",
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.6.0",
100
- "@types/react": "~19.2.14",
101
- "@vitest/ui": "^4.1.5",
102
- "convex-test": "^0.0.51",
103
- "oxfmt": "^0.48.0",
104
- "oxlint": "^1.63.0",
105
- "tsx": "^4.21.0",
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.5"
110
+ "vitest": "^4.1.8"
108
111
  },
109
112
  "overrides": {
110
- "@better-auth/passkey": "1.6.9",
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 `bun run ios` on a physical device without juggling provisioning profiles in Xcode.
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 `bunx vexpo`), not here.
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
- bunx vexpo lite # dev-mode setup (Convex + Better Auth only)
21
- bunx vexpo full # full provisioning to TestFlight-ready
22
- bunx vexpo doctor # cross-source drift detection
23
- bunx vexpo env push # sync from .env.local + .env.prod to Convex/EAS
24
- bunx vexpo apple asc-key # validate ASC API key
25
- bunx vexpo apple services-id # attach SIWA capability to App ID
26
- bunx vexpo apple jwt # sign client_secret JWT, push to Convex
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 [`vexpo` on npm](https://www.npmjs.com/package/vexpo). Source lives at [`github.com/ramonclaudio/vexpo`](https://github.com/ramonclaudio/vexpo).
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
- * Runtime-agnostic launcher for vexpo's TypeScript setup scripts.
4
- *
5
- * Picks the first available runtime that handles full TypeScript syntax:
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