@react-spa-scaffold/mcp 2.1.1 → 2.3.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.
Files changed (168) hide show
  1. package/README.md +2 -1
  2. package/dist/constants.d.ts +4 -0
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +4 -0
  5. package/dist/constants.js.map +1 -1
  6. package/dist/features/definitions/auth.d.ts +3 -0
  7. package/dist/features/definitions/auth.d.ts.map +1 -0
  8. package/dist/features/definitions/auth.js +17 -0
  9. package/dist/features/definitions/auth.js.map +1 -0
  10. package/dist/features/definitions/core.d.ts.map +1 -1
  11. package/dist/features/definitions/core.js +16 -1
  12. package/dist/features/definitions/core.js.map +1 -1
  13. package/dist/features/definitions/database.d.ts +3 -0
  14. package/dist/features/definitions/database.d.ts.map +1 -0
  15. package/dist/features/definitions/database.js +45 -0
  16. package/dist/features/definitions/database.js.map +1 -0
  17. package/dist/features/definitions/deployment.d.ts +3 -0
  18. package/dist/features/definitions/deployment.d.ts.map +1 -0
  19. package/dist/features/definitions/deployment.js +14 -0
  20. package/dist/features/definitions/deployment.js.map +1 -0
  21. package/dist/features/definitions/forms.d.ts.map +1 -1
  22. package/dist/features/definitions/forms.js +4 -0
  23. package/dist/features/definitions/forms.js.map +1 -1
  24. package/dist/features/definitions/index.d.ts +3 -0
  25. package/dist/features/definitions/index.d.ts.map +1 -1
  26. package/dist/features/definitions/index.js +3 -0
  27. package/dist/features/definitions/index.js.map +1 -1
  28. package/dist/features/definitions/mobile.d.ts.map +1 -1
  29. package/dist/features/definitions/mobile.js +11 -2
  30. package/dist/features/definitions/mobile.js.map +1 -1
  31. package/dist/features/definitions/observability.js +1 -1
  32. package/dist/features/definitions/observability.js.map +1 -1
  33. package/dist/features/definitions/routing.d.ts.map +1 -1
  34. package/dist/features/definitions/routing.js +2 -1
  35. package/dist/features/definitions/routing.js.map +1 -1
  36. package/dist/features/definitions/state.d.ts.map +1 -1
  37. package/dist/features/definitions/state.js +9 -2
  38. package/dist/features/definitions/state.js.map +1 -1
  39. package/dist/features/definitions/testing.d.ts.map +1 -1
  40. package/dist/features/definitions/testing.js +4 -2
  41. package/dist/features/definitions/testing.js.map +1 -1
  42. package/dist/features/registry.d.ts.map +1 -1
  43. package/dist/features/registry.js +4 -1
  44. package/dist/features/registry.js.map +1 -1
  45. package/dist/features/types.test.js +6 -2
  46. package/dist/features/types.test.js.map +1 -1
  47. package/dist/resources/docs.d.ts.map +1 -1
  48. package/dist/resources/docs.js +5 -0
  49. package/dist/resources/docs.js.map +1 -1
  50. package/dist/tools/add-features.js +1 -1
  51. package/dist/tools/add-features.js.map +1 -1
  52. package/dist/utils/docs.d.ts.map +1 -1
  53. package/dist/utils/docs.js +2 -0
  54. package/dist/utils/docs.js.map +1 -1
  55. package/dist/utils/scaffold/claude-md/index.d.ts.map +1 -1
  56. package/dist/utils/scaffold/claude-md/index.js +3 -1
  57. package/dist/utils/scaffold/claude-md/index.js.map +1 -1
  58. package/dist/utils/scaffold/claude-md/sections.d.ts +2 -0
  59. package/dist/utils/scaffold/claude-md/sections.d.ts.map +1 -1
  60. package/dist/utils/scaffold/claude-md/sections.js +132 -2
  61. package/dist/utils/scaffold/claude-md/sections.js.map +1 -1
  62. package/dist/utils/scaffold/compute.js +1 -1
  63. package/dist/utils/scaffold/compute.js.map +1 -1
  64. package/dist/utils/scaffold/generators.d.ts +2 -2
  65. package/dist/utils/scaffold/generators.d.ts.map +1 -1
  66. package/dist/utils/scaffold/generators.js +64 -22
  67. package/dist/utils/scaffold/generators.js.map +1 -1
  68. package/package.json +1 -1
  69. package/templates/.env.example +44 -10
  70. package/templates/.github/workflows/ci.yml +12 -4
  71. package/templates/.github/workflows/deploy.yml +59 -0
  72. package/templates/CLAUDE.md +251 -2
  73. package/templates/docs/ARCHITECTURE.md +13 -12
  74. package/templates/docs/AUTHENTICATION.md +325 -0
  75. package/templates/docs/CODING_STANDARDS.md +65 -0
  76. package/templates/docs/DEPLOYMENT.md +268 -0
  77. package/templates/docs/E2E_TESTING.md +133 -11
  78. package/templates/docs/SUPABASE_INTEGRATION.md +310 -0
  79. package/templates/docs/TESTING.md +195 -77
  80. package/templates/e2e/auth/auth.setup.ts +60 -0
  81. package/templates/e2e/fixtures/index.ts +24 -2
  82. package/templates/e2e/tests/profile.auth.spec.ts +103 -0
  83. package/templates/e2e/tests/profile.spec.ts +64 -0
  84. package/templates/e2e/tests/register-form.spec.ts +38 -0
  85. package/templates/gitignore +5 -0
  86. package/templates/package.json +15 -3
  87. package/templates/playwright.config.ts +39 -4
  88. package/templates/src/App.tsx +32 -19
  89. package/templates/src/components/layout/Header.test.tsx +17 -1
  90. package/templates/src/components/layout/Header.tsx +13 -1
  91. package/templates/src/components/shared/AccountButton/AccountButton.test.tsx +30 -0
  92. package/templates/src/components/shared/AccountButton/AccountButton.tsx +38 -0
  93. package/templates/src/components/shared/AccountButton/index.ts +1 -0
  94. package/templates/src/components/shared/ErrorBoundary/ErrorBoundary.test.tsx +4 -4
  95. package/templates/src/components/shared/ErrorBoundary/ErrorBoundary.tsx +55 -53
  96. package/templates/src/components/shared/ProfileSync/ProfileSync.test.tsx +44 -0
  97. package/templates/src/components/shared/ProfileSync/ProfileSync.tsx +104 -0
  98. package/templates/src/components/shared/ProfileSync/index.ts +1 -0
  99. package/templates/src/components/shared/ProtectedRoute/ProtectedRoute.test.tsx +43 -0
  100. package/templates/src/components/shared/ProtectedRoute/ProtectedRoute.tsx +35 -0
  101. package/templates/src/components/shared/ProtectedRoute/index.ts +1 -0
  102. package/templates/src/components/shared/index.ts +5 -2
  103. package/templates/src/contexts/clerkContext.tsx +45 -0
  104. package/templates/src/contexts/performanceContext.tsx +3 -3
  105. package/templates/src/contexts/supabaseContext.test.tsx +59 -0
  106. package/templates/src/contexts/supabaseContext.tsx +87 -0
  107. package/templates/src/hooks/index.ts +40 -2
  108. package/templates/src/hooks/supabase/index.ts +12 -0
  109. package/templates/src/hooks/supabase/useProfiles.test.tsx +207 -0
  110. package/templates/src/hooks/supabase/useProfiles.ts +213 -0
  111. package/templates/src/hooks/supabase/useSupabaseQuery.test.tsx +150 -0
  112. package/templates/src/hooks/supabase/useSupabaseQuery.ts +91 -0
  113. package/templates/src/hooks/useCopyFeedback.test.ts +129 -0
  114. package/templates/src/hooks/useCopyFeedback.ts +41 -0
  115. package/templates/src/hooks/useDebouncedCallback.test.ts +164 -0
  116. package/templates/src/hooks/useDebouncedCallback.ts +47 -0
  117. package/templates/src/hooks/useDocumentTitle.test.ts +59 -0
  118. package/templates/src/hooks/useDocumentTitle.ts +31 -0
  119. package/templates/src/hooks/useIOSViewportReset.test.ts +58 -0
  120. package/templates/src/hooks/useIOSViewportReset.ts +18 -0
  121. package/templates/src/hooks/useKeyboardShortcut.test.ts +86 -0
  122. package/templates/src/hooks/useKeyboardShortcuts.ts +44 -0
  123. package/templates/src/hooks/useLocalStorage.test.ts +111 -0
  124. package/templates/src/hooks/useLocalStorage.ts +77 -0
  125. package/templates/src/hooks/useSyncedFormData.test.ts +75 -0
  126. package/templates/src/hooks/useSyncedFormData.ts +21 -0
  127. package/templates/src/hooks/useSyncedState.test.ts +119 -0
  128. package/templates/src/hooks/useSyncedState.ts +30 -0
  129. package/templates/src/index.css +1 -0
  130. package/templates/src/lib/api.test.ts +30 -38
  131. package/templates/src/lib/api.ts +1 -7
  132. package/templates/src/lib/config.ts +54 -4
  133. package/templates/src/lib/constants.ts +10 -0
  134. package/templates/src/lib/createSelectors.test.ts +136 -0
  135. package/templates/src/lib/createSelectors.ts +31 -0
  136. package/templates/src/lib/env.ts +36 -14
  137. package/templates/src/lib/index.ts +5 -2
  138. package/templates/src/lib/routes.ts +1 -0
  139. package/templates/src/lib/sentry.ts +58 -0
  140. package/templates/src/lib/storage.ts +6 -2
  141. package/templates/src/lib/supabase/client.ts +58 -0
  142. package/templates/src/lib/supabase/index.ts +5 -0
  143. package/templates/src/main.tsx +19 -31
  144. package/templates/src/mocks/constants.ts +31 -0
  145. package/templates/src/mocks/fixtures/index.ts +3 -1
  146. package/templates/src/mocks/fixtures/profiles.ts +55 -0
  147. package/templates/src/mocks/fixtures/users.ts +91 -0
  148. package/templates/src/mocks/handlers/index.ts +2 -1
  149. package/templates/src/mocks/handlers/supabase.ts +64 -0
  150. package/templates/src/mocks/handlers/todos.ts +1 -1
  151. package/templates/src/mocks/index.ts +6 -0
  152. package/templates/src/pages/Profile.test.tsx +263 -0
  153. package/templates/src/pages/Profile.tsx +171 -0
  154. package/templates/src/pages/index.ts +1 -0
  155. package/templates/src/stores/preferencesStore.ts +35 -9
  156. package/templates/src/test/clerkMock.tsx +137 -0
  157. package/templates/src/test/fetchMock.ts +58 -0
  158. package/templates/src/test/index.ts +51 -2
  159. package/templates/src/test/mocks.ts +128 -1
  160. package/templates/src/test/providers.tsx +10 -4
  161. package/templates/src/test/supabaseMock.ts +112 -0
  162. package/templates/src/test-setup.ts +42 -2
  163. package/templates/src/types/database.ts +46 -0
  164. package/templates/src/types/index.ts +1 -0
  165. package/templates/src/types/supabase.ts +167 -0
  166. package/templates/src/vite-env.d.ts +6 -0
  167. package/templates/supabase/migrations/20260104000000_create_profiles_table.sql +67 -0
  168. package/templates/vitest.config.ts +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAe5D,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAgBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAiB5D,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAkBR"}
