@donotdev/cli 0.0.14 → 0.0.16

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 (184) hide show
  1. package/dependencies-matrix.json +372 -88
  2. package/dist/bin/commands/agent-setup.js +7 -1
  3. package/dist/bin/commands/build.js +141 -44
  4. package/dist/bin/commands/bump.js +81 -41
  5. package/dist/bin/commands/cacheout.js +37 -9
  6. package/dist/bin/commands/create-app.js +276 -121
  7. package/dist/bin/commands/create-project.js +506 -217
  8. package/dist/bin/commands/deploy.js +1785 -694
  9. package/dist/bin/commands/dev.js +177 -43
  10. package/dist/bin/commands/doctor.d.ts +6 -0
  11. package/dist/bin/commands/doctor.d.ts.map +1 -0
  12. package/dist/bin/commands/{lint.js → doctor.js} +1215 -156
  13. package/dist/bin/commands/doctor.js.map +1 -0
  14. package/dist/bin/commands/emu.js +451 -104
  15. package/dist/bin/commands/format.js +37 -9
  16. package/dist/bin/commands/make-admin.js +77499 -11
  17. package/dist/bin/commands/preview.js +181 -43
  18. package/dist/bin/commands/setup.d.ts +6 -0
  19. package/dist/bin/commands/setup.d.ts.map +1 -0
  20. package/dist/bin/commands/setup.js +11733 -0
  21. package/dist/bin/commands/setup.js.map +1 -0
  22. package/dist/bin/commands/supabase-setup.d.ts +6 -0
  23. package/dist/bin/commands/supabase-setup.d.ts.map +1 -0
  24. package/dist/bin/commands/supabase-setup.js +7 -0
  25. package/dist/bin/commands/supabase-setup.js.map +1 -0
  26. package/dist/bin/commands/sync-secrets.js +211 -34
  27. package/dist/bin/commands/type-check.d.ts +14 -0
  28. package/dist/bin/commands/type-check.d.ts.map +1 -0
  29. package/dist/bin/commands/type-check.js +2049 -0
  30. package/dist/bin/commands/type-check.js.map +1 -0
  31. package/dist/bin/commands/wai.js +3 -1
  32. package/dist/bin/dndev.js +73 -52
  33. package/dist/bin/donotdev.js +54 -45
  34. package/dist/index.js +4212 -3050
  35. package/package.json +3 -3
  36. package/templates/app-demo/src/App.tsx.example +1 -0
  37. package/templates/app-demo/src/pages/FullPage.tsx.example +2 -2
  38. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +2 -2
  39. package/templates/app-demo/src/themes.css.example +5 -12
  40. package/templates/app-expo/.env.example +44 -0
  41. package/templates/app-expo/.expo/README.md.example +5 -0
  42. package/templates/app-expo/.gitignore.example +36 -0
  43. package/templates/app-expo/README.md.example +58 -0
  44. package/templates/app-expo/app/.gitkeep +2 -0
  45. package/templates/app-expo/app/_layout.tsx.example +41 -0
  46. package/templates/app-expo/app/form.tsx.example +52 -0
  47. package/templates/app-expo/app/index.tsx.example +89 -0
  48. package/templates/app-expo/app/list.tsx.example +32 -0
  49. package/templates/app-expo/app/profile.tsx.example +76 -0
  50. package/templates/app-expo/app/signin.tsx.example +53 -0
  51. package/templates/app-expo/app.json.example +39 -0
  52. package/templates/app-expo/assets/adaptive-icon.png +0 -0
  53. package/templates/app-expo/assets/favicon.png +0 -0
  54. package/templates/app-expo/assets/icon.png +0 -0
  55. package/templates/app-expo/assets/splash.png +0 -0
  56. package/templates/app-expo/babel.config.js.example +10 -0
  57. package/templates/app-expo/eas.json.example +20 -0
  58. package/templates/app-expo/expo-env.d.ts.example +4 -0
  59. package/templates/app-expo/metro.config.js.example +20 -0
  60. package/templates/app-expo/service-account-key.json.example +12 -0
  61. package/templates/app-expo/src/config/app.ts.example +46 -0
  62. package/templates/app-expo/src/config/providers.ts.example +7 -0
  63. package/templates/app-expo/tsconfig.json.example +19 -0
  64. package/templates/app-next/.env.example +4 -33
  65. package/templates/app-next/src/app/ClientLayout.tsx.example +2 -0
  66. package/templates/app-next/src/app/layout.tsx.example +7 -6
  67. package/templates/app-next/src/config/providers.ts.example +7 -0
  68. package/templates/app-next/src/globals.css.example +2 -11
  69. package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
  70. package/templates/app-next/src/themes.css.example +10 -13
  71. package/templates/app-vite/.env.example +3 -32
  72. package/templates/app-vite/index.html.example +2 -24
  73. package/templates/app-vite/src/App.tsx.example +2 -0
  74. package/templates/app-vite/src/config/providers.ts.example +7 -0
  75. package/templates/app-vite/src/globals.css.example +2 -12
  76. package/templates/app-vite/src/pages/FormPageExample.tsx.example +1 -2
  77. package/templates/app-vite/src/pages/HomePage.tsx.example +2 -2
  78. package/templates/app-vite/src/themes.css.example +109 -79
  79. package/templates/app-vite/vercel.json.example +11 -0
  80. package/templates/functions-firebase/README.md.example +1 -1
  81. package/templates/functions-firebase/build.mjs.example +2 -72
  82. package/templates/functions-firebase/functions-firebase/.env.example.example +24 -26
  83. package/templates/functions-firebase/functions-firebase/README.md.example +1 -1
  84. package/templates/functions-firebase/functions-firebase/build.mjs.example +2 -72
  85. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
  86. package/templates/functions-firebase/functions.config.js.example +1 -1
  87. package/templates/functions-supabase/supabase/config.toml.example +59 -0
  88. package/templates/functions-supabase/supabase/functions/.env.example +13 -0
  89. package/templates/functions-supabase/supabase/functions/cancel-subscription/index.ts.example +7 -0
  90. package/templates/functions-supabase/supabase/functions/change-plan/index.ts.example +11 -0
  91. package/templates/functions-supabase/supabase/functions/create-checkout-session/index.ts.example +11 -0
  92. package/templates/functions-supabase/supabase/functions/create-customer-portal/index.ts.example +7 -0
  93. package/templates/functions-supabase/supabase/functions/crud/index.ts.example +16 -0
  94. package/templates/functions-supabase/supabase/functions/delete-account/index.ts.example +7 -0
  95. package/templates/functions-supabase/supabase/functions/deno.json.example +8 -0
  96. package/templates/functions-supabase/supabase/functions/get-custom-claims/index.ts.example +7 -0
  97. package/templates/functions-supabase/supabase/functions/get-user-auth-status/index.ts.example +7 -0
  98. package/templates/functions-supabase/supabase/functions/refresh-subscription-status/index.ts.example +7 -0
  99. package/templates/functions-supabase/supabase/functions/remove-custom-claims/index.ts.example +7 -0
  100. package/templates/functions-supabase/supabase/functions/set-custom-claims/index.ts.example +7 -0
  101. package/templates/functions-supabase/supabase/migrations/20250101000000_idempotency.sql +24 -0
  102. package/templates/functions-supabase/supabase/migrations/20250101000001_rate_limits.sql +22 -0
  103. package/templates/functions-supabase/supabase/migrations/20250101000002_cleanup_jobs.sql +28 -0
  104. package/templates/functions-supabase/supabase/migrations/20250101000003_operation_metrics.sql +28 -0
  105. package/templates/functions-vercel/functions-vercel/tsconfig.json.example +1 -1
  106. package/templates/functions-vercel/functions-vercel/vercel.json.example +1 -1
  107. package/templates/functions-vercel/vercel.json.example +1 -1
  108. package/templates/github/github/workflows/firebase-deploy.yml.example +1 -1
  109. package/templates/github/workflows/firebase-deploy.yml.example +1 -1
  110. package/templates/overlay-firebase/env.fragment.example +34 -0
  111. package/templates/overlay-firebase/env.fragment.expo.example +34 -0
  112. package/templates/overlay-firebase/env.fragment.nextjs.example +34 -0
  113. package/templates/overlay-firebase/src/config/providers.expo.ts.example +49 -0
  114. package/templates/overlay-firebase/src/config/providers.ts.example +23 -0
  115. package/templates/overlay-supabase/env.fragment.example +12 -0
  116. package/templates/overlay-supabase/env.fragment.expo.example +12 -0
  117. package/templates/overlay-supabase/env.fragment.nextjs.example +12 -0
  118. package/templates/overlay-supabase/src/config/providers.expo.ts.example +35 -0
  119. package/templates/overlay-supabase/src/config/providers.ts.example +33 -0
  120. package/templates/overlay-supabase/vercel.headers.example +23 -0
  121. package/templates/overlay-supabase/vercel.json.example +22 -0
  122. package/templates/overlay-vercel/env.fragment.example +34 -0
  123. package/templates/overlay-vercel/env.fragment.nextjs.example +34 -0
  124. package/templates/overlay-vercel/src/config/providers.ts.example +24 -0
  125. package/templates/root-consumer/.claude/agents/architect.md.example +2 -310
  126. package/templates/root-consumer/.claude/agents/builder.md.example +2 -326
  127. package/templates/root-consumer/.claude/agents/coder.md.example +2 -83
  128. package/templates/root-consumer/.claude/agents/extractor.md.example +2 -231
  129. package/templates/root-consumer/.claude/agents/polisher.md.example +2 -132
  130. package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +2 -81
  131. package/templates/root-consumer/.claude/commands/grill.md.example +30 -0
  132. package/templates/root-consumer/.claude/commands/techdebt.md.example +28 -0
  133. package/templates/root-consumer/.clinerules.example +1 -0
  134. package/templates/root-consumer/.cursor/rules/no-docs.mdc.example +15 -0
  135. package/templates/root-consumer/.cursorrules.example +1 -0
  136. package/templates/root-consumer/.github/copilot-instructions.md.example +1 -0
  137. package/templates/root-consumer/.windsurfrules.example +1 -0
  138. package/templates/root-consumer/AI.md.example +44 -123
  139. package/templates/root-consumer/CLAUDE.md.example +1 -134
  140. package/templates/root-consumer/CONVENTIONS.md.example +1 -0
  141. package/templates/root-consumer/GEMINI.md.example +1 -0
  142. package/templates/root-consumer/firebase.json.example +1 -1
  143. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +22 -2
  144. package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +0 -18
  145. package/templates/root-consumer/guides/dndev/COMPONENTS_UI.md.example +1 -1
  146. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +101 -32
  147. package/templates/root-consumer/guides/dndev/INDEX.md.example +4 -2
  148. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  149. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +241 -12
  150. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +13 -7
  151. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +60 -0
  152. package/templates/root-consumer/guides/dndev/SETUP_SOC2.md.example +234 -0
  153. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +62 -0
  154. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -0
  155. package/templates/root-consumer/guides/dndev/SETUP_THEMES.md.example +6 -2
  156. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +176 -0
  157. package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +5 -9
  158. package/templates/root-consumer/guides/dndev/essences_reference.css.example +174 -0
  159. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +7 -8
  160. package/templates/root-consumer/guides/wai-way/agents/builder.md.example +10 -0
  161. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +25 -5
  162. package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +13 -2
  163. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +2 -2
  164. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +55 -15
  165. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +15 -4
  166. package/templates/root-consumer/guides/wai-way/spec_template.md.example +7 -6
  167. package/dist/bin/commands/lint.d.ts +0 -11
  168. package/dist/bin/commands/lint.d.ts.map +0 -1
  169. package/dist/bin/commands/lint.js.map +0 -1
  170. package/dist/bin/commands/staging.d.ts +0 -11
  171. package/dist/bin/commands/staging.d.ts.map +0 -1
  172. package/dist/bin/commands/staging.js +0 -12
  173. package/dist/bin/commands/staging.js.map +0 -1
  174. package/templates/app-payload/.env.example +0 -28
  175. package/templates/app-payload/README.md.example +0 -233
  176. package/templates/app-payload/collections/Company.ts.example +0 -125
  177. package/templates/app-payload/collections/Hero.ts.example +0 -62
  178. package/templates/app-payload/collections/Media.ts.example +0 -41
  179. package/templates/app-payload/collections/Products.ts.example +0 -115
  180. package/templates/app-payload/collections/Services.ts.example +0 -104
  181. package/templates/app-payload/collections/Testimonials.ts.example +0 -92
  182. package/templates/app-payload/collections/Users.ts.example +0 -35
  183. package/templates/app-payload/src/server.ts.example +0 -79
  184. package/templates/app-payload/tsconfig.json.example +0 -24
