create-m5kdev 0.32.8 → 0.34.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 (152) hide show
  1. package/dist/src/catalog.cjs +76 -11
  2. package/dist/src/catalog.cjs.map +1 -1
  3. package/dist/src/catalog.d.cts +13 -1
  4. package/dist/src/create.cjs +6 -2
  5. package/dist/src/create.cjs.map +1 -1
  6. package/dist/src/doctor.cjs +13 -7
  7. package/dist/src/doctor.cjs.map +1 -1
  8. package/dist/src/fs.cjs +10 -5
  9. package/dist/src/fs.cjs.map +1 -1
  10. package/dist/src/prompts.cjs +32 -0
  11. package/dist/src/prompts.cjs.map +1 -1
  12. package/dist/src/prompts.d.cts +7 -1
  13. package/dist/src/template.cjs +23 -4
  14. package/dist/src/template.cjs.map +1 -1
  15. package/dist/src/template.d.cts +17 -3
  16. package/dist/src/types.d.cts +11 -4
  17. package/package.json +4 -1
  18. package/templates/minimal-app/.cursor/rules/module-dto-guide.mdc +1 -1
  19. package/templates/minimal-app/.cursor/rules/module-grants-guide.mdc +3 -3
  20. package/templates/minimal-app/.cursor/rules/module-module-guide.mdc +3 -2
  21. package/templates/minimal-app/.cursor/rules/module-service-guide.mdc +1 -1
  22. package/templates/minimal-app/.dockerignore.tpl +31 -0
  23. package/templates/minimal-app/.gitignore.tpl +1 -0
  24. package/templates/minimal-app/AGENTS.md.tpl +13 -10
  25. package/templates/minimal-app/CLAUDE.md.tpl +132 -131
  26. package/templates/minimal-app/README.md.tpl +50 -19
  27. package/templates/minimal-app/apps/e2e/package.json.tpl +23 -23
  28. package/templates/minimal-app/apps/e2e/playwright.config.ts.tpl +51 -39
  29. package/templates/minimal-app/apps/e2e/playwright.expo.config.ts.tpl +38 -38
  30. package/templates/minimal-app/apps/e2e/servers.ts.tpl +136 -112
  31. package/templates/minimal-app/apps/e2e/tests/conversation.spec.ts.tpl +22 -0
  32. package/templates/minimal-app/apps/e2e/tests/email.spec.ts.tpl +47 -47
  33. package/templates/minimal-app/apps/e2e/tests/expo-helpers.ts.tpl +73 -73
  34. package/templates/minimal-app/apps/e2e/tests/expo-standard.spec.ts.tpl +517 -517
  35. package/templates/minimal-app/apps/e2e/tests/expo-waitlist.spec.ts.tpl +94 -94
  36. package/templates/minimal-app/apps/e2e/tests/files.spec.ts.tpl +35 -0
  37. package/templates/minimal-app/apps/e2e/tests/helpers.ts.tpl +289 -289
  38. package/templates/minimal-app/apps/e2e/tests/standard.spec.ts.tpl +516 -516
  39. package/templates/minimal-app/apps/e2e/tests/waitlist.spec.ts.tpl +107 -107
  40. package/templates/minimal-app/apps/e2e/tests/workflow.spec.ts.tpl +26 -0
  41. package/templates/minimal-app/apps/e2e/tsconfig.json.tpl +10 -10
  42. package/templates/minimal-app/apps/email/package.json.tpl +34 -34
  43. package/templates/minimal-app/apps/email/src/emails/trialEndingEmail.tsx.tpl +40 -0
  44. package/templates/minimal-app/apps/email/src/index.ts.tpl +7 -0
  45. package/templates/minimal-app/apps/email/src/resources.ts.tpl +72 -65
  46. package/templates/minimal-app/apps/expo/app.json.tpl +36 -36
  47. package/templates/minimal-app/apps/expo/eslint.config.js.tpl +8 -8
  48. package/templates/minimal-app/apps/expo/metro.config.js.tpl +16 -16
  49. package/templates/minimal-app/apps/expo/package.json.tpl +59 -59
  50. package/templates/minimal-app/apps/expo/src/app/_layout.tsx.tpl +31 -31
  51. package/templates/minimal-app/apps/expo/src/app/claim-account.tsx.tpl +151 -151
  52. package/templates/minimal-app/apps/expo/src/app/forgot-password.tsx.tpl +53 -53
  53. package/templates/minimal-app/apps/expo/src/app/index.tsx.tpl +8 -8
  54. package/templates/minimal-app/apps/expo/src/app/login.tsx.tpl +71 -71
  55. package/templates/minimal-app/apps/expo/src/app/logout.tsx.tpl +19 -19
  56. package/templates/minimal-app/apps/expo/src/app/organization/accept-invitation.tsx.tpl +85 -85
  57. package/templates/minimal-app/apps/expo/src/app/posts.tsx.tpl +40 -40
  58. package/templates/minimal-app/apps/expo/src/app/reset-password.tsx.tpl +75 -75
  59. package/templates/minimal-app/apps/expo/src/app/signup.tsx.tpl +193 -193
  60. package/templates/minimal-app/apps/expo/src/components/AuthScaffold.tsx.tpl +34 -34
  61. package/templates/minimal-app/apps/expo/src/components/FormTextField.tsx.tpl +37 -37
  62. package/templates/minimal-app/apps/expo/src/components/LoadingScreen.tsx.tpl +10 -10
  63. package/templates/minimal-app/apps/expo/src/components/StatusText.tsx.tpl +22 -22
  64. package/templates/minimal-app/apps/expo/src/config.ts.tpl +9 -9
  65. package/templates/minimal-app/apps/expo/src/global.css.tpl +11 -11
  66. package/templates/minimal-app/apps/expo/src/lib/trpc.ts.tpl +20 -20
  67. package/templates/minimal-app/apps/expo/tsconfig.json.tpl +11 -11
  68. package/templates/minimal-app/apps/expo/uniwind-env.d.ts.tpl +1 -1
  69. package/templates/minimal-app/apps/landing/.env.production.example.tpl +7 -0
  70. package/templates/minimal-app/apps/landing/Dockerfile.tpl +39 -0
  71. package/templates/minimal-app/apps/landing/fly.toml.tpl +20 -0
  72. package/templates/minimal-app/apps/landing/index.html.tpl +35 -0
  73. package/templates/minimal-app/apps/landing/package.json.tpl +34 -0
  74. package/templates/minimal-app/apps/landing/scripts/fly-deploy.mjs.tpl +75 -0
  75. package/templates/minimal-app/apps/landing/scripts/fly-secrets.mjs.tpl +31 -0
  76. package/templates/minimal-app/apps/landing/src/App.tsx.tpl +12 -0
  77. package/templates/minimal-app/apps/landing/src/LandingPage.tsx.tpl +37 -0
  78. package/templates/minimal-app/apps/landing/src/index.css.tpl +24 -0
  79. package/templates/minimal-app/apps/landing/src/main.tsx.tpl +16 -0
  80. package/templates/minimal-app/apps/landing/src/vite-env.d.ts.tpl +11 -0
  81. package/templates/minimal-app/apps/landing/tsconfig.json.tpl +12 -0
  82. package/templates/minimal-app/apps/landing/vite.config.ts.tpl +25 -0
  83. package/templates/minimal-app/apps/server/AGENTS.md.tpl +54 -46
  84. package/templates/minimal-app/apps/server/{drizzle/seed.e2e.ts.tpl → db.e2e.ts.tpl} +57 -40
  85. package/templates/minimal-app/apps/server/{drizzle/seed.ts.tpl → db.ts.tpl} +27 -20
  86. package/templates/minimal-app/apps/server/drizzle/0002_concerned_proudstar.sql +3 -0
  87. package/templates/minimal-app/apps/server/drizzle/0003_silly_the_liberteens.sql +27 -0
  88. package/templates/minimal-app/apps/server/drizzle/meta/0000_snapshot.json.tpl +56 -166
  89. package/templates/minimal-app/apps/server/drizzle/meta/0001_snapshot.json.tpl +1796 -1910
  90. package/templates/minimal-app/apps/server/drizzle/meta/0002_snapshot.json.tpl +1818 -0
  91. package/templates/minimal-app/apps/server/drizzle/meta/0003_snapshot.json.tpl +2137 -0
  92. package/templates/minimal-app/apps/server/drizzle/meta/_journal.json.tpl +15 -1
  93. package/templates/minimal-app/apps/server/drizzle.config.ts.tpl +3 -33
  94. package/templates/minimal-app/apps/server/package.json.tpl +57 -56
  95. package/templates/minimal-app/apps/server/src/app.ts.tpl +149 -141
  96. package/templates/minimal-app/apps/server/src/index.ts.tpl +12 -65
  97. package/templates/minimal-app/apps/server/src/modules/conversation/conversation.mastra.ts.tpl +26 -0
  98. package/templates/minimal-app/apps/server/src/modules/demo-workflow/demo-workflow.module.ts.tpl +47 -0
  99. package/templates/minimal-app/apps/server/src/modules/demo-workflow/demo-workflow.service.ts.tpl +43 -0
  100. package/templates/minimal-app/apps/server/src/modules/demo-workflow/demo-workflow.trpc.ts.tpl +16 -0
  101. package/templates/minimal-app/apps/server/src/modules/posts/posts.db.ts.tpl +28 -28
  102. package/templates/minimal-app/apps/server/src/modules/posts/posts.grants.ts.tpl +28 -30
  103. package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +54 -54
  104. package/templates/minimal-app/apps/server/src/modules/posts/posts.repository.ts.tpl +67 -67
  105. package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +116 -115
  106. package/templates/minimal-app/apps/server/src/modules/posts/posts.trpc.ts.tpl +37 -37
  107. package/templates/minimal-app/apps/server/src/modules/test-harness/test-harness.module.ts.tpl +279 -279
  108. package/templates/minimal-app/apps/server/src/schema.ts.tpl +31 -20
  109. package/templates/minimal-app/apps/server/src/types.ts.tpl +12 -1
  110. package/templates/minimal-app/apps/server/tsconfig.json.tpl +1 -1
  111. package/templates/minimal-app/apps/server/tsup.config.ts.tpl +23 -9
  112. package/templates/minimal-app/apps/shared/.env.example.tpl +5 -0
  113. package/templates/minimal-app/apps/shared/.env.production.example.tpl +23 -0
  114. package/templates/minimal-app/apps/shared/.env.tpl +5 -0
  115. package/templates/minimal-app/apps/shared/Dockerfile.tpl +48 -0
  116. package/templates/minimal-app/apps/shared/fly.toml.tpl +24 -0
  117. package/templates/minimal-app/apps/shared/package.json.tpl +25 -24
  118. package/templates/minimal-app/apps/shared/scripts/fly-deploy.mjs.tpl +75 -0
  119. package/templates/minimal-app/apps/shared/scripts/fly-secrets.mjs.tpl +31 -0
  120. package/templates/minimal-app/apps/shared/src/modules/app/app.constants.ts.tpl +28 -28
  121. package/templates/minimal-app/apps/shared/src/modules/conversation/conversation.constants.ts.tpl +1 -0
  122. package/templates/minimal-app/apps/shared/src/modules/notification/notification.schema.ts.tpl +3 -3
  123. package/templates/minimal-app/apps/shared/src/modules/posts/posts.constants.ts.tpl +5 -5
  124. package/templates/minimal-app/apps/shared/src/modules/posts/posts.schema.ts.tpl +25 -25
  125. package/templates/minimal-app/apps/webapp/package.json.tpl +53 -53
  126. package/templates/minimal-app/apps/webapp/public/push-sw.js.tpl +34 -34
  127. package/templates/minimal-app/apps/webapp/src/App.tsx.tpl +46 -44
  128. package/templates/minimal-app/apps/webapp/src/Layout.tsx.tpl +96 -65
  129. package/templates/minimal-app/apps/webapp/src/Router.tsx.tpl +114 -93
  130. package/templates/minimal-app/apps/webapp/src/index.css.tpl +15 -15
  131. package/templates/minimal-app/apps/webapp/src/main.tsx.tpl +26 -26
  132. package/templates/minimal-app/apps/webapp/src/modules/conversation/ConversationRoute.tsx.tpl +36 -0
  133. package/templates/minimal-app/apps/webapp/src/modules/files/FilesRoute.tsx.tpl +88 -0
  134. package/templates/minimal-app/apps/webapp/src/modules/files/hooks/useFilesRoute.ts.tpl +50 -0
  135. package/templates/minimal-app/apps/webapp/src/modules/workflows/WorkflowsRoute.tsx.tpl +97 -0
  136. package/templates/minimal-app/apps/webapp/src/modules/workflows/hooks/useWorkflowsRoute.ts.tpl +64 -0
  137. package/templates/minimal-app/apps/webapp/src/utils/i18n.ts.tpl +13 -13
  138. package/templates/minimal-app/apps/webapp/src/utils/trpc.ts.tpl +10 -10
  139. package/templates/minimal-app/apps/webapp/src/vite-env.d.ts.tpl +1 -1
  140. package/templates/minimal-app/apps/webapp/translations/en/app.json.tpl +7 -7
  141. package/templates/minimal-app/apps/webapp/translations/en/{{APP_SLUG}}.json.tpl +193 -135
  142. package/templates/minimal-app/apps/webapp/tsconfig.json.tpl +17 -17
  143. package/templates/minimal-app/apps/webapp/vite.config.ts.tpl +31 -31
  144. package/templates/minimal-app/biome.json.tpl +17 -12
  145. package/templates/minimal-app/package.json.tpl +9 -5
  146. package/templates/minimal-app/pnpm-workspace.yaml.tpl +67 -58
  147. package/templates/minimal-app/template.manifest.json +92 -2
  148. package/templates/minimal-app/apps/server/drizzle/db.ts.tpl +0 -26
  149. package/templates/minimal-app/apps/server/drizzle/guard.ts.tpl +0 -36
  150. package/templates/minimal-app/apps/server/drizzle/reset.ts.tpl +0 -40
  151. package/templates/minimal-app/apps/server/drizzle/sync.ts.tpl +0 -16
  152. package/templates/minimal-app/apps/server/src/lib/auth.ts.tpl +0 -12