@@ -2,7 +2,7 @@
2
2
  * CLAUDE.md generator - composes sections based on selected features.
3
3
  */
4
4
  import { FEATURE } from '../../../constants.js';
5
- import { generateHeader, generateCommandsSection, generateStructureSection, generateCodePatternsSection, generateUiSection, generateMobileSection, generateThemingSection, generateMcpSection, generateI18nSection, generateTestingSection, generateGotchasSection, } from './sections.js';
5
+ import { generateHeader, generateCommandsSection, generateStructureSection, generateCodePatternsSection, generateUiSection, generateMobileSection, generateThemingSection, generateAuthSection, generateDatabaseSection, generateMcpSection, generateI18nSection, generateTestingSection, generateGotchasSection, } from './sections.js';
6
6
  /** Generates CLAUDE.md content based on selected features. */
7
7
  export function generateClaudeMd(featureIds, projectName, scripts) {
8
8
  const sections = [
@@ -13,6 +13,8 @@ export function generateClaudeMd(featureIds, projectName, scripts) {
13
13
  featureIds.includes(FEATURE.UI) && generateUiSection(),
14
14
  featureIds.includes(FEATURE.MOBILE) && generateMobileSection(),
15
15
  featureIds.includes(FEATURE.THEMING) && generateThemingSection(),
16
+ featureIds.includes(FEATURE.AUTH) && generateAuthSection(),
17
+ featureIds.includes(FEATURE.DATABASE) && generateDatabaseSection(),
16
18
  generateMcpSection(featureIds),
17
19
  featureIds.includes(FEATURE.I18N) && generateI18nSection(),
18
20
  featureIds.includes(FEATURE.TESTING) && generateTestingSection(),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAC9B,UAAuB,EACvB,WAAmB,EACnB,OAA+B;IAE/B,MAAM,QAAQ,GAAG;QACf,cAAc,CAAC,WAAW,CAAC;QAC3B,uBAAuB,CAAC,OAAO,CAAC;QAChC,wBAAwB,CAAC,UAAU,CAAC;QACpC,2BAA2B,CAAC,UAAU,CAAC;QACvC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,iBAAiB,EAAE;QACtD,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,qBAAqB,EAAE;QAC9D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,kBAAkB,CAAC,UAAU,CAAC;QAC9B,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,EAAE;QAC1D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,sBAAsB,CAAC,UAAU,CAAC;KACnC,CAAC;IAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAC9B,UAAuB,EACvB,WAAmB,EACnB,OAA+B;IAE/B,MAAM,QAAQ,GAAG;QACf,cAAc,CAAC,WAAW,CAAC;QAC3B,uBAAuB,CAAC,OAAO,CAAC;QAChC,wBAAwB,CAAC,UAAU,CAAC;QACpC,2BAA2B,CAAC,UAAU,CAAC;QACvC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,iBAAiB,EAAE;QACtD,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,qBAAqB,EAAE;QAC9D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,EAAE;QAC1D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,uBAAuB,EAAE;QAClE,kBAAkB,CAAC,UAAU,CAAC;QAC9B,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,EAAE;QAC1D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,sBAAsB,CAAC,UAAU,CAAC;KACnC,CAAC;IAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
@@ -9,6 +9,8 @@ export declare function generateCodePatternsSection(featureIds: FeatureId[]): st
9
9
  export declare function generateUiSection(): string;
10
10
  export declare function generateMobileSection(): string;
11
11
  export declare function generateThemingSection(): string;
12
+ export declare function generateAuthSection(): string;
13
+ export declare function generateDatabaseSection(): string;
12
14
  export declare function generateMcpSection(featureIds: FeatureId[]): string;
13
15
  export declare function generateI18nSection(): string;
14
16
  export declare function generateTestingSection(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/sections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAqB5D,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAe/E;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAuCxE;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAkB3E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAmB1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAoC9C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAwClE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAY5C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAe/C;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAoBtE"}
1
+ {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/sections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAyB5D,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAe/E;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA6CxE;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAkB3E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAmB1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAoC9C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAsC5C;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CA0EhD;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAwClE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAY5C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAe/C;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA2BtE"}
@@ -19,6 +19,10 @@ const SCRIPT_DESCRIPTIONS = {
19
19
  'e2e:ui': 'Playwright UI mode',
20
20
  'i18n:extract': 'Extract translations to .po',
21
21
  prepare: 'Initialize Husky hooks',
22
+ 'db:types': 'Generate Supabase TypeScript types',
23
+ 'db:push': 'Push database migrations',
24
+ 'db:reset': 'Reset database (destructive)',
25
+ 'db:studio': 'Open Supabase Studio',
22
26
  };
23
27
  export function generateHeader(projectName) {
24
28
  return `# CLAUDE.md
@@ -42,7 +46,10 @@ ${commandLines.join('\n')}
42
46
  }
43
47
  export function generateStructureSection(featureIds) {
44
48
  const parts = ['src/', '├── components/ # ui/ (primitives), layout/, shared/ (features)'];
45
- if (featureIds.includes(FEATURE.API) || featureIds.includes(FEATURE.I18N) || featureIds.includes(FEATURE.MOBILE)) {
49
+ if (featureIds.includes(FEATURE.API) ||
50
+ featureIds.includes(FEATURE.I18N) ||
51
+ featureIds.includes(FEATURE.MOBILE) ||
52
+ featureIds.includes(FEATURE.DATABASE)) {
46
53
  parts.push('├── contexts/ # React Context providers');
47
54
  }
48
55
  parts.push('├── hooks/ # Custom hooks');
@@ -53,6 +60,8 @@ export function generateStructureSection(featureIds) {
53
60
  libParts.push('routes');
54
61
  if (featureIds.includes(FEATURE.STATE))
55
62
  libParts.push('storage');
63
+ if (featureIds.includes(FEATURE.DATABASE))
64
+ libParts.push('supabase');
56
65
  parts.push(`├── lib/ # ${libParts.join(', ')}`);
57
66
  if (featureIds.includes(FEATURE.ROUTING))
58
67
  parts.push('├── pages/ # Lazy-loaded route components');
@@ -180,6 +189,120 @@ const getResolvedTheme = usePreferencesStore((s) => s.getResolvedTheme);
180
189
  The \`useThemeEffect\` hook automatically applies the \`.dark\` class to the document.
181
190
  The ThemeToggle component provides a UI for switching between light, dark, and system themes.`;
182
191
  }
192
+ export function generateAuthSection() {
193
+ return `
194
+ ## Authentication (Clerk)
195
+
196
+ Clerk provides authentication with modal-based sign-in.
197
+
198
+ ### Setup
199
+
200
+ 1. Create an account at [clerk.com](https://clerk.com)
201
+ 2. Get your Publishable Key from the dashboard
202
+ 3. Set \`VITE_CLERK_PUBLISHABLE_KEY\` in \`.env\`
203
+
204
+ ### Usage
205
+
206
+ \`\`\`tsx
207
+ import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/react-router';
208
+ import { ProtectedRoute } from '@/components/shared';
209
+
210
+ // Conditional rendering
211
+ <SignedIn><UserButton /></SignedIn>
212
+ <SignedOut><SignInButton mode="modal"><Button>Sign In</Button></SignInButton></SignedOut>
213
+
214
+ // Protected routes
215
+ <Route path="/dashboard" element={<ProtectedRoute><DashboardPage /></ProtectedRoute>} />
216
+ \`\`\`
217
+
218
+ ### Testing
219
+
220
+ \`\`\`tsx
221
+ import { setMockClerkSignedIn, resetClerkMocks } from '@/test';
222
+
223
+ beforeEach(() => resetClerkMocks());
224
+
225
+ it('shows sign-in when not authenticated', () => {
226
+ setMockClerkSignedIn(false);
227
+ // ...
228
+ });
229
+ \`\`\``;
230
+ }
231
+ export function generateDatabaseSection() {
232
+ return `
233
+ ## Database (Supabase)
234
+
235
+ Supabase provides PostgreSQL with Row Level Security (RLS), integrated with Clerk authentication.
236
+
237
+ ### Setup
238
+
239
+ 1. Create a project at [supabase.com](https://supabase.com)
240
+ 2. Configure Clerk as third-party auth provider in Supabase Dashboard
241
+ 3. Enable Supabase integration in Clerk Dashboard → Integrations
242
+ 4. Set environment variables in \`.env\`:
243
+ - \`VITE_SUPABASE_DATABASE_URL\` - Your project URL
244
+ - \`VITE_SUPABASE_ANON_KEY\` - Your anon/public key
245
+ - \`SUPABASE_PROJECT_ID\` - Project ID for CLI (subdomain from your URL)
246
+
247
+ ### Usage
248
+
249
+ \`\`\`tsx
250
+ import { useSupabase, useSupabaseQuery, useProfile } from '@/hooks';
251
+
252
+ // Direct client access
253
+ const supabase = useSupabase();
254
+ const { data } = await supabase.from('profiles').select();
255
+
256
+ // TanStack Query wrapper
257
+ const { data, isLoading } = useSupabaseQuery({
258
+ table: 'profiles',
259
+ queryKey: ['current'],
260
+ });
261
+
262
+ // Current user's profile
263
+ const { profile, isLoading, exists } = useProfile();
264
+ \`\`\`
265
+
266
+ ### Profile Mutations
267
+
268
+ \`\`\`tsx
269
+ import { useUpsertProfile, useUpdateProfile, useDeleteProfile } from '@/hooks';
270
+
271
+ const upsertProfile = useUpsertProfile();
272
+ await upsertProfile.mutateAsync({ id: userId, email: 'user@example.com' });
273
+ \`\`\`
274
+
275
+ ### Auto-Sync
276
+
277
+ \`\`\`tsx
278
+ import { ProfileSync } from '@/components/shared';
279
+
280
+ // Add to app to auto-sync Clerk user to Supabase
281
+ <ProfileSync />
282
+ \`\`\`
283
+
284
+ ### Testing
285
+
286
+ \`\`\`tsx
287
+ import { render, setMockSupabaseData, setMockSupabaseError, createProfile, resetSupabaseMocks } from '@/test';
288
+
289
+ beforeEach(() => resetSupabaseMocks());
290
+
291
+ it('displays profile data', async () => {
292
+ setMockSupabaseData([createProfile({ full_name: 'Test User' })]);
293
+ render(<ProfileCard />);
294
+ // Assert profile is displayed
295
+ });
296
+
297
+ it('handles error', async () => {
298
+ setMockSupabaseError({ message: 'Failed', code: 'ERROR' });
299
+ render(<ProfileCard />);
300
+ // Assert error state
301
+ });
302
+ \`\`\`
303
+
304
+ See [docs/SUPABASE_INTEGRATION.md](docs/SUPABASE_INTEGRATION.md) for full details.`;
305
+ }
183
306
  export function generateMcpSection(featureIds) {
184
307
  let section = `
185
308
  ## MCP Servers (PREFER OVER WebSearch)
@@ -254,12 +377,19 @@ export function generateGotchasSection(featureIds) {
254
377
  gotchas.push('**Conventional commits** enforced by commitlint');
255
378
  }
256
379
  if (featureIds.includes(FEATURE.MOBILE)) {
257
- gotchas.push('**Context hooks throw** outside provider (e.g., `useMobileContext()`)');
380
+ gotchas.push('**Context hooks throw** outside provider (e.g., `useMobileContext()`, `useSupabase()`)');
258
381
  }
259
382
  gotchas.push('**Barrel exports** in each directory via `index.ts`');
260
383
  if (featureIds.includes(FEATURE.UI)) {
261
384
  gotchas.push('**UI components** import directly: `@/components/ui/button` (no barrel)');
262
385
  }
386
+ if (featureIds.includes(FEATURE.AUTH)) {
387
+ gotchas.push('**Clerk auth required** - set `VITE_CLERK_PUBLISHABLE_KEY` in `.env`');
388
+ }
389
+ if (featureIds.includes(FEATURE.DATABASE)) {
390
+ gotchas.push('**Supabase requires Clerk** - SupabaseProvider must be inside ClerkProvider');
391
+ gotchas.push('**RLS policies required** - All Supabase tables should have Row Level Security enabled');
392
+ }
263
393
  return `
264
394
  ## Common Gotchas
265
395
 
@@ -1 +1 @@
1
- {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/sections.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/sections.ts"],"names":[],"mappings":"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"}
@@ -49,7 +49,7 @@ export async function computeScaffold(selectedFeatures, projectName = 'my-app')
49
49
  const claudeMd = generateClaudeMd(resolvedFeatures, projectName, scripts);
50
50
  const viteEnvDts = generateViteEnvDts(resolvedFeatures);
51
51
  const envTs = generateEnvTs(resolvedFeatures);
52
- const routesTs = resolvedFeatures.includes(FEATURE.ROUTING) ? generateRoutesTs() : undefined;
52
+ const routesTs = resolvedFeatures.includes(FEATURE.ROUTING) ? generateRoutesTs(resolvedFeatures) : undefined;
53
53
  return {
54
54
  packageJson: { name: projectName, dependencies, devDependencies, scripts, engines },
55
55
  structure,
@@ -1 +1 @@
1
- {"version":3,"file":"compute.js","sourceRoot":"","sources":["../../../src/utils/scaffold/compute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compute.js","sourceRoot":"","sources":["../../../src/utils/scaffold/compute.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,6 @@ export { generateClaudeMd } from './claude-md/index.js';
4
4
  export declare function generateViteEnvDts(featureIds: FeatureId[]): string;
5
5
  /** Generate env.ts content based on selected features. */
6
6
  export declare function generateEnvTs(featureIds: FeatureId[]): string;
7
- /** Generates routes.ts content. */
8
- export declare function generateRoutesTs(): string;
7
+ /** Generates routes.ts content based on selected features. */
8
+ export declare function generateRoutesTs(featureIds: FeatureId[]): string;
9
9
  //# sourceMappingURL=generators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../../src/utils/scaffold/generators.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA4ClE;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAwE7D;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,IAAI,MAAM,CAazC"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../../src/utils/scaffold/generators.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAqDlE;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA2G7D;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAqBhE"}
@@ -27,6 +27,13 @@ export function generateViteEnvDts(featureIds) {
27
27
  if (featureIds.includes(FEATURE.PERFORMANCE)) {
28
28
  envVars.push(' readonly VITE_PERF_TEST: string;');
29
29
  }
30
+ if (featureIds.includes(FEATURE.AUTH)) {
31
+ envVars.push(' readonly VITE_CLERK_PUBLISHABLE_KEY: string;');
32
+ }
33
+ if (featureIds.includes(FEATURE.DATABASE)) {
34
+ envVars.push(' readonly VITE_SUPABASE_DATABASE_URL: string;');
35
+ envVars.push(' readonly VITE_SUPABASE_ANON_KEY: string;');
36
+ }
30
37
  // Vite built-in env vars (always required for TypeScript)
31
38
  envVars.push(" readonly MODE: 'development' | 'production' | 'test';");
32
39
  envVars.push(' readonly DEV: boolean;');
@@ -45,38 +52,66 @@ interface ImportMeta {
45
52
  }
46
53
  /** Generate env.ts content based on selected features. */
47
54
  export function generateEnvTs(featureIds) {
48
- const schemaFields = [
49
- ' VITE_APP_NAME: z.string().min(1).optional(),',
50
- ' VITE_APP_URL: z.string().url().optional(),',
51
- ];
55
+ // Check if we need the booleanEnv helper
56
+ const needsBooleanEnv = featureIds.includes(FEATURE.OBSERVABILITY) || featureIds.includes(FEATURE.PERFORMANCE);
57
+ const schemaFields = [' VITE_APP_NAME: z.string().min(1),', ' VITE_APP_URL: z.string().url(),'];
52
58
  const envFields = [
53
59
  ' VITE_APP_NAME: import.meta.env.VITE_APP_NAME,',
54
60
  ' VITE_APP_URL: import.meta.env.VITE_APP_URL,',
55
61
  ];
56
62
  if (featureIds.includes(FEATURE.API)) {
57
- schemaFields.push(' VITE_API_URL: z.string().url().optional(),');
63
+ schemaFields.push(' VITE_API_URL: z.string().url(),');
58
64
  envFields.push(' VITE_API_URL: import.meta.env.VITE_API_URL,');
59
65
  }
60
66
  if (featureIds.includes(FEATURE.OBSERVABILITY)) {
61
- schemaFields.push(' VITE_SENTRY_DSN: z.string().url().optional(),');
62
- schemaFields.push(' VITE_SENTRY_ENABLED: z.string().optional(),');
67
+ schemaFields.push(' VITE_SENTRY_DSN: z.string().url(),');
68
+ schemaFields.push(' VITE_SENTRY_ENABLED: booleanEnv,');
63
69
  envFields.push(' VITE_SENTRY_DSN: import.meta.env.VITE_SENTRY_DSN,');
64
70
  envFields.push(' VITE_SENTRY_ENABLED: import.meta.env.VITE_SENTRY_ENABLED,');
65
71
  }
72
+ if (featureIds.includes(FEATURE.AUTH)) {
73
+ schemaFields.push(' VITE_CLERK_PUBLISHABLE_KEY: z.string().min(1),');
74
+ envFields.push(' VITE_CLERK_PUBLISHABLE_KEY: import.meta.env.VITE_CLERK_PUBLISHABLE_KEY,');
75
+ }
76
+ if (featureIds.includes(FEATURE.DATABASE)) {
77
+ schemaFields.push(' VITE_SUPABASE_DATABASE_URL: z.string().url(),');
78
+ schemaFields.push(' VITE_SUPABASE_ANON_KEY: z.string().min(1),');
79
+ envFields.push(' VITE_SUPABASE_DATABASE_URL: import.meta.env.VITE_SUPABASE_DATABASE_URL,');
80
+ envFields.push(' VITE_SUPABASE_ANON_KEY: import.meta.env.VITE_SUPABASE_ANON_KEY,');
81
+ }
82
+ if (featureIds.includes(FEATURE.PERFORMANCE)) {
83
+ schemaFields.push(' VITE_PERF_TEST: booleanEnv,');
84
+ envFields.push(' VITE_PERF_TEST: import.meta.env.VITE_PERF_TEST,');
85
+ }
66
86
  // Vite built-in env vars (always included)
67
- schemaFields.push(" MODE: z.enum(['development', 'production', 'test']).default('development'),");
68
- schemaFields.push(' DEV: z.boolean().default(false),');
69
- schemaFields.push(' PROD: z.boolean().default(false),');
87
+ schemaFields.push(" MODE: z.enum(['development', 'production', 'test']),");
88
+ schemaFields.push(' DEV: z.boolean(),');
89
+ schemaFields.push(' PROD: z.boolean(),');
70
90
  envFields.push(' MODE: import.meta.env.MODE,');
71
91
  envFields.push(' DEV: import.meta.env.DEV,');
72
92
  envFields.push(' PROD: import.meta.env.PROD,');
93
+ // Build the booleanEnv helper if needed
94
+ const booleanEnvHelper = needsBooleanEnv
95
+ ? `
96
+ /**
97
+ * Transforms string env var to boolean.
98
+ * - 'true', '1' → true
99
+ * - 'false', '0' → false
100
+ */
101
+ const booleanEnv = z.enum(['true', 'false', '1', '0']).transform((val) => val === 'true' || val === '1');
102
+
103
+ `
104
+ : '';
73
105
  return `/**
74
106
  * Environment variable validation using Zod.
75
107
  * Validates at runtime to catch missing/invalid env vars early.
108
+ *
109
+ * All env vars are REQUIRED. The MCP scaffold tool strips unused vars
110
+ * when scaffolding builds without certain features.
76
111
  */
77
112
 
78
113
  import { z } from 'zod';
79
-
114
+ ${booleanEnvHelper}
80
115
  const envSchema = z.object({
81
116
  ${schemaFields.join('\n')}
82
117
  });
@@ -85,7 +120,7 @@ export type Env = z.infer<typeof envSchema>;
85
120
 
86
121
  /**
87
122
  * Validate environment variables and return typed env object.
88
- * Throws if validation fails in production.
123
+ * Throws if any required env var is missing or invalid.
89
124
  */
90
125
  export function validateEnv(): Env {
91
126
  const env = {
@@ -95,15 +130,17 @@ ${envFields.join('\n')}
95
130
  const result = envSchema.safeParse(env);
96
131
 
97
132
  if (!result.success) {
98
- const errors = result.error.format();
99
- console.error('Environment validation failed:', errors);
133
+ const errors = result.error.flatten();
134
+ const fieldErrors = Object.entries(errors.fieldErrors)
135
+ .map(([key, msgs]) => \`\${key}: \${(msgs as string[]).join(', ')}\`)
136
+ .join('; ');
137
+ const formErrors = errors.formErrors.join('; ');
138
+ const allErrors = [fieldErrors, formErrors].filter(Boolean).join('; ');
100
139
 
101
- if (import.meta.env.PROD) {
102
- throw new Error('Invalid environment configuration');
103
- }
140
+ throw new Error(\`Environment validation failed: \${allErrors}\`);
104
141
  }
105
142
 
106
- return result.data
143
+ return result.data;
107
144
  }
108
145
 
109
146
  /**
@@ -113,16 +150,21 @@ ${envFields.join('\n')}
113
150
  export const env = validateEnv();
114
151
  `;
115
152
  }
116
- /** Generates routes.ts content. */
117
- export function generateRoutesTs() {
153
+ /** Generates routes.ts content based on selected features. */
154
+ export function generateRoutesTs(featureIds) {
155
+ const routes = [" HOME: '/',"];
156
+ // Add PROFILE route when database feature is selected
157
+ if (featureIds.includes(FEATURE.DATABASE)) {
158
+ routes.push(" PROFILE: '/profile',");
159
+ }
160
+ routes.push(" NOT_FOUND: '*',");
118
161
  return `/**
119
162
  * Typed route constants.
120
163
  * Use these instead of hardcoded strings for type-safe navigation.
121
164
  */
122
165
 
123
166
  export const ROUTES = {
124
- HOME: '/',
125
- NOT_FOUND: '*',
167
+ ${routes.join('\n')}
126
168
  } as const;
127
169
 
128
170
  export type AppRoute = (typeof ROUTES)[keyof typeof ROUTES];
@@ -1 +1 @@
1
- {"version":3,"file":"generators.js","sourceRoot":"","sources":["../../../src/utils/scaffold/generators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generators.js","sourceRoot":"","sources":["../../../src/utils/scaffold/generators.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-spa-scaffold/mcp",
3
- "version": "2.1.1",
3
+ "version": "2.3.0",
4
4
  "description": "MCP server for scaffolding projects based on react-spa-scaffold template",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,21 +1,55 @@
1
- # Application
1
+ # ─────────────────────────────────────────────────────────────
2
+ # Application (required)
3
+ # ─────────────────────────────────────────────────────────────
2
4
  VITE_APP_NAME="My App"
3
5
  VITE_APP_URL=http://localhost:5173
4
-
5
- # Optional: Base URL for deployment subdirectory
6
- # VITE_BASE_URL=/
6
+ VITE_API_URL=https://jsonplaceholder.typicode.com
7
7
 
8
8
  # ─────────────────────────────────────────────────────────────
9
- # Sentry Error Tracking (production only)
9
+ # Sentry Error Tracking (required)
10
10
  # ─────────────────────────────────────────────────────────────
11
- # Set to 'false' to disable Sentry entirely (opt-out)
12
- # Enabled by default when DSN is provided
13
- # VITE_SENTRY_ENABLED=true
14
-
15
11
  # Runtime DSN for error reporting (client-side, safe to expose)
16
- # VITE_SENTRY_DSN=https://xxxxx@o123456.ingest.sentry.io/789
12
+ # Get from: https://sentry.io/settings/projects/YOUR_PROJECT/keys/
13
+ VITE_SENTRY_DSN=https://xxxxx@o123456.ingest.sentry.io/789
14
+ VITE_SENTRY_ENABLED=true
17
15
 
18
16
  # CI/CD secrets for source map upload (set in GitHub Secrets):
19
17
  # - SENTRY_AUTH_TOKEN: API token for uploading source maps
20
18
  # - SENTRY_ORG: Sentry organization slug
21
19
  # - SENTRY_PROJECT: Sentry project slug
20
+
21
+ # ─────────────────────────────────────────────────────────────
22
+ # Clerk Authentication (required)
23
+ # ─────────────────────────────────────────────────────────────
24
+ # Get your Publishable Key from: https://dashboard.clerk.com/~/api-keys
25
+ VITE_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
26
+
27
+ # ─────────────────────────────────────────────────────────────
28
+ # Supabase Database (required)
29
+ # ─────────────────────────────────────────────────────────────
30
+ # Get your Project URL and API Key from:
31
+ # https://supabase.com/dashboard/project/YOUR_PROJECT/settings/api
32
+ #
33
+ # For Netlify deployments, these can be auto-configured via the
34
+ # Netlify Supabase extension: Extensions > Supabase > Connect
35
+ VITE_SUPABASE_DATABASE_URL=https://your-project.supabase.co
36
+ VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
37
+
38
+ # ─────────────────────────────────────────────────────────────
39
+ # Performance Testing (required)
40
+ # ─────────────────────────────────────────────────────────────
41
+ VITE_PERF_TEST=false
42
+
43
+ # Supabase CLI (required for npm run db:types)
44
+ # Project ID is the subdomain from your Supabase URL (e.g., abc123xyz from https://abc123xyz.supabase.co)
45
+ SUPABASE_PROJECT_ID=your-project-id
46
+
47
+ # ─────────────────────────────────────────────────────────────
48
+ # E2E Testing (optional - for authenticated Playwright tests)
49
+ # ─────────────────────────────────────────────────────────────
50
+ # Create a test user in Clerk and provide credentials here
51
+ # Required for running: npx playwright test --project=authenticated
52
+ # E2E_CLERK_USER_USERNAME=test@example.com
53
+ # E2E_CLERK_USER_PASSWORD=your-test-password
54
+ # CLERK_SECRET_KEY=sk_test_xxxxx
55
+
@@ -84,14 +84,19 @@ jobs:
84
84
  fail-fast: false
85
85
  matrix:
86
86
  include:
87
- - type: functional
88
- project: functional
89
- command: npx playwright test --project=functional
87
+ - type: desktop
88
+ project: desktop
89
+ command: npx playwright test --project=desktop
90
90
  report-name: playwright-report
91
91
  upload-on: failure
92
+ - type: mobile
93
+ project: mobile
94
+ command: npx playwright test --project=mobile
95
+ report-name: playwright-report-mobile
96
+ upload-on: failure
92
97
  - type: performance
93
98
  project: performance
94
- command: PERF_TEST=true npx playwright test --project=performance
99
+ command: PERF_TEST=true PERF_CI=true npx playwright test --project=performance
95
100
  report-name: performance-report
96
101
  upload-on: always
97
102
  steps:
@@ -101,6 +106,9 @@ jobs:
101
106
  with:
102
107
  name: dist
103
108
  path: dist/
109
+ - name: Rebuild with performance tracking
110
+ if: matrix.type == 'performance'
111
+ run: VITE_PERF_TEST=true npm run build
104
112
  - name: Get Playwright version
105
113
  id: playwright-version
106
114
  run: echo "version=$(npm ls @playwright/test --json | jq -r '.dependencies["@playwright/test"].version')" >> $GITHUB_OUTPUT
@@ -0,0 +1,59 @@
1
+ name: Deploy
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pull-requests: write
13
+ deployments: write
14
+
15
+ concurrency:
16
+ group: deploy-${{ github.ref }}
17
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
18
+
19
+ jobs:
20
+ deploy:
21
+ name: Deploy
22
+ runs-on: ubuntu-latest
23
+ timeout-minutes: 15
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+
27
+ - uses: ./.github/actions/setup-node-deps
28
+
29
+ - name: Build
30
+ run: npm run build
31
+
32
+ - name: Deploy Preview
33
+ if: github.event_name == 'pull_request'
34
+ uses: nwtgck/actions-netlify@v3
35
+ with:
36
+ publish-dir: './dist'
37
+ production-deploy: false
38
+ github-token: ${{ secrets.GITHUB_TOKEN }}
39
+ deploy-message: 'Preview deploy from PR #${{ github.event.number }}'
40
+ enable-pull-request-comment: true
41
+ enable-commit-comment: false
42
+ overwrites-pull-request-comment: true
43
+ alias: pr-${{ github.event.number }}
44
+ env:
45
+ NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
46
+ NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
47
+
48
+ - name: Deploy Production
49
+ if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
50
+ uses: nwtgck/actions-netlify@v3
51
+ with:
52
+ publish-dir: './dist'
53
+ production-deploy: true
54
+ github-token: ${{ secrets.GITHUB_TOKEN }}
55
+ deploy-message: 'Production deploy from ${{ github.sha }}'
56
+ enable-commit-comment: true
57
+ env:
58
+ NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
59
+ NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}