@@ -0,0 +1,7 @@
1
+ // supabase/functions/get-user-auth-status/index.ts
2
+ // Supabase Edge Function — Get User Auth Status
3
+ // Deploy: supabase functions deploy get-user-auth-status
4
+
5
+ import { createGetUserAuthStatus } from '@donotdev/functions/supabase';
6
+
7
+ Deno.serve(createGetUserAuthStatus());
@@ -0,0 +1,7 @@
1
+ // supabase/functions/refresh-subscription-status/index.ts
2
+ // Supabase Edge Function — Refresh Subscription Status
3
+ // Deploy: supabase functions deploy refresh-subscription-status
4
+
5
+ import { createRefreshSubscriptionStatus } from '@donotdev/functions/supabase';
6
+
7
+ Deno.serve(createRefreshSubscriptionStatus());
@@ -0,0 +1,7 @@
1
+ // supabase/functions/remove-custom-claims/index.ts
2
+ // Supabase Edge Function — Remove Custom Claims from app_metadata
3
+ // Deploy: supabase functions deploy remove-custom-claims
4
+
5
+ import { createRemoveCustomClaims } from '@donotdev/functions/supabase';
6
+
7
+ Deno.serve(createRemoveCustomClaims());
@@ -0,0 +1,7 @@
1
+ // supabase/functions/set-custom-claims/index.ts
2
+ // Supabase Edge Function — Set Custom Claims (app_metadata)
3
+ // Deploy: supabase functions deploy set-custom-claims
4
+
5
+ import { createSetCustomClaims } from '@donotdev/functions/supabase';
6
+
7
+ Deno.serve(createSetCustomClaims());
@@ -0,0 +1,24 @@
1
+ -- Migration: Create idempotency table for Supabase CRUD operations
2
+ -- Generated: 2026-02-19
3
+ -- Purpose: Store operation results to prevent duplicate processing
4
+ -- TTL: 24 hours default, configurable per operation
5
+
6
+ CREATE TABLE IF NOT EXISTS idempotency (
7
+ id TEXT PRIMARY KEY, -- Format: "{operation}_{idempotencyKey}"
8
+ operation TEXT NOT NULL, -- 'create', 'update', 'delete', etc.
9
+ idempotency_key TEXT NOT NULL UNIQUE, -- Client-provided key
10
+ result JSONB NOT NULL, -- Cached operation result
11
+ processed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
12
+ processed_by TEXT NOT NULL, -- User ID
13
+ expires_at TIMESTAMPTZ NOT NULL -- TTL for cleanup (default: 24h)
14
+ );
15
+
16
+ -- Indexes for efficient lookups
17
+ CREATE INDEX IF NOT EXISTS idx_idempotency_expires ON idempotency(expires_at);
18
+ CREATE INDEX IF NOT EXISTS idx_idempotency_key ON idempotency(idempotency_key);
19
+ CREATE INDEX IF NOT EXISTS idx_idempotency_operation ON idempotency(operation, expires_at);
20
+
21
+ -- Comments
22
+ COMMENT ON TABLE idempotency IS 'Stores idempotency keys and cached operation results to prevent duplicate processing';
23
+ COMMENT ON COLUMN idempotency.id IS 'Composite key: {operation}_{idempotencyKey}';
24
+ COMMENT ON COLUMN idempotency.expires_at IS 'TTL for automatic cleanup - defaults to 24 hours from processed_at';
@@ -0,0 +1,22 @@
1
+ -- Migration: Create rate_limits table for Supabase Edge Functions
2
+ -- Generated: 2026-02-19
3
+ -- Purpose: Track API call rates per user/IP to prevent abuse
4
+ -- Pattern: Same as Firebase Firestore rateLimits collection
5
+
6
+ CREATE TABLE IF NOT EXISTS rate_limits (
7
+ key TEXT PRIMARY KEY, -- Format: "{operation}_{identifier}" (e.g., "create_apartment_uid_123")
8
+ attempts INTEGER NOT NULL DEFAULT 1,
9
+ window_start TIMESTAMPTZ NOT NULL DEFAULT now(),
10
+ block_until TIMESTAMPTZ, -- NULL if not blocked
11
+ last_updated TIMESTAMPTZ NOT NULL DEFAULT now()
12
+ );
13
+
14
+ -- Indexes for efficient lookups and cleanup
15
+ CREATE INDEX IF NOT EXISTS idx_rate_limits_window ON rate_limits(window_start);
16
+ CREATE INDEX IF NOT EXISTS idx_rate_limits_block ON rate_limits(block_until) WHERE block_until IS NOT NULL;
17
+ CREATE INDEX IF NOT EXISTS idx_rate_limits_updated ON rate_limits(last_updated);
18
+
19
+ -- Comments
20
+ COMMENT ON TABLE rate_limits IS 'Tracks API call rates per operation and identifier (user ID or IP)';
21
+ COMMENT ON COLUMN rate_limits.key IS 'Composite key: {operation}_{identifier_type}_{identifier_value}';
22
+ COMMENT ON COLUMN rate_limits.block_until IS 'Timestamp when rate limit block expires (NULL if not blocked)';
@@ -0,0 +1,28 @@
1
+ -- Migration: Create cleanup cron jobs for idempotency and rate_limits tables
2
+ -- Generated: 2026-02-19
3
+ -- Purpose: Automatically clean up expired records to prevent table bloat
4
+ -- Schedule: Daily at 2 AM UTC (idempotency), 3 AM UTC (rate_limits), 4 AM UTC (metrics)
5
+
6
+ -- Enable pg_cron extension (if not already enabled)
7
+ CREATE EXTENSION IF NOT EXISTS pg_cron;
8
+
9
+ -- Cleanup expired idempotency records (daily at 2 AM UTC)
10
+ SELECT cron.schedule(
11
+ 'cleanup-idempotency',
12
+ '0 2 * * *',
13
+ $$DELETE FROM idempotency WHERE expires_at < now()$$
14
+ );
15
+
16
+ -- Cleanup old rate limit records (daily at 3 AM UTC)
17
+ SELECT cron.schedule(
18
+ 'cleanup-rate-limits',
19
+ '0 3 * * *',
20
+ $$DELETE FROM rate_limits WHERE window_start + interval '7 days' < now()$$
21
+ );
22
+
23
+ -- Cleanup old operation metrics (daily at 4 AM UTC)
24
+ SELECT cron.schedule(
25
+ 'cleanup-operation-metrics',
26
+ '0 4 * * *',
27
+ $$DELETE FROM operation_metrics WHERE timestamp < now() - interval '90 days'$$
28
+ );
@@ -0,0 +1,28 @@
1
+ -- Migration: Create operation_metrics table for Supabase Edge Functions monitoring
2
+ -- Generated: 2026-02-19
3
+ -- Purpose: Track operation success/failure rates, duration, and user activity
4
+ -- Retention: 90 days (configurable via cleanup job)
5
+
6
+ CREATE TABLE IF NOT EXISTS operation_metrics (
7
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
8
+ operation TEXT NOT NULL, -- e.g., 'create_apartment', 'get_user'
9
+ user_id TEXT, -- NULL for guest operations
10
+ status TEXT NOT NULL, -- 'success', 'failed', 'pending'
11
+ duration_ms INTEGER, -- Operation duration in milliseconds
12
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT now(),
13
+ metadata JSONB, -- Additional context (request ID, etc.)
14
+ error_code TEXT, -- If status = 'failed'
15
+ error_message TEXT -- If status = 'failed'
16
+ );
17
+
18
+ -- Indexes for efficient queries
19
+ CREATE INDEX IF NOT EXISTS idx_metrics_operation ON operation_metrics(operation, timestamp DESC);
20
+ CREATE INDEX IF NOT EXISTS idx_metrics_user ON operation_metrics(user_id, timestamp DESC) WHERE user_id IS NOT NULL;
21
+ CREATE INDEX IF NOT EXISTS idx_metrics_status ON operation_metrics(status, timestamp DESC);
22
+ CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON operation_metrics(timestamp DESC);
23
+
24
+ -- Comments
25
+ COMMENT ON TABLE operation_metrics IS 'Tracks operation metrics for monitoring and analytics';
26
+ COMMENT ON COLUMN operation_metrics.operation IS 'Operation name (e.g., create_apartment, get_user)';
27
+ COMMENT ON COLUMN operation_metrics.duration_ms IS 'Operation duration in milliseconds';
28
+ COMMENT ON COLUMN operation_metrics.metadata IS 'Additional context as JSON (request ID, etc.)';
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
2
+ "extends": "../../../tsconfig.functions.json",
3
3
  "compilerOptions": {
4
4
  "outDir": "./lib",
5
5
  "rootDir": "./src",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "functions": {
3
3
  "src/api/**/*.ts": {
4
- "runtime": "nodejs20.x"
4
+ "runtime": "nodejs22.x"
5
5
  }
6
6
  },
7
7
  "env": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "functions": {
3
3
  "src/api/**/*.ts": {
4
- "runtime": "nodejs20.x"
4
+ "runtime": "nodejs22.x"
5
5
  }
6
6
  },
7
7
  "env": {
@@ -32,7 +32,7 @@ jobs:
32
32
  - name: Set up Node.js
33
33
  uses: actions/setup-node@v4
34
34
  with:
35
- node-version: '20' # Using Node 20
35
+ node-version: '22' # Using Node 22 LTS
36
36
 
37
37
  # Step 5: Setup Bun
38
38
  - name: Install Bun
@@ -32,7 +32,7 @@ jobs:
32
32
  - name: Set up Node.js
33
33
  uses: actions/setup-node@v4
34
34
  with:
35
- node-version: '20' # Using Node 20
35
+ node-version: '22' # Using Node 22 LTS
36
36
 
37
37
  # Step 5: Setup Bun
38
38
  - name: Install Bun
@@ -0,0 +1,34 @@
1
+
2
+ # =============================================================================
3
+ # Firebase Configuration
4
+ # =============================================================================
5
+ # Get these values from your Firebase project settings
6
+ # Run `dndev setup firebase` to auto-populate, or copy from Firebase Console
7
+ VITE_FIREBASE_API_KEY=
8
+ VITE_FIREBASE_PROJECT_ID=
9
+ # Copy from Firebase Console. Framework uses APP_URL hostname in production automatically.
10
+ VITE_FIREBASE_AUTH_DOMAIN=
11
+ VITE_FIREBASE_STORAGE_BUCKET=
12
+ VITE_FIREBASE_MESSAGING_SENDER_ID=
13
+ VITE_FIREBASE_APP_ID=
14
+ VITE_FIREBASE_MEASUREMENT_ID=
15
+ VITE_FIREBASE_FUNCTIONS_REGION=
16
+
17
+ # =============================================================================
18
+ # Firebase Emulator (Development only)
19
+ # =============================================================================
20
+ # Set to true to use Firebase emulators instead of production services
21
+ VITE_USE_FIREBASE_EMULATOR=false
22
+ VITE_FIREBASE_EMULATOR_HOST=localhost
23
+ VITE_FIREBASE_EMULATOR_PORT=9099
24
+ VITE_FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
25
+ VITE_FIREBASE_FIRESTORE_EMULATOR_HOST=localhost:8080
26
+ VITE_FIREBASE_FUNCTIONS_EMULATOR_PORT=5001
27
+
28
+ # =============================================================================
29
+ # Firebase App Check (Abuse Protection)
30
+ # =============================================================================
31
+ # reCAPTCHA v3 site key for App Check
32
+ # VITE_RECAPTCHA_SITE_KEY=6LcXXXX...
33
+ # Optional: Debug token for localhost testing
34
+ # VITE_APPCHECK_DEBUG_TOKEN=XXXX-XXXX-XXXX
@@ -0,0 +1,34 @@
1
+
2
+ # =============================================================================
3
+ # Firebase Configuration
4
+ # =============================================================================
5
+ # Get these values from your Firebase project settings
6
+ # Run `dndev setup firebase` to auto-populate, or copy from Firebase Console
7
+ EXPO_PUBLIC_FIREBASE_API_KEY=
8
+ EXPO_PUBLIC_FIREBASE_PROJECT_ID=
9
+ # Copy from Firebase Console. Framework uses APP_URL hostname in production automatically.
10
+ EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN=
11
+ EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET=
12
+ EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
13
+ EXPO_PUBLIC_FIREBASE_APP_ID=
14
+ EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID=
15
+ EXPO_PUBLIC_FIREBASE_FUNCTIONS_REGION=
16
+
17
+ # =============================================================================
18
+ # Firebase Emulator (Development only)
19
+ # =============================================================================
20
+ # Set to true to use Firebase emulators instead of production services
21
+ EXPO_PUBLIC_USE_FIREBASE_EMULATOR=false
22
+ EXPO_PUBLIC_FIREBASE_EMULATOR_HOST=localhost
23
+ EXPO_PUBLIC_FIREBASE_EMULATOR_PORT=9099
24
+ EXPO_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
25
+ EXPO_PUBLIC_FIREBASE_FIRESTORE_EMULATOR_HOST=localhost:8080
26
+ EXPO_PUBLIC_FIREBASE_FUNCTIONS_EMULATOR_PORT=5001
27
+
28
+ # =============================================================================
29
+ # Firebase App Check (Abuse Protection)
30
+ # =============================================================================
31
+ # reCAPTCHA v3 site key for App Check
32
+ # EXPO_PUBLIC_RECAPTCHA_SITE_KEY=6LcXXXX...
33
+ # Optional: Debug token for localhost testing
34
+ # EXPO_PUBLIC_APPCHECK_DEBUG_TOKEN=XXXX-XXXX-XXXX
@@ -0,0 +1,34 @@
1
+
2
+ # =============================================================================
3
+ # Firebase Configuration
4
+ # =============================================================================
5
+ # Get these values from your Firebase project settings
6
+ # Run `dndev setup firebase` to auto-populate, or copy from Firebase Console
7
+ NEXT_PUBLIC_FIREBASE_API_KEY=
8
+ NEXT_PUBLIC_FIREBASE_PROJECT_ID=
9
+ # Copy from Firebase Console. Framework uses APP_URL hostname in production automatically.
10
+ NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
11
+ NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
12
+ NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
13
+ NEXT_PUBLIC_FIREBASE_APP_ID=
14
+ NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=
15
+ NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION=
16
+
17
+ # =============================================================================
18
+ # Firebase Emulator (Development only)
19
+ # =============================================================================
20
+ # Set to true to use Firebase emulators instead of production services
21
+ NEXT_PUBLIC_USE_FIREBASE_EMULATOR=false
22
+ NEXT_PUBLIC_FIREBASE_EMULATOR_HOST=localhost
23
+ NEXT_PUBLIC_FIREBASE_EMULATOR_PORT=9099
24
+ NEXT_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
25
+ NEXT_PUBLIC_FIREBASE_FIRESTORE_EMULATOR_HOST=localhost:8080
26
+ NEXT_PUBLIC_FIREBASE_FUNCTIONS_EMULATOR_PORT=5001
27
+
28
+ # =============================================================================
29
+ # Firebase App Check (Abuse Protection)
30
+ # =============================================================================
31
+ # reCAPTCHA v3 site key for App Check
32
+ # NEXT_PUBLIC_RECAPTCHA_SITE_KEY=6LcXXXX...
33
+ # Optional: Debug token for localhost testing
34
+ # NEXT_PUBLIC_APPCHECK_DEBUG_TOKEN=XXXX-XXXX-XXXX
@@ -0,0 +1,49 @@
1
+ // src/config/providers.ts — Firebase provider bootstrap (Expo)
2
+ // Auto-generated by DoNotDev scaffolding. Edit freely.
3
+ // Import from root layout (app/_layout.tsx): import '../src/config/providers';
4
+
5
+ import { initializeApp } from 'firebase/app';
6
+
7
+ import { configureProviders } from '@donotdev/core';
8
+ import {
9
+ FirestoreAdapter,
10
+ FirebaseAuth,
11
+ FirebaseStorageAdapter,
12
+ } from '@donotdev/firebase';
13
+ import { initializeExpoAuth } from '@donotdev/expo';
14
+
15
+ const apiKey = process.env.EXPO_PUBLIC_FIREBASE_API_KEY;
16
+ const projectId = process.env.EXPO_PUBLIC_FIREBASE_PROJECT_ID;
17
+
18
+ if (!apiKey || !projectId) {
19
+ throw new Error(
20
+ '[dndev] Missing Firebase env vars (EXPO_PUBLIC_FIREBASE_API_KEY, EXPO_PUBLIC_FIREBASE_PROJECT_ID). ' +
21
+ 'Copy .env.example to .env and fill in your Firebase config.'
22
+ );
23
+ }
24
+
25
+ const firebaseConfig = {
26
+ apiKey,
27
+ projectId,
28
+ authDomain: process.env.EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN,
29
+ storageBucket: process.env.EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET,
30
+ messagingSenderId: process.env.EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
31
+ appId: process.env.EXPO_PUBLIC_FIREBASE_APP_ID,
32
+ };
33
+
34
+ initializeApp(firebaseConfig);
35
+ // Must run before FirebaseAuth — sets up AsyncStorage persistence
36
+ initializeExpoAuth();
37
+
38
+ /**
39
+ * Register Firebase as the backend provider.
40
+ * Must run before any CRUD/auth/storage operations.
41
+ *
42
+ * Uses EXPO_PUBLIC_FIREBASE_* env vars (not VITE_*).
43
+ * initializeExpoAuth() sets up AsyncStorage persistence before FirebaseAuth.
44
+ */
45
+ configureProviders({
46
+ crud: new FirestoreAdapter(),
47
+ auth: new FirebaseAuth(),
48
+ storage: new FirebaseStorageAdapter(),
49
+ });
@@ -0,0 +1,23 @@
1
+ // src/config/providers.ts — Firebase provider bootstrap
2
+ // Auto-generated by DoNotDev scaffolding. Edit freely.
3
+ // Import from root component (App.tsx): import './config/providers';
4
+
5
+ import { configureProviders } from '@donotdev/core';
6
+ import {
7
+ FirestoreAdapter,
8
+ FirebaseAuth,
9
+ FirebaseStorageAdapter,
10
+ } from '@donotdev/firebase';
11
+
12
+ /**
13
+ * Register Firebase as the backend provider.
14
+ * Must run before any CRUD/auth/storage operations.
15
+ *
16
+ * Firebase SDK is auto-initialized by the framework's Vite plugin
17
+ * from VITE_FIREBASE_* env vars — no `initializeApp()` needed here.
18
+ */
19
+ configureProviders({
20
+ crud: new FirestoreAdapter(),
21
+ auth: new FirebaseAuth(),
22
+ storage: new FirebaseStorageAdapter(),
23
+ });
@@ -0,0 +1,12 @@
1
+
2
+ # =============================================================================
3
+ # Supabase Configuration (PUBLIC — safe to commit)
4
+ # =============================================================================
5
+ # Get these from: https://supabase.com/dashboard > your project > Settings > API
6
+ # - Project URL: the https://xxx.supabase.co URL
7
+ # - Public key: "Publishable key" (sb_publishable_...) or legacy "anon key" (eyJ...)
8
+ #
9
+ # Then run: dndev setup supabase
10
+ # =============================================================================
11
+ VITE_SUPABASE_URL=
12
+ VITE_SUPABASE_PUBLIC_KEY=
@@ -0,0 +1,12 @@
1
+
2
+ # =============================================================================
3
+ # Supabase Configuration (PUBLIC — safe to commit)
4
+ # =============================================================================
5
+ # Get these from: https://supabase.com/dashboard > your project > Settings > API
6
+ # - Project URL: the https://xxx.supabase.co URL
7
+ # - Public key: "Publishable key" (sb_publishable_...) or legacy "anon key" (eyJ...)
8
+ #
9
+ # Then run: dndev setup supabase
10
+ # =============================================================================
11
+ EXPO_PUBLIC_SUPABASE_URL=
12
+ EXPO_PUBLIC_SUPABASE_PUBLIC_KEY=
@@ -0,0 +1,12 @@
1
+
2
+ # =============================================================================
3
+ # Supabase Configuration (PUBLIC — safe to commit)
4
+ # =============================================================================
5
+ # Get these from: https://supabase.com/dashboard > your project > Settings > API
6
+ # - Project URL: the https://xxx.supabase.co URL
7
+ # - Public key: "Publishable key" (sb_publishable_...) or legacy "anon key" (eyJ...)
8
+ #
9
+ # Then run: dndev setup supabase
10
+ # =============================================================================
11
+ NEXT_PUBLIC_SUPABASE_URL=
12
+ NEXT_PUBLIC_SUPABASE_PUBLIC_KEY=
@@ -0,0 +1,35 @@
1
+ // src/config/providers.ts — Supabase provider bootstrap (Expo)
2
+ // Auto-generated by DoNotDev scaffolding. Edit freely.
3
+ // Import from root layout (app/_layout.tsx): import '../src/config/providers';
4
+
5
+ import { createClient } from '@supabase/supabase-js';
6
+
7
+ import { configureProviders } from '@donotdev/core';
8
+ import {
9
+ SupabaseAuth,
10
+ SupabaseCrudAdapter,
11
+ SupabaseStorageAdapter,
12
+ } from '@donotdev/supabase';
13
+
14
+ const url = process.env.EXPO_PUBLIC_SUPABASE_URL;
15
+ const publicKey = process.env.EXPO_PUBLIC_SUPABASE_PUBLIC_KEY || process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY; // New: sb_publishable_..., Legacy: anon key
16
+
17
+ if (!url || !publicKey) {
18
+ console.warn(
19
+ '[dndev] Supabase not configured. Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY in .env'
20
+ );
21
+ } else {
22
+ const supabase = createClient(url, publicKey);
23
+
24
+ /**
25
+ * Register Supabase as the backend provider.
26
+ * Must run before any CRUD/auth/storage operations.
27
+ *
28
+ * Uses EXPO_PUBLIC_SUPABASE_* env vars (not VITE_*).
29
+ */
30
+ configureProviders({
31
+ crud: new SupabaseCrudAdapter(supabase),
32
+ auth: new SupabaseAuth(supabase),
33
+ storage: new SupabaseStorageAdapter(supabase),
34
+ });
35
+ }
@@ -0,0 +1,33 @@
1
+ // src/config/providers.ts — Supabase provider bootstrap
2
+ // Auto-generated by DoNotDev scaffolding. Edit freely.
3
+ // Import from root component (App.tsx): import './config/providers';
4
+
5
+ import { createClient } from '@supabase/supabase-js';
6
+
7
+ import { configureProviders } from '@donotdev/core';
8
+ import {
9
+ SupabaseAuth,
10
+ SupabaseCrudAdapter,
11
+ SupabaseStorageAdapter,
12
+ } from '@donotdev/supabase';
13
+
14
+ const url = import.meta.env.VITE_SUPABASE_URL;
15
+ const publicKey = import.meta.env.VITE_SUPABASE_PUBLIC_KEY || import.meta.env.VITE_SUPABASE_ANON_KEY; // New: sb_publishable_..., Legacy: anon key
16
+
17
+ if (!url || !publicKey) {
18
+ console.warn(
19
+ '[dndev] Supabase not configured. Set VITE_SUPABASE_URL and VITE_SUPABASE_PUBLIC_KEY (or VITE_SUPABASE_ANON_KEY) in .env'
20
+ );
21
+ } else {
22
+ const supabase = createClient(url, publicKey);
23
+
24
+ /**
25
+ * Register Supabase as the backend provider.
26
+ * Must run before any CRUD/auth/storage operations.
27
+ */
28
+ configureProviders({
29
+ crud: new SupabaseCrudAdapter(supabase),
30
+ auth: new SupabaseAuth(supabase),
31
+ storage: new SupabaseStorageAdapter(supabase),
32
+ });
33
+ }
@@ -0,0 +1,23 @@
1
+ [
2
+ {
3
+ "source": "/(.*)",
4
+ "headers": [
5
+ {
6
+ "key": "Content-Security-Policy",
7
+ "value": "default-src 'self'; script-src 'self' https://js.stripe.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.stripe.com; frame-src 'none' https://js.stripe.com https://hooks.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self'"
8
+ },
9
+ {
10
+ "key": "X-Content-Type-Options",
11
+ "value": "nosniff"
12
+ },
13
+ {
14
+ "key": "X-Frame-Options",
15
+ "value": "DENY"
16
+ },
17
+ {
18
+ "key": "Referrer-Policy",
19
+ "value": "strict-origin-when-cross-origin"
20
+ }
21
+ ]
22
+ }
23
+ ]
@@ -0,0 +1,22 @@
1
+ {
2
+ "buildCommand": "bun run build",
3
+ "outputDirectory": "dist",
4
+ "installCommand": "bun install",
5
+ "rewrites": [
6
+ { "source": "/(.*)", "destination": "/index.html" }
7
+ ],
8
+ "headers": [
9
+ {
10
+ "source": "/(.*)",
11
+ "headers": [
12
+ {
13
+ "key": "Content-Security-Policy",
14
+ "value": "default-src 'self'; script-src 'self' https://js.stripe.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.stripe.com; frame-src 'none' https://js.stripe.com https://hooks.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self'"
15
+ },
16
+ { "key": "X-Content-Type-Options", "value": "nosniff" },
17
+ { "key": "X-Frame-Options", "value": "DENY" },
18
+ { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
19
+ ]
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,34 @@
1
+
2
+ # =============================================================================
3
+ # Firebase Configuration (data layer for Vercel-hosted app)
4
+ # =============================================================================
5
+ # Get these values from your Firebase project settings
6
+ # Run `dndev setup firebase` to auto-populate, or copy from Firebase Console
7
+ VITE_FIREBASE_API_KEY=
8
+ VITE_FIREBASE_PROJECT_ID=
9
+ # Copy from Firebase Console. Framework uses APP_URL hostname in production automatically.
10
+ VITE_FIREBASE_AUTH_DOMAIN=
11
+ VITE_FIREBASE_STORAGE_BUCKET=
12
+ VITE_FIREBASE_MESSAGING_SENDER_ID=
13
+ VITE_FIREBASE_APP_ID=
14
+ VITE_FIREBASE_MEASUREMENT_ID=
15
+ VITE_FIREBASE_FUNCTIONS_REGION=
16
+
17
+ # =============================================================================
18
+ # Firebase Emulator (Development only)
19
+ # =============================================================================
20
+ # Set to true to use Firebase emulators instead of production services
21
+ VITE_USE_FIREBASE_EMULATOR=false
22
+ VITE_FIREBASE_EMULATOR_HOST=localhost
23
+ VITE_FIREBASE_EMULATOR_PORT=9099
24
+ VITE_FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
25
+ VITE_FIREBASE_FIRESTORE_EMULATOR_HOST=localhost:8080
26
+ VITE_FIREBASE_FUNCTIONS_EMULATOR_PORT=5001
27
+
28
+ # =============================================================================
29
+ # Firebase App Check (Abuse Protection)
30
+ # =============================================================================
31
+ # reCAPTCHA v3 site key for App Check
32
+ # VITE_RECAPTCHA_SITE_KEY=6LcXXXX...
33
+ # Optional: Debug token for localhost testing
34
+ # VITE_APPCHECK_DEBUG_TOKEN=XXXX-XXXX-XXXX
@@ -0,0 +1,34 @@
1
+
2
+ # =============================================================================
3
+ # Firebase Configuration (data layer for Vercel-hosted app)
4
+ # =============================================================================
5
+ # Get these values from your Firebase project settings
6
+ # Run `dndev setup firebase` to auto-populate, or copy from Firebase Console
7
+ NEXT_PUBLIC_FIREBASE_API_KEY=
8
+ NEXT_PUBLIC_FIREBASE_PROJECT_ID=
9
+ # Copy from Firebase Console. Framework uses APP_URL hostname in production automatically.
10
+ NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
11
+ NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
12
+ NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
13
+ NEXT_PUBLIC_FIREBASE_APP_ID=
14
+ NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=
15
+ NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION=
16
+
17
+ # =============================================================================
18
+ # Firebase Emulator (Development only)
19
+ # =============================================================================
20
+ # Set to true to use Firebase emulators instead of production services
21
+ NEXT_PUBLIC_USE_FIREBASE_EMULATOR=false
22
+ NEXT_PUBLIC_FIREBASE_EMULATOR_HOST=localhost
23
+ NEXT_PUBLIC_FIREBASE_EMULATOR_PORT=9099
24
+ NEXT_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
25
+ NEXT_PUBLIC_FIREBASE_FIRESTORE_EMULATOR_HOST=localhost:8080
26
+ NEXT_PUBLIC_FIREBASE_FUNCTIONS_EMULATOR_PORT=5001
27
+
28
+ # =============================================================================
29
+ # Firebase App Check (Abuse Protection)
30
+ # =============================================================================
31
+ # reCAPTCHA v3 site key for App Check
32
+ # NEXT_PUBLIC_RECAPTCHA_SITE_KEY=6LcXXXX...
33
+ # Optional: Debug token for localhost testing
34
+ # NEXT_PUBLIC_APPCHECK_DEBUG_TOKEN=XXXX-XXXX-XXXX
@@ -0,0 +1,24 @@
1
+ // src/config/providers.ts — Vercel + Firebase provider bootstrap
2
+ // Auto-generated by DoNotDev scaffolding. Edit freely.
3
+ // Import from root component (App.tsx): import './config/providers';
4
+
5
+ import { configureProviders } from '@donotdev/core';
6
+ import {
7
+ FirestoreAdapter,
8
+ FirebaseAuth,
9
+ FirebaseStorageAdapter,
10
+ } from '@donotdev/firebase';
11
+
12
+ /**
13
+ * Register Firebase as the data provider for a Vercel-hosted app.
14
+ * Vercel handles hosting + API routes; Firebase provides CRUD/auth/storage.
15
+ * Must run before any CRUD/auth/storage operations.
16
+ *
17
+ * Firebase SDK is auto-initialized by the framework's Vite plugin
18
+ * from VITE_FIREBASE_* env vars — no `initializeApp()` needed here.
19
+ */
20
+ configureProviders({
21
+ crud: new FirestoreAdapter(),
22
+ auth: new FirebaseAuth(),
23
+ storage: new FirebaseStorageAdapter(),
24
+ });