@@ -1,61 +1,70 @@
1
1
  packages:
2
2
  - apps/**
3
- catalog:
4
- "@biomejs/biome": 2.2.0
5
- "@heroui/react": 3.0.3
6
- "@heroui/styles": 3.0.3
7
- "@libsql/client": 0.17.4
8
- "@m5kdev/backend": 0.32.9
9
- "@m5kdev/commons": 0.32.9
10
- "@m5kdev/config": 0.32.9
11
- "@m5kdev/email": 0.32.9
12
- "@m5kdev/frontend": 0.32.9
13
- "@m5kdev/web-ui": 0.32.9
14
- "@playwright/test": 1.57.0
15
- "@react-email/components": 1.0.1
16
- "@tailwindcss/vite": 4.1.11
17
- "@tanstack/react-query": 5.83.0
18
- "@trpc/client": 11.4.3
19
- "@trpc/server": 11.4.3
20
- "@trpc/tanstack-react-query": 11.4.3
21
- "@types/cors": 2.8.17
22
- "@types/express": 4.17.21
23
- "@types/node": 20.19.11
24
- "@types/react": 19.2.17
25
- "@types/react-dom": 19.2.3
26
- "@vitejs/plugin-react": 4.2.0
27
- babel-plugin-react-compiler: 1.0.0
28
- better-auth: 1.4.18
29
- cors: 2.8.5
30
- dotenv: 16.6.1
31
- drizzle-kit: 0.31.10
32
- drizzle-orm: 0.45.2
33
- drizzle-zod: 0.8.3
34
- express: 4.21.2
35
- i18next: 25.3.2
36
- ioredis: 5.11.1
37
- lucide-react: 0.488.0
38
- neverthrow: 8.2.0
39
- nuqs: 2.4.3
40
- posthog-js: 1.258.2
41
- react: 19.2.1
42
- react-dom: 19.2.1
43
- react-email: 5.0.5
44
- react-hook-form: 7.61.1
45
- react-i18next: 15.6.1
46
- react-native-web: ^0.21.2
47
- react-router: 7.10.1
48
- sonner: 1.7.4
49
- tailwindcss: 4.1.11
50
- tslib: 2.8.1
51
- tsup: 8.4.0
52
- tsx: 4.19.2
53
- turbo: 2.5.6
54
- tw-animate-css: 1.3.6
55
- typescript: 6.0.3
56
- uuid: 11.0.5
57
- vite: 7.0.4
58
- vite-plugin-i18next-loader: 3.1.2
59
- vite-tsconfig-paths: 5.1.4
60
- zod: 4.2.1
3
+ catalog: {}
4
+ catalogs:
5
+ m5kdev:
6
+ "@biomejs/biome": 2.5.9
7
+ "@heroui/react": 3.0.3
8
+ "@heroui/styles": 3.0.3
9
+ "@libsql/client": 0.17.4
10
+ "@m5kdev/backend": 0.34.0
11
+ "@m5kdev/commons": 0.34.0
12
+ "@m5kdev/config": 0.34.0
13
+ "@m5kdev/email": 0.34.0
14
+ "@m5kdev/frontend": 0.34.0
15
+ "@m5kdev/module-clay": 0.34.0
16
+ "@m5kdev/module-docx": 0.34.0
17
+ "@m5kdev/module-pdf": 0.34.0
18
+ "@m5kdev/module-social": 0.34.0
19
+ "@m5kdev/module-video": 0.34.0
20
+ "@m5kdev/web-ui": 0.34.0
21
+ "@mastra/core": 1.51.0
22
+ "@openrouter/ai-sdk-provider": 3.0.0
23
+ "@opentelemetry/api": 1.9.0
24
+ "@playwright/test": 1.57.0
25
+ "@react-email/components": 1.0.1
26
+ "@tailwindcss/vite": 4.1.17
27
+ "@tanstack/react-query": 5.83.0
28
+ "@trpc/client": 11.4.3
29
+ "@trpc/server": 11.4.3
30
+ "@trpc/tanstack-react-query": 11.4.3
31
+ "@types/express": 4.17.21
32
+ "@types/node": 20.19.11
33
+ "@types/react": 19.2.17
34
+ "@types/react-dom": 19.2.3
35
+ "@vitejs/plugin-react": 4.2.0
36
+ babel-plugin-react-compiler: 1.0.0
37
+ better-auth: 1.4.18
38
+ dotenv: 16.6.1
39
+ drizzle-kit: 0.31.10
40
+ drizzle-orm: 0.45.2
41
+ drizzle-zod: 0.8.3
42
+ express: 4.21.2
43
+ i18next: 25.3.2
44
+ ioredis: 5.11.1
45
+ lucide-react: 0.488.0
46
+ neverthrow: 8.2.0
47
+ nuqs: 2.4.3
48
+ posthog-js: 1.258.2
49
+ react: 19.2.3
50
+ react-dom: 19.2.3
51
+ react-email: 5.0.5
52
+ react-hook-form: 7.61.1
53
+ react-i18next: 15.6.1
54
+ react-native-web: ^0.21.2
55
+ react-router: 7.10.1
56
+ sonner: 1.7.4
57
+ tailwind-merge: 3.4.0
58
+ tailwindcss: 4.1.17
59
+ tslib: 2.8.1
60
+ tsup: 8.4.0
61
+ tsx: 4.19.2
62
+ turbo: 2.5.6
63
+ tw-animate-css: 1.3.6
64
+ typescript: 6.0.3
65
+ uuid: 11.0.5
66
+ vite: 7.0.4
67
+ vite-plugin-i18next-loader: 3.1.2
68
+ vite-tsconfig-paths: 5.1.4
69
+ zod: 4.2.1
61
70
  catalogMode: strict
@@ -2,21 +2,86 @@
2
2
  "schemaVersion": 1,
3
3
  "features": {
4
4
  "test-harness": {
5
+ "kind": "harness",
5
6
  "paths": [
6
7
  "apps/e2e/",
7
8
  "apps/server/src/modules/test-harness/",
8
- "apps/server/drizzle/seed.e2e.ts"
9
+ "apps/server/db.e2e.ts"
9
10
  ]
10
11
  },
11
12
  "webapp": {
13
+ "kind": "platform",
12
14
  "paths": [
13
15
  "apps/webapp/"
14
16
  ]
15
17
  },
16
18
  "expo": {
19
+ "kind": "platform",
17
20
  "paths": [
18
21
  "apps/expo/"
19
22
  ]
23
+ },
24
+ "billing": {
25
+ "kind": "module",
26
+ "label": "Billing",
27
+ "paths": []
28
+ },
29
+ "files": {
30
+ "kind": "module",
31
+ "label": "Files",
32
+ "paths": [
33
+ "apps/webapp/src/modules/files/",
34
+ "apps/e2e/tests/files.spec.ts"
35
+ ]
36
+ },
37
+ "workflows": {
38
+ "kind": "module",
39
+ "label": "Workflows",
40
+ "paths": [
41
+ "apps/webapp/src/modules/workflows/",
42
+ "apps/server/src/modules/demo-workflow/",
43
+ "apps/e2e/tests/workflow.spec.ts"
44
+ ]
45
+ },
46
+ "ai": {
47
+ "kind": "module",
48
+ "label": "AI",
49
+ "paths": [
50
+ "apps/webapp/src/modules/conversation/",
51
+ "apps/server/src/modules/conversation/",
52
+ "apps/shared/src/modules/conversation/",
53
+ "apps/e2e/tests/conversation.spec.ts"
54
+ ]
55
+ },
56
+ "notifications": {
57
+ "kind": "module",
58
+ "label": "Notifications",
59
+ "experimental": true,
60
+ "paths": []
61
+ },
62
+ "tags": {
63
+ "kind": "module",
64
+ "label": "Tags",
65
+ "experimental": true,
66
+ "paths": []
67
+ },
68
+ "connect": {
69
+ "kind": "module",
70
+ "label": "Connect",
71
+ "experimental": true,
72
+ "paths": []
73
+ },
74
+ "recurrence": {
75
+ "kind": "module",
76
+ "label": "Recurrence",
77
+ "experimental": true,
78
+ "paths": []
79
+ },
80
+ "webhook": {
81
+ "kind": "module",
82
+ "label": "Webhook",
83
+ "experimental": true,
84
+ "paths": []
20
85
  }
21
86
  },
22
87
  "requiredPaths": [
@@ -24,7 +89,8 @@
24
89
  "pnpm-workspace.yaml",
25
90
  "apps/shared/package.json",
26
91
  "apps/server/package.json",
27
- "apps/email/package.json"
92
+ "apps/email/package.json",
93
+ "apps/landing/package.json"
28
94
  ],
29
95
  "sync": {
30
96
  "defaultPolicy": "merge",
@@ -37,6 +103,18 @@
37
103
  "pattern": "**/.env",
