@ramonclaudio/create-vexpo 0.1.0
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 +50 -0
- package/dist/index.js +183 -0
- package/dist/templates/default/.eas/workflows/asc-events.yml +84 -0
- package/dist/templates/default/.eas/workflows/deploy-production.yml +129 -0
- package/dist/templates/default/.eas/workflows/development-builds.yml +19 -0
- package/dist/templates/default/.eas/workflows/e2e-tests.yml +42 -0
- package/dist/templates/default/.eas/workflows/pr-preview.yml +98 -0
- package/dist/templates/default/.eas/workflows/release.yml +44 -0
- package/dist/templates/default/.eas/workflows/rollback.yml +86 -0
- package/dist/templates/default/.eas/workflows/rollout.yml +84 -0
- package/dist/templates/default/.eas/workflows/rotate-apple-jwt.yml +42 -0
- package/dist/templates/default/.eas/workflows/testflight.yml +57 -0
- package/dist/templates/default/.github/workflows/check.yml +28 -0
- package/dist/templates/default/.maestro/launch.yaml +18 -0
- package/dist/templates/default/AGENTS.md +79 -0
- package/dist/templates/default/DESIGN.md +331 -0
- package/dist/templates/default/LICENSE +21 -0
- package/dist/templates/default/README.md +153 -0
- package/dist/templates/default/SETUP.md +618 -0
- package/dist/templates/default/__tests__/convex/constants.test.ts +49 -0
- package/dist/templates/default/__tests__/convex/validators.test.ts +23 -0
- package/dist/templates/default/__tests__/convex/webhook.test.ts +343 -0
- package/dist/templates/default/__tests__/lib/deep-link.test.ts +67 -0
- package/dist/templates/default/_easignore +22 -0
- package/dist/templates/default/_editorconfig +9 -0
- package/dist/templates/default/_env.example +34 -0
- package/dist/templates/default/_fingerprintignore +24 -0
- package/dist/templates/default/_gitattributes +7 -0
- package/dist/templates/default/_gitignore +69 -0
- package/dist/templates/default/_oxfmtrc.json +3 -0
- package/dist/templates/default/_oxlintrc.json +34 -0
- package/dist/templates/default/app/(app)/(tabs)/(home)/index.tsx +50 -0
- package/dist/templates/default/app/(app)/(tabs)/(home,search)/_layout.tsx +44 -0
- package/dist/templates/default/app/(app)/(tabs)/(search)/index.tsx +247 -0
- package/dist/templates/default/app/(app)/(tabs)/_layout.tsx +77 -0
- package/dist/templates/default/app/(app)/(tabs)/settings/_layout.tsx +37 -0
- package/dist/templates/default/app/(app)/(tabs)/settings/index.tsx +362 -0
- package/dist/templates/default/app/(app)/(tabs)/settings/preferences.tsx +184 -0
- package/dist/templates/default/app/(app)/_layout.tsx +73 -0
- package/dist/templates/default/app/(app)/debug.tsx +389 -0
- package/dist/templates/default/app/(app)/help.tsx +254 -0
- package/dist/templates/default/app/(app)/linked.tsx +116 -0
- package/dist/templates/default/app/(app)/privacy.tsx +159 -0
- package/dist/templates/default/app/(app)/profile.tsx +915 -0
- package/dist/templates/default/app/(app)/sessions.tsx +191 -0
- package/dist/templates/default/app/(app)/welcome.tsx +140 -0
- package/dist/templates/default/app/(auth)/_layout.tsx +31 -0
- package/dist/templates/default/app/(auth)/forgot-password.tsx +168 -0
- package/dist/templates/default/app/(auth)/reset-password.tsx +314 -0
- package/dist/templates/default/app/(auth)/sign-in.tsx +453 -0
- package/dist/templates/default/app/(auth)/sign-up.tsx +563 -0
- package/dist/templates/default/app/+native-intent.tsx +14 -0
- package/dist/templates/default/app/+not-found.tsx +51 -0
- package/dist/templates/default/app/_layout.tsx +102 -0
- package/dist/templates/default/app-store/screenshots/.gitkeep +0 -0
- package/dist/templates/default/app-store/screenshots/README.md +13 -0
- package/dist/templates/default/app.config.ts +201 -0
- package/dist/templates/default/app.json +11 -0
- package/dist/templates/default/assets/brand-icon-dark.png +0 -0
- package/dist/templates/default/assets/brand-icon-light.png +0 -0
- package/dist/templates/default/assets/fonts/Geist-Black.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-BlackItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Bold.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-BoldItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-ExtraBold.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-ExtraBoldItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-ExtraLight.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-ExtraLightItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Italic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Light.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-LightItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Medium.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-MediumItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Regular.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-SemiBold.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-SemiBoldItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Thin.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-ThinItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Variable-Italic.ttf +0 -0
- package/dist/templates/default/assets/fonts/Geist-Variable.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-Bold.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-BoldItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-Italic.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-Medium.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-MediumItalic.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistMono-Regular.ttf +0 -0
- package/dist/templates/default/assets/fonts/GeistPixel-Square.ttf +0 -0
- package/dist/templates/default/assets/icon.png +0 -0
- package/dist/templates/default/assets/sounds/notification.wav +0 -0
- package/dist/templates/default/assets/splash-image-dark.png +0 -0
- package/dist/templates/default/assets/splash-image-light.png +0 -0
- package/dist/templates/default/bun.lock +1860 -0
- package/dist/templates/default/components/auth/otp-verification.tsx +255 -0
- package/dist/templates/default/components/auth/password-field.tsx +121 -0
- package/dist/templates/default/components/auth/segmented-toggle.tsx +47 -0
- package/dist/templates/default/components/ui/convex-error.tsx +32 -0
- package/dist/templates/default/components/ui/error-boundary.tsx +57 -0
- package/dist/templates/default/components/ui/loading-screen.tsx +31 -0
- package/dist/templates/default/components/ui/material.tsx +94 -0
- package/dist/templates/default/components/ui/offline-banner.tsx +58 -0
- package/dist/templates/default/components/ui/prominent-button.tsx +71 -0
- package/dist/templates/default/components/ui/skeleton.tsx +107 -0
- package/dist/templates/default/components/ui/status-text.tsx +49 -0
- package/dist/templates/default/components/ui/update-banner.tsx +82 -0
- package/dist/templates/default/constants/layout.ts +102 -0
- package/dist/templates/default/constants/theme.ts +401 -0
- package/dist/templates/default/constants/ui.ts +77 -0
- package/dist/templates/default/convex/_generated/api.d.ts +77 -0
- package/dist/templates/default/convex/_generated/api.js +23 -0
- package/dist/templates/default/convex/_generated/dataModel.d.ts +60 -0
- package/dist/templates/default/convex/_generated/server.d.ts +143 -0
- package/dist/templates/default/convex/_generated/server.js +93 -0
- package/dist/templates/default/convex/admin.ts +102 -0
- package/dist/templates/default/convex/auth.config.ts +6 -0
- package/dist/templates/default/convex/auth.ts +335 -0
- package/dist/templates/default/convex/constants.ts +46 -0
- package/dist/templates/default/convex/convex.config.ts +11 -0
- package/dist/templates/default/convex/crons.ts +42 -0
- package/dist/templates/default/convex/email.ts +109 -0
- package/dist/templates/default/convex/env.ts +31 -0
- package/dist/templates/default/convex/errors.ts +33 -0
- package/dist/templates/default/convex/functions.ts +54 -0
- package/dist/templates/default/convex/http.ts +176 -0
- package/dist/templates/default/convex/log.ts +81 -0
- package/dist/templates/default/convex/pushTokens.ts +114 -0
- package/dist/templates/default/convex/rateLimit.ts +92 -0
- package/dist/templates/default/convex/schema.ts +28 -0
- package/dist/templates/default/convex/tsconfig.json +18 -0
- package/dist/templates/default/convex/users.ts +279 -0
- package/dist/templates/default/convex/validators.ts +74 -0
- package/dist/templates/default/convex/webhook.ts +193 -0
- package/dist/templates/default/convex.json +6 -0
- package/dist/templates/default/eas.json +56 -0
- package/dist/templates/default/fingerprint.config.js +9 -0
- package/dist/templates/default/hooks/use-debounce.ts +20 -0
- package/dist/templates/default/hooks/use-deep-link.ts +43 -0
- package/dist/templates/default/hooks/use-navigation-tracking.ts +15 -0
- package/dist/templates/default/hooks/use-network.ts +11 -0
- package/dist/templates/default/hooks/use-notifications.ts +107 -0
- package/dist/templates/default/hooks/use-onboarding.ts +15 -0
- package/dist/templates/default/hooks/use-reduced-motion.ts +11 -0
- package/dist/templates/default/hooks/use-theme.ts +53 -0
- package/dist/templates/default/hooks/use-updates.ts +86 -0
- package/dist/templates/default/lib/a11y.ts +5 -0
- package/dist/templates/default/lib/app.ts +14 -0
- package/dist/templates/default/lib/assets.ts +17 -0
- package/dist/templates/default/lib/auth-client.ts +21 -0
- package/dist/templates/default/lib/convex-auth.tsx +79 -0
- package/dist/templates/default/lib/deep-link.ts +71 -0
- package/dist/templates/default/lib/dev-menu.ts +119 -0
- package/dist/templates/default/lib/device.ts +40 -0
- package/dist/templates/default/lib/dynamic-font.ts +49 -0
- package/dist/templates/default/lib/env.ts +10 -0
- package/dist/templates/default/lib/haptics.ts +24 -0
- package/dist/templates/default/lib/notifications.ts +276 -0
- package/dist/templates/default/lib/preferences.ts +45 -0
- package/dist/templates/default/lib/schemas.ts +137 -0
- package/dist/templates/default/lib/storage.ts +47 -0
- package/dist/templates/default/lib/updates.ts +107 -0
- package/dist/templates/default/metro.config.js +14 -0
- package/dist/templates/default/package.json +129 -0
- package/dist/templates/default/patches/PR-368.patch +91 -0
- package/dist/templates/default/patches/convex-dev-better-auth-0.12.2.tgz +0 -0
- package/dist/templates/default/plugins/README.md +9 -0
- package/dist/templates/default/plugins/with-auto-signing.js +45 -0
- package/dist/templates/default/plugins/with-pod-deployment-target.js +35 -0
- package/dist/templates/default/scripts/README.md +36 -0
- package/dist/templates/default/scripts/_run.mjs +77 -0
- package/dist/templates/default/scripts/clean.ts +543 -0
- package/dist/templates/default/scripts/rotate-apple-jwt.mjs +80 -0
- package/dist/templates/default/store.config.json +58 -0
- package/dist/templates/default/tsconfig.json +13 -0
- package/dist/templates/default/vitest.config.ts +21 -0
- package/package.json +69 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: Rollback
|
|
2
|
+
|
|
3
|
+
# Manually trigger a rollback on any branch. Two flavors, matching the
|
|
4
|
+
# canonical eas-cli surface:
|
|
5
|
+
#
|
|
6
|
+
# "previous" → republish an earlier update group on the same branch.
|
|
7
|
+
# Picks the most recent successful update before the
|
|
8
|
+
# currently-active one. Use this when a recent OTA broke
|
|
9
|
+
# something users on previous builds didn't see.
|
|
10
|
+
# Maps to `eas update:republish`.
|
|
11
|
+
# https://docs.expo.dev/eas-update/rollbacks/
|
|
12
|
+
#
|
|
13
|
+
# "embedded" → roll back to the build's embedded bundle (the JS that
|
|
14
|
+
# shipped with the .ipa). Effectively makes the next-OTA-check
|
|
15
|
+
# ignore the current rollout and serve the binary as-is.
|
|
16
|
+
# Use this when a broken OTA shouldn't ship to ANYONE on
|
|
17
|
+
# that build. Maps to `eas update:roll-back-to-embedded`.
|
|
18
|
+
# https://docs.expo.dev/eas-update/rollbacks/
|
|
19
|
+
#
|
|
20
|
+
# Pair with the asc-events workflow's Slack notify so the team knows.
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
inputs:
|
|
25
|
+
branch:
|
|
26
|
+
description: Branch to roll back (production | pr-<n>)
|
|
27
|
+
type: string
|
|
28
|
+
required: true
|
|
29
|
+
type:
|
|
30
|
+
description: Rollback flavor
|
|
31
|
+
type: select
|
|
32
|
+
required: true
|
|
33
|
+
default: previous
|
|
34
|
+
options:
|
|
35
|
+
- previous
|
|
36
|
+
- embedded
|
|
37
|
+
message:
|
|
38
|
+
description: Optional message stored on the update group
|
|
39
|
+
type: string
|
|
40
|
+
required: false
|
|
41
|
+
|
|
42
|
+
concurrency:
|
|
43
|
+
cancel_in_progress: false
|
|
44
|
+
group: ${{ workflow.filename }}-${{ inputs.branch }}
|
|
45
|
+
|
|
46
|
+
defaults:
|
|
47
|
+
tools:
|
|
48
|
+
bun: latest
|
|
49
|
+
|
|
50
|
+
jobs:
|
|
51
|
+
rollback:
|
|
52
|
+
name: Roll back ${{ inputs.branch }} (${{ inputs.type }})
|
|
53
|
+
environment: ${{ inputs.branch == 'production' && 'production' || 'development' }}
|
|
54
|
+
runs_on: linux-medium
|
|
55
|
+
steps:
|
|
56
|
+
- uses: eas/checkout
|
|
57
|
+
- uses: eas/install_node_modules
|
|
58
|
+
- name: Roll back
|
|
59
|
+
run: |
|
|
60
|
+
MSG="${{ inputs.message }}"
|
|
61
|
+
MSG_ARG=""
|
|
62
|
+
if [ -n "$MSG" ]; then MSG_ARG="--message \"$MSG\""; fi
|
|
63
|
+
if [ "${{ inputs.type }}" = "embedded" ]; then
|
|
64
|
+
eval bunx eas-cli update:roll-back-to-embedded \
|
|
65
|
+
--branch "${{ inputs.branch }}" \
|
|
66
|
+
--platform ios \
|
|
67
|
+
--non-interactive \
|
|
68
|
+
$MSG_ARG
|
|
69
|
+
else
|
|
70
|
+
eval bunx eas-cli update:republish \
|
|
71
|
+
--branch "${{ inputs.branch }}" \
|
|
72
|
+
--platform ios \
|
|
73
|
+
--non-interactive \
|
|
74
|
+
$MSG_ARG
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
notify:
|
|
78
|
+
name: Notify Slack
|
|
79
|
+
needs: [rollback]
|
|
80
|
+
type: slack
|
|
81
|
+
params:
|
|
82
|
+
webhook_url: https://hooks.slack.com/services/REPLACE/ME/HERE
|
|
83
|
+
message: |
|
|
84
|
+
:rewind: Rolled back `${{ inputs.branch }}` to ${{ inputs.type }}.
|
|
85
|
+
Triggered by: ${{ github.triggering_actor }}
|
|
86
|
+
Workflow: ${{ workflow.url }}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Rollout
|
|
2
|
+
|
|
3
|
+
# Manually run a gradual rollout: publish a fresh OTA at a non-100%
|
|
4
|
+
# percentage, or bump/lower the % of the most recent rollout group on a
|
|
5
|
+
# branch. Mirrors the canonical EAS Update rollout flow:
|
|
6
|
+
# https://docs.expo.dev/eas-update/rollouts/
|
|
7
|
+
#
|
|
8
|
+
# Two paths, controlled by `action`:
|
|
9
|
+
#
|
|
10
|
+
# "publish" → `eas update --branch <b> --rollout-percentage <%>`
|
|
11
|
+
# Publishes a fresh OTA from the current HEAD at the given %.
|
|
12
|
+
# Use to start a new rollout (e.g. 5% → 25% → 100%).
|
|
13
|
+
#
|
|
14
|
+
# "edit" → `eas update:edit --branch <b> --rollout-percentage <%>`
|
|
15
|
+
# Bumps the percentage of the currently-active rollout group
|
|
16
|
+
# on the branch. Use to ramp an existing rollout.
|
|
17
|
+
#
|
|
18
|
+
# After confirming adoption looks healthy on the Insights dashboard, set
|
|
19
|
+
# the rollout to 100. To kill a bad rollout, use the `rollback` workflow.
|
|
20
|
+
|
|
21
|
+
on:
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
inputs:
|
|
24
|
+
branch:
|
|
25
|
+
description: Branch (production | pr-<n>)
|
|
26
|
+
type: string
|
|
27
|
+
required: true
|
|
28
|
+
default: production
|
|
29
|
+
action:
|
|
30
|
+
description: Publish a new rollout, or edit the % of the existing one
|
|
31
|
+
type: select
|
|
32
|
+
required: true
|
|
33
|
+
default: edit
|
|
34
|
+
options:
|
|
35
|
+
- edit
|
|
36
|
+
- publish
|
|
37
|
+
percentage:
|
|
38
|
+
description: Rollout percentage (1-100)
|
|
39
|
+
type: number
|
|
40
|
+
required: true
|
|
41
|
+
default: 25
|
|
42
|
+
|
|
43
|
+
concurrency:
|
|
44
|
+
cancel_in_progress: false
|
|
45
|
+
group: ${{ workflow.filename }}-${{ inputs.branch }}
|
|
46
|
+
|
|
47
|
+
defaults:
|
|
48
|
+
tools:
|
|
49
|
+
bun: latest
|
|
50
|
+
|
|
51
|
+
jobs:
|
|
52
|
+
rollout:
|
|
53
|
+
name: ${{ inputs.action }} → ${{ inputs.percentage }}% on ${{ inputs.branch }}
|
|
54
|
+
environment: ${{ inputs.branch == 'production' && 'production' || 'development' }}
|
|
55
|
+
runs_on: linux-medium
|
|
56
|
+
steps:
|
|
57
|
+
- uses: eas/checkout
|
|
58
|
+
- uses: eas/install_node_modules
|
|
59
|
+
- name: Roll out
|
|
60
|
+
run: |
|
|
61
|
+
if [ "${{ inputs.action }}" = "publish" ]; then
|
|
62
|
+
bunx eas-cli update \
|
|
63
|
+
--branch "${{ inputs.branch }}" \
|
|
64
|
+
--platform ios \
|
|
65
|
+
--rollout-percentage "${{ inputs.percentage }}" \
|
|
66
|
+
--non-interactive \
|
|
67
|
+
--message "Rollout publish @ ${{ inputs.percentage }}%"
|
|
68
|
+
else
|
|
69
|
+
bunx eas-cli update:edit \
|
|
70
|
+
--branch "${{ inputs.branch }}" \
|
|
71
|
+
--rollout-percentage "${{ inputs.percentage }}" \
|
|
72
|
+
--non-interactive
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
notify:
|
|
76
|
+
name: Notify Slack
|
|
77
|
+
needs: [rollout]
|
|
78
|
+
type: slack
|
|
79
|
+
params:
|
|
80
|
+
webhook_url: https://hooks.slack.com/services/REPLACE/ME/HERE
|
|
81
|
+
message: |
|
|
82
|
+
:chart_with_upwards_trend: Rollout ${{ inputs.action }} on `${{ inputs.branch }}` → ${{ inputs.percentage }}%
|
|
83
|
+
Triggered by: ${{ github.triggering_actor }}
|
|
84
|
+
Workflow: ${{ workflow.url }}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Rotate Apple Sign In JWT
|
|
2
|
+
|
|
3
|
+
# Apple caps client_secret JWTs at 180 days. We re-sign every 90 days so
|
|
4
|
+
# we always have plenty of headroom and never get caught with an expired
|
|
5
|
+
# token. Replaces the GitHub Actions equivalent. runs on EAS infrastructure
|
|
6
|
+
# and reads secrets from EAS env vars (production, secret visibility) rather
|
|
7
|
+
# than GitHub repo secrets.
|
|
8
|
+
#
|
|
9
|
+
# Required EAS env vars (production environment, secret visibility):
|
|
10
|
+
# APPLE_P8_PRIVATE_KEY PEM contents of the Sign In with Apple .p8
|
|
11
|
+
# APPLE_TEAM_ID 10-char Apple Team id
|
|
12
|
+
# APPLE_KEY_ID 10-char Sign In with Apple key id
|
|
13
|
+
# APPLE_SERVICES_ID Services id (e.g. com.you.app.signin)
|
|
14
|
+
# CONVEX_DEPLOY_KEY Production Convex deploy key
|
|
15
|
+
#
|
|
16
|
+
# Set them once with:
|
|
17
|
+
# eas env:create --name APPLE_P8_PRIVATE_KEY --value-file <path-to-.p8> \
|
|
18
|
+
# --environment production --visibility secret
|
|
19
|
+
# eas env:create --name APPLE_TEAM_ID --value <value> \
|
|
20
|
+
# --environment production --visibility secret
|
|
21
|
+
# ...etc
|
|
22
|
+
|
|
23
|
+
on:
|
|
24
|
+
schedule:
|
|
25
|
+
- cron: "0 12 1 */3 *" # 12:00 UTC on the 1st, every 3rd month
|
|
26
|
+
workflow_dispatch: {}
|
|
27
|
+
|
|
28
|
+
defaults:
|
|
29
|
+
tools:
|
|
30
|
+
bun: latest
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
rotate:
|
|
34
|
+
name: Sign + push fresh client_secret
|
|
35
|
+
type: custom
|
|
36
|
+
runs_on: linux-medium
|
|
37
|
+
environment: production # pulls EAS env vars from production
|
|
38
|
+
steps:
|
|
39
|
+
- uses: eas/checkout
|
|
40
|
+
- uses: eas/install_node_modules
|
|
41
|
+
- name: Sign + push to Convex
|
|
42
|
+
run: node scripts/rotate-apple-jwt.mjs
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: TestFlight
|
|
2
|
+
|
|
3
|
+
# Builds and distributes to TestFlight using the dedicated `testflight` job
|
|
4
|
+
# (https://docs.expo.dev/eas/workflows/pre-packaged-jobs/#testflight). Unlike a
|
|
5
|
+
# plain `submit`, this job lets us name internal/external groups, attach a
|
|
6
|
+
# changelog, and gate on Beta App Review.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches: ["beta/*"]
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
inputs:
|
|
13
|
+
changelog:
|
|
14
|
+
type: string
|
|
15
|
+
required: false
|
|
16
|
+
description: 'What to test ("Bug fixes" if omitted)'
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
cancel_in_progress: true
|
|
20
|
+
group: ${{ workflow.filename }}-${{ github.ref }}
|
|
21
|
+
|
|
22
|
+
defaults:
|
|
23
|
+
tools:
|
|
24
|
+
bun: latest
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
precheck:
|
|
28
|
+
name: Precheck
|
|
29
|
+
type: custom
|
|
30
|
+
runs_on: linux-medium
|
|
31
|
+
steps:
|
|
32
|
+
- uses: eas/checkout
|
|
33
|
+
- uses: eas/install_node_modules
|
|
34
|
+
- name: Typecheck
|
|
35
|
+
run: bun run typecheck
|
|
36
|
+
- name: Lint
|
|
37
|
+
run: bun run lint
|
|
38
|
+
- name: Test
|
|
39
|
+
run: bun run test
|
|
40
|
+
|
|
41
|
+
build_ios:
|
|
42
|
+
name: Build iOS
|
|
43
|
+
needs: [precheck]
|
|
44
|
+
type: build
|
|
45
|
+
params:
|
|
46
|
+
platform: ios
|
|
47
|
+
profile: production
|
|
48
|
+
|
|
49
|
+
testflight:
|
|
50
|
+
name: Distribute to TestFlight
|
|
51
|
+
needs: [build_ios]
|
|
52
|
+
type: testflight
|
|
53
|
+
params:
|
|
54
|
+
build_id: ${{ needs.build_ios.outputs.build_id }}
|
|
55
|
+
profile: testflight
|
|
56
|
+
internal_groups: ["Internal"]
|
|
57
|
+
changelog: ${{ inputs.changelog || github.event.head_commit.message || 'Bug fixes' }}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
check:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: oven-sh/setup-bun@v2
|
|
13
|
+
- run: bun install
|
|
14
|
+
- run: bunx expo-doctor
|
|
15
|
+
- run: bun run typecheck
|
|
16
|
+
- run: bun run lint
|
|
17
|
+
- run: bun run format:check
|
|
18
|
+
- run: bun run test
|
|
19
|
+
|
|
20
|
+
fingerprint:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
- uses: oven-sh/setup-bun@v2
|
|
27
|
+
- run: bun install
|
|
28
|
+
- run: bun run fp:diff
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Smoke test: app launches and the welcome screen renders.
|
|
2
|
+
#
|
|
3
|
+
# Maestro auto-derives the appId from the build's bundle id, so the same
|
|
4
|
+
# flow runs against the dev simulator binary (`com.example.<pkg>` fallback
|
|
5
|
+
# in app.config.ts) and the production binary (`com.<your-team>.<app>`)
|
|
6
|
+
# without edits.
|
|
7
|
+
#
|
|
8
|
+
# Run locally: `maestro test .maestro/launch.yaml`
|
|
9
|
+
# Run on EAS: triggered by `.eas/workflows/e2e-tests.yml` on every PR.
|
|
10
|
+
appId: ${MAESTRO_APP_ID}
|
|
11
|
+
---
|
|
12
|
+
- launchApp:
|
|
13
|
+
clearState: true
|
|
14
|
+
- assertVisible:
|
|
15
|
+
text: "Welcome"
|
|
16
|
+
timeout: 30000
|
|
17
|
+
- assertVisible: "Your new app starts here."
|
|
18
|
+
- takeScreenshot: welcome
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# AGENTS
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding assistants (Claude Code, Cursor, Aider, etc.) working in
|
|
4
|
+
a scaffolded vexpo project. The same content applies to humans reading by
|
|
5
|
+
hand. These are conventions, not magic.
|
|
6
|
+
|
|
7
|
+
## Stack at a glance
|
|
8
|
+
|
|
9
|
+
- **Backend.** Convex. Reactive queries, real-time sync, storage. No raw DB
|
|
10
|
+
calls. Everything goes through `convex/` (server) and `convex/react`
|
|
11
|
+
(client). After running `npx convex ai-files install`, read
|
|
12
|
+
`convex/_generated/ai/guidelines.md` before touching anything in `convex/`.
|
|
13
|
+
- **Auth.** Better Auth via `@convex-dev/better-auth`. Patched locally with
|
|
14
|
+
PR #368 until upstream merges (`patches/`). Email verification is gated on
|
|
15
|
+
the `REQUIRE_EMAIL_VERIFICATION` Convex env var.
|
|
16
|
+
- **Mobile.** Expo SDK 56 canary, RN 0.85, React 19. **iOS only today.**
|
|
17
|
+
Native UI exclusively via `@expo/ui/swift-ui`. No NativeWind, no Tailwind,
|
|
18
|
+
no `react-native-paper`.
|
|
19
|
+
- **CI/CD.** EAS Workflows (`.eas/workflows/*.yml`) for everything
|
|
20
|
+
Expo-shaped. GitHub Actions (`.github/workflows/check.yml`) only for
|
|
21
|
+
general-purpose checks (typecheck, lint, format, tests, fingerprint).
|
|
22
|
+
|
|
23
|
+
## Conventions
|
|
24
|
+
|
|
25
|
+
- **TypeScript:** `strict: true`. Don't add `any` casts. If a type is hard,
|
|
26
|
+
ask before reaching for `any`.
|
|
27
|
+
- **Imports:** Path alias `@/` resolves to the template root. No deep
|
|
28
|
+
relative imports (`../../../`).
|
|
29
|
+
- **Files:** Lowercase, kebab-case filenames. One component per file. Default
|
|
30
|
+
export the component, named exports for everything else.
|
|
31
|
+
- **State:** Convex `useQuery`/`useMutation` for server state. React `useState`
|
|
32
|
+
for local UI state. No Redux, no Zustand, no Jotai.
|
|
33
|
+
- **Styling:** `@expo/ui/swift-ui` primitives + `modifiers`. The chassis is
|
|
34
|
+
SwiftUI, not RN. `<Host>` boundary tells you you're crossing into native.
|
|
35
|
+
- **Validation:** Zod on the client (`lib/schemas.ts`), Convex validators on
|
|
36
|
+
the server (`convex/validators.ts`). Don't pick one. Both, at each
|
|
37
|
+
boundary.
|
|
38
|
+
- **Errors:** Throw real `Error` instances. Wrap server errors with
|
|
39
|
+
`formatError` from `components/ui/convex-error.tsx`. Don't swallow.
|
|
40
|
+
- **Tests:** Vitest. `templates/default/__tests__/` covers Convex constants,
|
|
41
|
+
validators, and deep-link parsing. Add tests for new validator logic and
|
|
42
|
+
new HTTP handlers.
|
|
43
|
+
|
|
44
|
+
## What requires extra care
|
|
45
|
+
|
|
46
|
+
- **Convex functions**: every query/mutation needs both server-side
|
|
47
|
+
validators and matching client types. The `convex/_generated/` directory is
|
|
48
|
+
the contract. Run `bunx convex codegen` after schema or function changes.
|
|
49
|
+
- **HTTP routes** (`convex/http.ts`): every public endpoint must use
|
|
50
|
+
`convex/webhook.ts` `withWebhook()` factory for HMAC verification + body
|
|
51
|
+
cap + structured logging, or document why it doesn't. Inbound webhooks are
|
|
52
|
+
untrusted by default.
|
|
53
|
+
- **Apple SIWA JWT**: rotates every 90 days via
|
|
54
|
+
`.eas/workflows/rotate-apple-jwt.yml`. Don't break the env-var contract
|
|
55
|
+
that cron depends on (`APPLE_P8_PRIVATE_KEY`, `APPLE_TEAM_ID`,
|
|
56
|
+
`APPLE_KEY_ID`, `APPLE_SERVICES_ID`, `CONVEX_DEPLOY_KEY`).
|
|
57
|
+
- **Push notifications**: only work on a physical device. iOS Simulator does
|
|
58
|
+
not deliver APNs. Don't try to test push flows in the simulator.
|
|
59
|
+
- **`store.config.json`**: ships with placeholder values. `bunx vexpo
|
|
60
|
+
rebrand` fills them in. App Review will reject builds with placeholder
|
|
61
|
+
contact info.
|
|
62
|
+
|
|
63
|
+
## When in doubt
|
|
64
|
+
|
|
65
|
+
- Run `bunx vexpo doctor` to check that `.env.local`, Convex env, EAS env,
|
|
66
|
+
and `app.config.ts` agree.
|
|
67
|
+
- Use `bunx eas <subcommand>` for canonical EAS operations. **Don't reinvent
|
|
68
|
+
EAS.** That's the vexpo design principle.
|
|
69
|
+
- Read `SETUP.md` for the long-form orchestration walkthrough.
|
|
70
|
+
|
|
71
|
+
<!-- convex-ai-start -->
|
|
72
|
+
|
|
73
|
+
This project uses [Convex](https://convex.dev) as its backend.
|
|
74
|
+
|
|
75
|
+
When working on Convex code, **always read `convex/_generated/ai/guidelines.md` first** for important guidelines on how to correctly use Convex APIs and patterns. The file contains rules that override what you may have learned about Convex from training data.
|
|
76
|
+
|
|
77
|
+
Convex agent skills for common tasks can be installed by running `npx convex ai-files install`.
|
|
78
|
+
|
|
79
|
+
<!-- convex-ai-end -->
|