38
104
  "policy": "ignore"
39
105
  },
106
+ {
107
+ "pattern": ".env.production",
108
+ "policy": "ignore"
109
+ },
110
+ {
111
+ "pattern": "**/.env.production",
112
+ "policy": "ignore"
113
+ },
114
+ {
115
+ "pattern": "**/fly.toml",
116
+ "policy": "ignore"
117
+ },
40
118
  {
41
119
  "pattern": "**/drizzle/*.sql",
42
120
  "policy": "ignore"
@@ -44,6 +122,18 @@
44
122
  {
45
123
  "pattern": "**/drizzle/meta/**",
46
124
  "policy": "ignore"
125
+ },
126
+ {
127
+ "pattern": "apps/server/db.ts",
128
+ "policy": "ensure"
129
+ },
130
+ {
131
+ "pattern": "apps/server/db.e2e.ts",
132
+ "policy": "ensure"
133
+ },
134
+ {
135
+ "pattern": "apps/server/drizzle.config.ts",
136
+ "policy": "ensure"
47
137
  }
48
138
  ],
49
139
  "renames": []
@@ -1,26 +0,0 @@
1
- import { createClient } from "@libsql/client";
2
- import { drizzle } from "drizzle-orm/libsql";
3
- import * as schema from "../src/schema";
4
-
5
- /**
6
- * Standalone DB handle for scripts (seed, maintenance). Deliberately does NOT
7
- * import ./app — constructing the backend app opens Redis/queue connections
8
- * that keep short-lived scripts alive forever. The running server gets its own
9
- * connection through createBackendApp.
10
- */
11
- const databaseUrl = process.env.DATABASE_URL ?? "file:./local.db";
12
- const syncUrl = process.env.TURSO_DATABASE_URL;
13
- const authToken = process.env.TURSO_AUTH_TOKEN;
14
-
15
- export const isRemote = syncUrl && authToken;
16
-
17
- const client = createClient(
18
- isRemote ? { url: databaseUrl, syncUrl, authToken } : { url: databaseUrl }
19
- );
20
-
21
- export const orm = drizzle(client, { schema });
22
-
23
- export type Orm = typeof orm;
24
- export type Schema = typeof schema;
25
-
26
- export { schema };
@@ -1,36 +0,0 @@
1
- import net from "node:net";
2
-
3
- const CONNECT_TIMEOUT_MS = 500;
4
-
5
- function isPortInUse(port: number): Promise<boolean> {
6
- return new Promise((resolve) => {
7
- const socket = net.connect({ port, host: "127.0.0.1" });
8
- const done = (result: boolean) => {
9
- socket.destroy();
10
- resolve(result);
11
- };
12
- socket.setTimeout(CONNECT_TIMEOUT_MS);
13
- socket.once("connect", () => done(true));
14
- socket.once("timeout", () => done(false));
15
- socket.once("error", () => done(false));
16
- });
17
- }
18
-
19
- /**
20
- * The dev server holds its own libsql connection on the local database file —
21
- * an embedded replica when Turso is configured. A second process syncing or
22
- * deleting that file corrupts the WAL, so db scripts must not run while the
23
- * server is up. Best-effort check: only the conventional PORT is probed.
24
- */
25
- export async function ensureDevServerStopped(): Promise<void> {
26
- if (process.env.SKIP_DB_GUARD === "true") return;
27
- const databaseUrl = process.env.DATABASE_URL ?? "file:./local.db";
28
- if (!databaseUrl.startsWith("file:")) return;
29
- const port = Number.parseInt(process.env.PORT ?? "8080", 10);
30
- if (Number.isNaN(port) || !(await isPortInUse(port))) return;
31
- console.error(
32
- `[drizzle] A server is listening on port ${port} and holds ${databaseUrl}. ` +
33
- "Stop the dev server first, or set SKIP_DB_GUARD=true to override."
34
- );
35
- process.exit(1);
36
- }
@@ -1,40 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { ensureDevServerStopped } from "./guard";
4
-
5
- /** Deletes the local SQLite database (and stored-email output) for a clean slate. */
6
- function sqlitePathFromDatabaseUrl(url: string) {
7
- if (!url.startsWith("file:")) return null;
8
- return path.resolve(process.cwd(), url.slice("file:".length));
9
- }
10
-
11
- // Sidecars include the embedded-replica sync metadata (-info, -client_wal_index);
12
- // leaving those behind next to a recreated file causes WAL/sync conflicts.
13
- const DB_SIDECAR_SUFFIXES = ["-shm", "-wal", "-journal", "-info", "-client_wal_index"];
14
-
15
- async function removeIfExists(target: string) {
16
- await fs.rm(target, { recursive: true, force: true });
17
- }
18
-
19
- async function reset() {
20
- await ensureDevServerStopped();
21
- const dbPath = sqlitePathFromDatabaseUrl(process.env.DATABASE_URL ?? "");
22
- if (dbPath) {
23
- await removeIfExists(dbPath);
24
- for (const suffix of DB_SIDECAR_SUFFIXES) {
25
- await removeIfExists(`${dbPath}${suffix}`);
26
- }
27
- await fs.mkdir(path.dirname(dbPath), { recursive: true });
28
- }
29
-
30
- const emailDirectory = process.env.EMAIL_OUTPUT_DIRECTORY
31
- ? path.resolve(process.cwd(), process.env.EMAIL_OUTPUT_DIRECTORY)
32
- : null;
33
-
34
- if (emailDirectory) {
35
- await removeIfExists(emailDirectory);
36
- await fs.mkdir(emailDirectory, { recursive: true });
37
- }
38
- }
39
-
40
- void reset();
@@ -1,16 +0,0 @@
1
- import { isRemote, orm } from "./db";
2
- import { ensureDevServerStopped } from "./guard";
3
-
4
- async function sync() {
5
- await ensureDevServerStopped();
6
- if (isRemote) {
7
- await orm.$client.sync();
8
- } else {
9
- console.info("Local database no sync required");
10
- }
11
- }
12
-
13
- sync().then(() => {
14
- console.info("Sync completed");
15
- process.exit(0);
16
- });
@@ -1,12 +0,0 @@
1
- import { builtBackendApp } from "../app";
2
-
3
- const authInstance = builtBackendApp.auth?.instance;
4
-
5
- if (!authInstance) {
6
- throw new Error("Auth is not configured on the backend app.");
7
- }
8
-
9
- export const auth = authInstance;
10
-
11
- export type Session = typeof auth.$Infer.Session;
12
- export type User = Session["user"];