devpush 0.0.0-stage → 1.0.0-beta.3

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 (456) hide show
  1. package/README.md +6 -2
  2. package/agent-release.json +37 -0
  3. package/dist/package/LICENSE.md +21 -0
  4. package/dist/package/migrate.mjs +182 -0
  5. package/dist/package/plugins.mjs +125 -0
  6. package/dist/package/vite.mjs +439 -0
  7. package/package.json +170 -4
  8. package/public/apple-touch-icon.png +0 -0
  9. package/public/favicon.svg +1 -0
  10. package/public/logo-email.png +0 -0
  11. package/public/robots.txt +3 -0
  12. package/public/social.png +0 -0
  13. package/src/cloudflare-runtime.d.ts +78 -0
  14. package/src/components/about-dialog.tsx +70 -0
  15. package/src/components/copy-button.tsx +74 -0
  16. package/src/components/logo-mark.tsx +20 -0
  17. package/src/components/pending-collection.tsx +103 -0
  18. package/src/components/resource-avatar.tsx +65 -0
  19. package/src/components/route-error-state.tsx +95 -0
  20. package/src/components/section-navigation.tsx +39 -0
  21. package/src/components/settings-layout.tsx +111 -0
  22. package/src/components/storage-capabilities.tsx +11 -0
  23. package/src/components/table-pager.tsx +101 -0
  24. package/src/components/ui/alert-dialog.tsx +180 -0
  25. package/src/components/ui/alert.tsx +78 -0
  26. package/src/components/ui/avatar.tsx +58 -0
  27. package/src/components/ui/badge.tsx +49 -0
  28. package/src/components/ui/button-group.tsx +38 -0
  29. package/src/components/ui/button.tsx +67 -0
  30. package/src/components/ui/card.tsx +82 -0
  31. package/src/components/ui/chart.tsx +307 -0
  32. package/src/components/ui/checkbox.tsx +30 -0
  33. package/src/components/ui/combobox.tsx +256 -0
  34. package/src/components/ui/dialog.tsx +163 -0
  35. package/src/components/ui/dropdown-menu.tsx +110 -0
  36. package/src/components/ui/empty.tsx +65 -0
  37. package/src/components/ui/field.tsx +192 -0
  38. package/src/components/ui/input-group.tsx +118 -0
  39. package/src/components/ui/input-otp.tsx +70 -0
  40. package/src/components/ui/input.tsx +19 -0
  41. package/src/components/ui/label.tsx +24 -0
  42. package/src/components/ui/pagination.tsx +34 -0
  43. package/src/components/ui/popover.tsx +86 -0
  44. package/src/components/ui/select.tsx +145 -0
  45. package/src/components/ui/skeleton.tsx +19 -0
  46. package/src/components/ui/sonner.tsx +47 -0
  47. package/src/components/ui/switch.tsx +31 -0
  48. package/src/components/ui/table.tsx +81 -0
  49. package/src/components/ui/textarea.tsx +18 -0
  50. package/src/components/ui/tooltip.tsx +55 -0
  51. package/src/features/admin/admin-settings.tsx +1048 -0
  52. package/src/features/auth/current-user-context-query.ts +11 -0
  53. package/src/features/auth/login-form.tsx +442 -0
  54. package/src/features/auth/sign-out-menu-item.tsx +42 -0
  55. package/src/features/deployments/deployment-actions.tsx +336 -0
  56. package/src/features/deployments/deployment-alias-badge.tsx +35 -0
  57. package/src/features/deployments/deployment-detail.tsx +596 -0
  58. package/src/features/deployments/deployment-filters.ts +66 -0
  59. package/src/features/deployments/deployment-list.tsx +465 -0
  60. package/src/features/deployments/deployment-visit-links.tsx +104 -0
  61. package/src/features/deployments/deployments-page.tsx +376 -0
  62. package/src/features/logs/log-scroll-area.tsx +69 -0
  63. package/src/features/notifications/email-preferences.tsx +232 -0
  64. package/src/features/onboarding/profile-onboarding.tsx +162 -0
  65. package/src/features/plugins/contributions.tsx +118 -0
  66. package/src/features/projects/backup-job-logs.tsx +143 -0
  67. package/src/features/projects/backup-policy-delete-dialog.tsx +82 -0
  68. package/src/features/projects/backup-restore-actions.tsx +573 -0
  69. package/src/features/projects/backup-status-icon.tsx +33 -0
  70. package/src/features/projects/backup-target-list.tsx +222 -0
  71. package/src/features/projects/backup-timestamp.tsx +32 -0
  72. package/src/features/projects/backup-volume-picker.tsx +158 -0
  73. package/src/features/projects/compose-service-input.tsx +64 -0
  74. package/src/features/projects/deploy-readiness.ts +28 -0
  75. package/src/features/projects/environment-dot.tsx +91 -0
  76. package/src/features/projects/log-keyword-filter.tsx +48 -0
  77. package/src/features/projects/manual-deploy-dialog.tsx +563 -0
  78. package/src/features/projects/pending-section.ts +26 -0
  79. package/src/features/projects/project-backup-details-pending.tsx +305 -0
  80. package/src/features/projects/project-backup-details.tsx +936 -0
  81. package/src/features/projects/project-backup-policy.tsx +644 -0
  82. package/src/features/projects/project-backup-utils.ts +190 -0
  83. package/src/features/projects/project-backups-pending.tsx +136 -0
  84. package/src/features/projects/project-backups.tsx +876 -0
  85. package/src/features/projects/project-environment-settings.tsx +1128 -0
  86. package/src/features/projects/project-heading.tsx +68 -0
  87. package/src/features/projects/project-layout.tsx +188 -0
  88. package/src/features/projects/project-logs.tsx +461 -0
  89. package/src/features/projects/project-overview.tsx +280 -0
  90. package/src/features/projects/project-route-pending.tsx +1064 -0
  91. package/src/features/projects/project-routing-settings.tsx +663 -0
  92. package/src/features/projects/project-settings-section.tsx +64 -0
  93. package/src/features/projects/project-settings-utils.ts +101 -0
  94. package/src/features/projects/project-settings.tsx +1472 -0
  95. package/src/features/projects/repository-picker-dialog.tsx +404 -0
  96. package/src/features/repositories/new-project-dialog-launcher.tsx +44 -0
  97. package/src/features/repositories/new-project-dialog.tsx +1204 -0
  98. package/src/features/repositories/new-project-pending.tsx +28 -0
  99. package/src/features/repositories/repository-list-pending.tsx +59 -0
  100. package/src/features/servers/server-availability-alert.tsx +44 -0
  101. package/src/features/servers/server-availability.ts +29 -0
  102. package/src/features/servers/server-avatar.tsx +52 -0
  103. package/src/features/servers/server-detail-pending.tsx +315 -0
  104. package/src/features/servers/server-detail.tsx +855 -0
  105. package/src/features/servers/server-metric-chart-pending.tsx +38 -0
  106. package/src/features/servers/server-metric-chart.tsx +182 -0
  107. package/src/features/servers/server-metric-format.ts +50 -0
  108. package/src/features/servers/server-metrics-pending.tsx +75 -0
  109. package/src/features/servers/server-metrics.tsx +136 -0
  110. package/src/features/servers/team-servers.tsx +432 -0
  111. package/src/features/settings/settings-route-pending.tsx +406 -0
  112. package/src/features/teams/backup-storage-settings.tsx +483 -0
  113. package/src/features/teams/navigation.ts +51 -0
  114. package/src/features/teams/new-team-dialog.tsx +132 -0
  115. package/src/features/teams/pending-section.ts +19 -0
  116. package/src/features/teams/team-header.tsx +1286 -0
  117. package/src/features/teams/team-heading.tsx +57 -0
  118. package/src/features/teams/team-home.tsx +391 -0
  119. package/src/features/teams/team-invite.tsx +155 -0
  120. package/src/features/teams/team-route-pending.tsx +505 -0
  121. package/src/features/teams/team-settings.tsx +1555 -0
  122. package/src/features/teams/use-workspace-updates.ts +126 -0
  123. package/src/features/users/api-keys-settings.tsx +544 -0
  124. package/src/features/users/api-scope-selection.tsx +269 -0
  125. package/src/features/users/connected-apps-settings.tsx +449 -0
  126. package/src/features/users/mcp-consent.tsx +220 -0
  127. package/src/features/users/profile-picture.tsx +171 -0
  128. package/src/features/users/user-settings.tsx +1064 -0
  129. package/src/lib/account-settings-schema.ts +78 -0
  130. package/src/lib/action-feedback.ts +81 -0
  131. package/src/lib/admin-search-schema.ts +8 -0
  132. package/src/lib/agent-release.d.mts +21 -0
  133. package/src/lib/agent-release.mjs +90 -0
  134. package/src/lib/allowlist-schema.ts +79 -0
  135. package/src/lib/api-key-schema.ts +176 -0
  136. package/src/lib/auth/client.ts +20 -0
  137. package/src/lib/avatar-schema.ts +11 -0
  138. package/src/lib/backup-cron.ts +118 -0
  139. package/src/lib/backup-database.ts +41 -0
  140. package/src/lib/backup-feature.ts +2 -0
  141. package/src/lib/backup-paths.ts +7 -0
  142. package/src/lib/backup-policy-schema.ts +85 -0
  143. package/src/lib/backup-resource-schema.ts +12 -0
  144. package/src/lib/backup-restore-schema.ts +15 -0
  145. package/src/lib/backup-storage-schema.ts +55 -0
  146. package/src/lib/deferred-module.ts +38 -0
  147. package/src/lib/deployment-logs-query.ts +63 -0
  148. package/src/lib/display-name.ts +7 -0
  149. package/src/lib/error-message.ts +119 -0
  150. package/src/lib/form-errors.ts +10 -0
  151. package/src/lib/internal-redirect.ts +25 -0
  152. package/src/lib/manual-deploy-options-query.ts +21 -0
  153. package/src/lib/notification-preferences.ts +43 -0
  154. package/src/lib/onboarding.ts +11 -0
  155. package/src/lib/operation-logs-query.ts +51 -0
  156. package/src/lib/page-head.ts +14 -0
  157. package/src/lib/project-context-query.ts +257 -0
  158. package/src/lib/project-creation-schema.ts +64 -0
  159. package/src/lib/project-env-schema.ts +23 -0
  160. package/src/lib/project-environments-schema.ts +56 -0
  161. package/src/lib/project-routing-schema.ts +94 -0
  162. package/src/lib/project-runtime-config.ts +131 -0
  163. package/src/lib/project-settings-schema.ts +75 -0
  164. package/src/lib/public-api-schema.ts +128 -0
  165. package/src/lib/public-error.ts +337 -0
  166. package/src/lib/query.ts +13 -0
  167. package/src/lib/repository-selection-query.ts +11 -0
  168. package/src/lib/resource-cache.ts +30 -0
  169. package/src/lib/runtime-id.ts +19 -0
  170. package/src/lib/search.ts +14 -0
  171. package/src/lib/server-context-query.ts +43 -0
  172. package/src/lib/server-name-schema.ts +11 -0
  173. package/src/lib/settings-conflict.ts +45 -0
  174. package/src/lib/settings-version.ts +7 -0
  175. package/src/lib/team-context-query.ts +126 -0
  176. package/src/lib/team-context-schema.ts +8 -0
  177. package/src/lib/team-forms-schema.ts +45 -0
  178. package/src/lib/team-role.ts +13 -0
  179. package/src/lib/team-settings-schema.ts +48 -0
  180. package/src/lib/urls.ts +3 -0
  181. package/src/lib/use-avatar-input.ts +61 -0
  182. package/src/lib/use-refresh-error.ts +18 -0
  183. package/src/lib/use-settings-version.ts +23 -0
  184. package/src/lib/utils.ts +6 -0
  185. package/src/lib/validation.ts +5 -0
  186. package/src/lib/workspace-updates.ts +53 -0
  187. package/src/package/config.ts +10 -0
  188. package/src/package/env.mjs +54 -0
  189. package/src/package/migrate-api.d.ts +5 -0
  190. package/src/package/migrate.ts +56 -0
  191. package/src/package/plugins.ts +141 -0
  192. package/src/package/sqlite.mjs +2 -0
  193. package/src/package/vite-api.d.ts +5 -0
  194. package/src/package/vite.ts +324 -0
  195. package/src/package/watch-guard.cjs +26 -0
  196. package/src/plugins/client.ts +57 -0
  197. package/src/plugins/contract.ts +188 -0
  198. package/src/plugins/default.server.ts +4 -0
  199. package/src/plugins/default.ui.ts +4 -0
  200. package/src/plugins/operations.ts +45 -0
  201. package/src/plugins/server.ts +197 -0
  202. package/src/plugins/version.ts +1 -0
  203. package/src/routeTree.gen.ts +1275 -0
  204. package/src/router.tsx +46 -0
  205. package/src/routes/$teamSlug.index.tsx +53 -0
  206. package/src/routes/$teamSlug.new-project.tsx +13 -0
  207. package/src/routes/$teamSlug.projects.$projectName.backups.$backupId.tsx +40 -0
  208. package/src/routes/$teamSlug.projects.$projectName.backups.tsx +82 -0
  209. package/src/routes/$teamSlug.projects.$projectName.deployments.$deploymentId.tsx +52 -0
  210. package/src/routes/$teamSlug.projects.$projectName.deployments.tsx +86 -0
  211. package/src/routes/$teamSlug.projects.$projectName.logs.tsx +55 -0
  212. package/src/routes/$teamSlug.projects.$projectName.settings.tsx +51 -0
  213. package/src/routes/$teamSlug.projects.$projectName.tsx +106 -0
  214. package/src/routes/$teamSlug.projects.tsx +40 -0
  215. package/src/routes/$teamSlug.servers.$serverId.tsx +31 -0
  216. package/src/routes/$teamSlug.servers.index.tsx +59 -0
  217. package/src/routes/$teamSlug.servers.tsx +7 -0
  218. package/src/routes/$teamSlug.settings.tsx +56 -0
  219. package/src/routes/$teamSlug.tsx +86 -0
  220. package/src/routes/[.]well-known.oauth-authorization-server.api.auth.ts +13 -0
  221. package/src/routes/[.]well-known.oauth-protected-resource.mcp.ts +6 -0
  222. package/src/routes/__root.tsx +155 -0
  223. package/src/routes/admin.tsx +55 -0
  224. package/src/routes/api/agents/certificates.ts +21 -0
  225. package/src/routes/api/agents/credentials/rotate.ts +22 -0
  226. package/src/routes/api/agents/heartbeat.ts +42 -0
  227. package/src/routes/api/agents/job-logs.ts +22 -0
  228. package/src/routes/api/agents/jobs/complete.ts +22 -0
  229. package/src/routes/api/agents/jobs/next.ts +29 -0
  230. package/src/routes/api/agents/jobs/progress.ts +32 -0
  231. package/src/routes/api/agents/jobs/status.ts +22 -0
  232. package/src/routes/api/agents/register.ts +45 -0
  233. package/src/routes/api/agents/runtime-logs.ts +22 -0
  234. package/src/routes/api/agents/switch.ts +25 -0
  235. package/src/routes/api/auth/$.ts +38 -0
  236. package/src/routes/api/cron/backups.ts +33 -0
  237. package/src/routes/api/cron/maintenance.ts +30 -0
  238. package/src/routes/api/github/install.callback.ts +51 -0
  239. package/src/routes/api/github/install.ts +41 -0
  240. package/src/routes/api/github/webhook.ts +11 -0
  241. package/src/routes/api/health.ts +19 -0
  242. package/src/routes/api/install/agent.$token.ts +50 -0
  243. package/src/routes/api/install/agent.binary.ts +83 -0
  244. package/src/routes/api/install/agent.checksum.ts +45 -0
  245. package/src/routes/api/install/agent.ts +26 -0
  246. package/src/routes/api/plugins/$.ts +11 -0
  247. package/src/routes/api/v1/$.ts +15 -0
  248. package/src/routes/api/workspaces/updates.ts +8 -0
  249. package/src/routes/auth.login.tsx +50 -0
  250. package/src/routes/deployments.$deploymentId.unavailable.tsx +21 -0
  251. package/src/routes/index.tsx +23 -0
  252. package/src/routes/invites.$token.tsx +35 -0
  253. package/src/routes/mcp.ts +13 -0
  254. package/src/routes/oauth.consent.tsx +54 -0
  255. package/src/routes/onboarding.tsx +37 -0
  256. package/src/routes/onboarding.workspace.tsx +44 -0
  257. package/src/routes/settings.tsx +30 -0
  258. package/src/routes/uploads/avatars/$fileName.ts +44 -0
  259. package/src/server/admin/access.ts +67 -0
  260. package/src/server/admin/functions.ts +122 -0
  261. package/src/server/admin/service.ts +260 -0
  262. package/src/server/agents/backup-state.ts +210 -0
  263. package/src/server/agents/certificates.ts +96 -0
  264. package/src/server/agents/claims.ts +116 -0
  265. package/src/server/agents/cleanup.ts +52 -0
  266. package/src/server/agents/compatibility.ts +116 -0
  267. package/src/server/agents/completion.ts +83 -0
  268. package/src/server/agents/container-cleanup-state.ts +51 -0
  269. package/src/server/agents/deployment-state.ts +111 -0
  270. package/src/server/agents/job-payloads.ts +159 -0
  271. package/src/server/agents/jobs.ts +1293 -0
  272. package/src/server/agents/protocol.ts +400 -0
  273. package/src/server/agents/reconciliation.ts +43 -0
  274. package/src/server/agents/runtime-logs.ts +337 -0
  275. package/src/server/agents/runtime-state.ts +125 -0
  276. package/src/server/api/admission.ts +12 -0
  277. package/src/server/api/authorization.ts +115 -0
  278. package/src/server/api/credentials.ts +569 -0
  279. package/src/server/api/cursors.ts +72 -0
  280. package/src/server/api/errors.ts +24 -0
  281. package/src/server/api/functions.ts +60 -0
  282. package/src/server/api/handler.ts +274 -0
  283. package/src/server/api/mutation-operations.ts +913 -0
  284. package/src/server/api/operation-context.ts +139 -0
  285. package/src/server/api/operation-contract.ts +1099 -0
  286. package/src/server/api/operations.ts +64 -0
  287. package/src/server/api/read-operations.ts +891 -0
  288. package/src/server/api/retention.ts +33 -0
  289. package/src/server/auth/access.ts +109 -0
  290. package/src/server/auth/auth-methods.ts +28 -0
  291. package/src/server/auth/better-auth.ts +518 -0
  292. package/src/server/auth/context.ts +28 -0
  293. package/src/server/auth/email-change.ts +47 -0
  294. package/src/server/auth/email-delivery.ts +51 -0
  295. package/src/server/auth/provider-identity.ts +19 -0
  296. package/src/server/auth/provider-tokens.ts +27 -0
  297. package/src/server/auth/session.server.ts +19 -0
  298. package/src/server/backups/database-commands.ts +40 -0
  299. package/src/server/backups/destination.ts +12 -0
  300. package/src/server/backups/feature.ts +6 -0
  301. package/src/server/backups/policy-validation.ts +51 -0
  302. package/src/server/backups/queue-state.ts +137 -0
  303. package/src/server/backups/service.ts +918 -0
  304. package/src/server/backups/storage-functions.ts +42 -0
  305. package/src/server/backups/storage-state.ts +67 -0
  306. package/src/server/backups/storage.ts +237 -0
  307. package/src/server/config.ts +274 -0
  308. package/src/server/db/atomic.ts +16 -0
  309. package/src/server/db/d1-connection.ts +83 -0
  310. package/src/server/db/errors.ts +17 -0
  311. package/src/server/db/index.cloudflare.ts +15 -0
  312. package/src/server/db/index.ts +35 -0
  313. package/src/server/db/libsql-connection.ts +72 -0
  314. package/src/server/db/log-schema.ts +102 -0
  315. package/src/server/db/migrate-libsql.ts +29 -0
  316. package/src/server/db/migrate-sqlite.ts +47 -0
  317. package/src/server/db/migration-history.ts +12 -0
  318. package/src/server/db/migrations-logs/0000_initial.sql +48 -0
  319. package/src/server/db/migrations-logs/0001_runtime_log_order.sql +2 -0
  320. package/src/server/db/migrations-logs/meta/0000_snapshot.json +327 -0
  321. package/src/server/db/migrations-logs/meta/0001_snapshot.json +329 -0
  322. package/src/server/db/migrations-logs/meta/_journal.json +20 -0
  323. package/src/server/db/migrations-sqlite/0000_initial.sql +894 -0
  324. package/src/server/db/migrations-sqlite/0001_agent_indexes.sql +5 -0
  325. package/src/server/db/migrations-sqlite/meta/0000_snapshot.json +5816 -0
  326. package/src/server/db/migrations-sqlite/meta/0001_snapshot.json +5841 -0
  327. package/src/server/db/migrations-sqlite/meta/_journal.json +20 -0
  328. package/src/server/db/oauth-schema.ts +216 -0
  329. package/src/server/db/remote-config.ts +47 -0
  330. package/src/server/db/schema.ts +1218 -0
  331. package/src/server/db/sqlite-connection.ts +94 -0
  332. package/src/server/db/sqlite-files.ts +27 -0
  333. package/src/server/db/sqlite-params.ts +19 -0
  334. package/src/server/db/worker-connection.ts +47 -0
  335. package/src/server/deleted-resources.ts +133 -0
  336. package/src/server/deletion-recovery.ts +272 -0
  337. package/src/server/email/layout.tsx +85 -0
  338. package/src/server/email/notification-template.tsx +62 -0
  339. package/src/server/email/otp-template.tsx +48 -0
  340. package/src/server/email/service.ts +251 -0
  341. package/src/server/email/team-invite-template.tsx +59 -0
  342. package/src/server/email/theme.ts +10 -0
  343. package/src/server/github/http.ts +14 -0
  344. package/src/server/github/install-state.ts +48 -0
  345. package/src/server/github/service.ts +831 -0
  346. package/src/server/github/webhook-handler.ts +198 -0
  347. package/src/server/github/webhooks.ts +205 -0
  348. package/src/server/http/auth.ts +11 -0
  349. package/src/server/http/error-diagnostics.ts +66 -0
  350. package/src/server/http/plugin-request.ts +15 -0
  351. package/src/server/http/proxy-request.ts +53 -0
  352. package/src/server/http/public-errors.ts +48 -0
  353. package/src/server/http/rate-limit.ts +59 -0
  354. package/src/server/http/request-body.ts +54 -0
  355. package/src/server/http/request-ip.ts +54 -0
  356. package/src/server/http/security-headers.ts +36 -0
  357. package/src/server/install/agent-binary.ts +230 -0
  358. package/src/server/install/agent-script.ts +565 -0
  359. package/src/server/install/release-binary.ts +65 -0
  360. package/src/server/logs/budget.ts +72 -0
  361. package/src/server/logs/cleanup.ts +64 -0
  362. package/src/server/logs/deployments.ts +98 -0
  363. package/src/server/logs/operations.ts +145 -0
  364. package/src/server/logs/retention.ts +39 -0
  365. package/src/server/maintenance.ts +61 -0
  366. package/src/server/mcp/connections.ts +358 -0
  367. package/src/server/mcp/functions.ts +63 -0
  368. package/src/server/mcp/handler.ts +295 -0
  369. package/src/server/mcp/oauth-discovery.cloudflare.ts +6 -0
  370. package/src/server/mcp/oauth-discovery.ts +8 -0
  371. package/src/server/mcp/oauth-provider.ts +220 -0
  372. package/src/server/mcp/urls.ts +20 -0
  373. package/src/server/notifications/functions.ts +51 -0
  374. package/src/server/notifications/observe.ts +303 -0
  375. package/src/server/notifications/outbox.ts +335 -0
  376. package/src/server/notifications/preferences.ts +131 -0
  377. package/src/server/notifications/query.ts +16 -0
  378. package/src/server/plugins/scope.ts +17 -0
  379. package/src/server/plugins/server-context.ts +157 -0
  380. package/src/server/plugins/services.server.ts +10 -0
  381. package/src/server/plugins/workspace-access.ts +74 -0
  382. package/src/server/projects/backup-policy-state.ts +68 -0
  383. package/src/server/projects/backups.ts +219 -0
  384. package/src/server/projects/compose-metadata.ts +174 -0
  385. package/src/server/projects/configuration-state.ts +90 -0
  386. package/src/server/projects/context.ts +909 -0
  387. package/src/server/projects/creation-state.ts +46 -0
  388. package/src/server/projects/deletion-state.ts +69 -0
  389. package/src/server/projects/deployment-config.ts +139 -0
  390. package/src/server/projects/deployment-logs.ts +97 -0
  391. package/src/server/projects/deployments.ts +1123 -0
  392. package/src/server/projects/domain-state.ts +71 -0
  393. package/src/server/projects/environment-branches.ts +75 -0
  394. package/src/server/projects/environment-state.ts +158 -0
  395. package/src/server/projects/environments.ts +424 -0
  396. package/src/server/projects/functions.ts +748 -0
  397. package/src/server/projects/generated-hostname.ts +77 -0
  398. package/src/server/projects/hostnames.ts +244 -0
  399. package/src/server/projects/mappers.ts +457 -0
  400. package/src/server/projects/names.ts +41 -0
  401. package/src/server/projects/project-env-vars.ts +28 -0
  402. package/src/server/projects/queue-state.ts +118 -0
  403. package/src/server/projects/repository.ts +368 -0
  404. package/src/server/projects/route-state.ts +37 -0
  405. package/src/server/projects/runtime-logs.ts +97 -0
  406. package/src/server/projects/settings-context.ts +58 -0
  407. package/src/server/projects/settings.ts +738 -0
  408. package/src/server/projects/types.ts +355 -0
  409. package/src/server/realtime/agent-events.ts +32 -0
  410. package/src/server/realtime/node-broadcaster.ts +71 -0
  411. package/src/server/realtime/node-handler.ts +55 -0
  412. package/src/server/realtime/service.ts +125 -0
  413. package/src/server/realtime/workspace-object.cloudflare.ts +62 -0
  414. package/src/server/realtime/workspace-object.ts +3 -0
  415. package/src/server/resources/color.ts +13 -0
  416. package/src/server/runtime/background.ts +21 -0
  417. package/src/server/runtime/node-asset-cache-plugin.ts +12 -0
  418. package/src/server/runtime/node-scheduler-plugin.ts +17 -0
  419. package/src/server/runtime/node-scheduler.ts +51 -0
  420. package/src/server/runtime/platform-env.cloudflare.ts +17 -0
  421. package/src/server/runtime/platform-env.ts +19 -0
  422. package/src/server/runtime/scheduled-task-error.ts +9 -0
  423. package/src/server/scheduled-tasks.ts +28 -0
  424. package/src/server/secrets/crypto.ts +56 -0
  425. package/src/server/servers/functions.ts +233 -0
  426. package/src/server/servers/lifecycle.ts +122 -0
  427. package/src/server/servers/metric-history-schema.ts +24 -0
  428. package/src/server/servers/metric-history.ts +55 -0
  429. package/src/server/servers/monitoring.ts +592 -0
  430. package/src/server/servers/service.ts +1211 -0
  431. package/src/server/servers/status.ts +32 -0
  432. package/src/server/servers/switch.ts +96 -0
  433. package/src/server/settings-version.ts +43 -0
  434. package/src/server/storage/capabilities.ts +6 -0
  435. package/src/server/storage/local-object-store.cloudflare.ts +7 -0
  436. package/src/server/storage/local-object-store.ts +50 -0
  437. package/src/server/storage/object-store.ts +160 -0
  438. package/src/server/teams/creation.ts +51 -0
  439. package/src/server/teams/delete-policy.ts +13 -0
  440. package/src/server/teams/deletion-state.ts +80 -0
  441. package/src/server/teams/functions.ts +324 -0
  442. package/src/server/teams/invitations.ts +38 -0
  443. package/src/server/teams/membership.ts +86 -0
  444. package/src/server/teams/queries.ts +261 -0
  445. package/src/server/teams/service.ts +1127 -0
  446. package/src/server/teams/types.ts +101 -0
  447. package/src/server/uploads/avatar.ts +133 -0
  448. package/src/server/users/deletion-state.ts +93 -0
  449. package/src/server/users/functions.ts +160 -0
  450. package/src/server/users/onboarding.ts +17 -0
  451. package/src/server/users/service.ts +644 -0
  452. package/src/server.ts +55 -0
  453. package/src/styles/shadcn.css +653 -0
  454. package/src/styles/theme.css +76 -0
  455. package/src/styles.css +177 -0
  456. package/wrangler.template.jsonc +37 -0
@@ -0,0 +1,126 @@
1
+ import { workspacePollInterval } from './workspace-updates'
2
+ import type { TeamSummary } from '#devpush/server/teams/types'
3
+ import { queryOptions } from '@tanstack/react-query'
4
+ import type { QueryClient } from '@tanstack/react-query'
5
+ import { redirect } from '@tanstack/react-router'
6
+
7
+ import {
8
+ getTeamSectionContext,
9
+ getTeamShellContext,
10
+ } from '#devpush/server/teams/functions'
11
+ import type { TeamContextSection } from '#devpush/lib/team-context-schema'
12
+
13
+ export type { TeamContextSection } from '#devpush/lib/team-context-schema'
14
+ export type TeamShellContext = NonNullable<
15
+ Awaited<ReturnType<typeof getTeamShellContext>>
16
+ >
17
+
18
+ export function teamShellQueryOptions({ teamSlug }: { teamSlug: string }) {
19
+ return queryOptions({
20
+ queryKey: ['team-context', teamSlug, 'shell'],
21
+ queryFn: async () => {
22
+ const context = await getTeamShellContext({ data: { teamSlug } })
23
+
24
+ if (!context) {
25
+ throw redirect({ to: '/auth/login' })
26
+ }
27
+
28
+ return context
29
+ },
30
+ })
31
+ }
32
+
33
+ export function teamSectionQueryOptions({
34
+ section,
35
+ teamSlug,
36
+ }: {
37
+ section: TeamContextSection
38
+ teamSlug: string
39
+ }) {
40
+ return queryOptions({
41
+ queryKey: ['team-context', teamSlug, 'section', section],
42
+ refetchIntervalInBackground: false,
43
+ refetchOnWindowFocus: ['servers', 'overview'].includes(section)
44
+ ? 'always'
45
+ : false,
46
+ refetchInterval: (query) =>
47
+ section === 'servers'
48
+ ? workspacePollInterval(teamSlug, 5_000)
49
+ : query.state.data?.section === 'overview' &&
50
+ query.state.data.deployments.some((deployment) =>
51
+ ['queued', 'running'].includes(deployment.status),
52
+ )
53
+ ? workspacePollInterval(teamSlug, 2_000)
54
+ : section === 'overview'
55
+ ? workspacePollInterval(teamSlug, 15_000)
56
+ : false,
57
+ queryFn: async () => {
58
+ const context = await getTeamSectionContext({
59
+ data: { section, teamSlug },
60
+ })
61
+
62
+ if (!context) {
63
+ throw redirect({ to: '/auth/login' })
64
+ }
65
+
66
+ return context
67
+ },
68
+ })
69
+ }
70
+
71
+ export function invalidateTeamContext(
72
+ queryClient: QueryClient,
73
+ teamSlug?: string,
74
+ ) {
75
+ return queryClient.invalidateQueries({
76
+ queryKey: teamSlug ? ['team-context', teamSlug] : ['team-context'],
77
+ })
78
+ }
79
+
80
+ export function getCachedTeamContexts(
81
+ queryClient: QueryClient,
82
+ teamSlug: string,
83
+ ) {
84
+ return queryClient
85
+ .getQueriesData<TeamShellContext>({
86
+ queryKey: ['team-context', teamSlug, 'shell'],
87
+ })
88
+ .flatMap(([, context]) => (context ? [context] : []))
89
+ }
90
+
91
+ // Team metadata is embedded in navigation for both team and project pages.
92
+ // Preserve each snapshot's age: changing a name does not refresh its other data.
93
+ export async function setTeamContextQueryData(
94
+ queryClient: QueryClient,
95
+ team: TeamSummary,
96
+ ) {
97
+ const filters = {
98
+ predicate: ({ queryKey }: { queryKey: readonly unknown[] }) =>
99
+ (queryKey[0] === 'team-context' && queryKey[2] === 'shell') ||
100
+ ['project-context', 'deployment-context', 'project-logs'].includes(
101
+ String(queryKey[0]),
102
+ ),
103
+ }
104
+ await queryClient.cancelQueries(filters)
105
+ for (const query of queryClient.getQueryCache().findAll(filters)) {
106
+ const cached = query.state.data as
107
+ | Pick<TeamShellContext, 'team' | 'userContext'>
108
+ | undefined
109
+ if (!cached) continue
110
+ const replaceTeam = (current: TeamSummary) =>
111
+ current.id === team.id ? team : current
112
+ queryClient.setQueryData(
113
+ query.queryKey,
114
+ {
115
+ ...cached,
116
+ team: replaceTeam(cached.team),
117
+ userContext: {
118
+ ...cached.userContext,
119
+ teams: cached.userContext.teams.map(replaceTeam),
120
+ defaultTeam: replaceTeam(cached.userContext.defaultTeam),
121
+ },
122
+ },
123
+ { updatedAt: query.state.dataUpdatedAt },
124
+ )
125
+ }
126
+ }
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod'
2
+
3
+ export const teamContextSectionSchema = z.enum([
4
+ 'overview',
5
+ 'servers',
6
+ 'settings',
7
+ ])
8
+ export type TeamContextSection = z.infer<typeof teamContextSectionSchema>
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod'
2
+
3
+ export const createTeamSchema = z.object({
4
+ name: z
5
+ .string()
6
+ .trim()
7
+ .min(1, 'Enter a team name.')
8
+ .max(100, 'Team names must be 100 characters or fewer.'),
9
+ })
10
+ const emailSchema = z
11
+ .string()
12
+ .trim()
13
+ .min(1, 'Enter an email address.')
14
+ .email('Enter a valid email address.')
15
+ .max(320, 'Email addresses must be 320 characters or fewer.')
16
+ const inviteSchema = z.object({
17
+ teamSlug: z.string().min(1),
18
+ email: emailSchema,
19
+ role: z.enum(['admin', 'member']),
20
+ })
21
+ export function parseInviteEmails(value: string) {
22
+ return [
23
+ ...new Set(
24
+ value
25
+ .split(/[\s,]+/)
26
+ .map((email) => email.trim().toLowerCase())
27
+ .filter((email) => emailSchema.safeParse(email).success),
28
+ ),
29
+ ]
30
+ }
31
+ export const bulkInviteSchema = inviteSchema.omit({ email: true }).extend({
32
+ emails: z
33
+ .string()
34
+ .trim()
35
+ .min(1, 'Enter at least one email address.')
36
+ .max(20000, 'Enter at most 20,000 characters at a time.')
37
+ .superRefine((value, ctx) => {
38
+ const emails = parseInviteEmails(value)
39
+ if (!emails.length)
40
+ ctx.addIssue({
41
+ code: 'custom',
42
+ message: 'Enter at least one valid email address.',
43
+ })
44
+ }),
45
+ })
@@ -0,0 +1,13 @@
1
+ export type TeamRole = 'owner' | 'admin' | 'member'
2
+
3
+ export function canManageTeamSettings(role: TeamRole) {
4
+ return role === 'owner' || role === 'admin'
5
+ }
6
+
7
+ export function canManageTeamMembers(role: TeamRole) {
8
+ return role === 'owner' || role === 'admin'
9
+ }
10
+
11
+ export function canDeleteTeam(role: TeamRole) {
12
+ return role === 'owner'
13
+ }
@@ -0,0 +1,48 @@
1
+ import { settingsVersionSchema } from '#devpush/lib/settings-version'
2
+ import { z } from 'zod'
3
+ import { avatarDataUrlSchema } from '#devpush/lib/avatar-schema'
4
+ import type { FormErrors } from './form-errors'
5
+
6
+ export const teamGeneralSchema = z.object({
7
+ settingsVersion: settingsVersionSchema,
8
+ teamId: z.string().min(1),
9
+ teamSlug: z.string().min(1),
10
+ name: z
11
+ .string()
12
+ .trim()
13
+ .min(1, 'Enter a team name.')
14
+ .max(100, 'Team names must be 100 characters or fewer.'),
15
+ slug: z
16
+ .string()
17
+ .trim()
18
+ .min(2, 'Enter a slug with at least 2 characters.')
19
+ .max(100, 'Slugs must be 100 characters or fewer.')
20
+ .regex(
21
+ /^[A-Za-z0-9][A-Za-z0-9._-]*[A-Za-z0-9]$/,
22
+ 'Use letters, numbers, dots, underscores, or hyphens. Start and end with a letter or number.',
23
+ ),
24
+ avatarDataUrl: avatarDataUrlSchema,
25
+ deleteAvatar: z.boolean().optional(),
26
+ })
27
+
28
+ export function teamSettingsErrors(error: unknown): FormErrors | null {
29
+ if (!(error instanceof Error)) return null
30
+ if (error.message === 'Team name is required.')
31
+ return { name: 'Enter a team name.' }
32
+ if (
33
+ [
34
+ 'This slug is reserved.',
35
+ 'A team with this slug already exists.',
36
+ ].includes(error.message)
37
+ )
38
+ return { slug: error.message }
39
+ if (
40
+ [
41
+ 'Upload a PNG, JPEG, or WebP image.',
42
+ 'Avatars must be 2 MB or smaller.',
43
+ 'The uploaded file does not match its image type.',
44
+ ].includes(error.message)
45
+ )
46
+ return { avatarDataUrl: error.message }
47
+ return null
48
+ }
@@ -0,0 +1,3 @@
1
+ export function routeUrl({ host, https }: { host: string; https: boolean }) {
2
+ return `${https ? 'https' : 'http'}://${host}`
3
+ }
@@ -0,0 +1,61 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+
3
+ // A reset, removal, or newer selection invalidates the previous file read.
4
+ export function useAvatarInput() {
5
+ const [dataUrl, setDataUrlState] = useState<string | null>(null)
6
+ const [pending, setPending] = useState(false)
7
+ const cancelRef = useRef<(() => void) | null>(null)
8
+ const cancelRead = useCallback(() => {
9
+ cancelRef.current?.()
10
+ cancelRef.current = null
11
+ setPending(false)
12
+ }, [])
13
+ useEffect(() => () => cancelRef.current?.(), [])
14
+ const setDataUrl = useCallback(
15
+ (value: string | null) => {
16
+ cancelRead()
17
+ setDataUrlState(value)
18
+ },
19
+ [cancelRead],
20
+ )
21
+ const read = useCallback(
22
+ (file: File) => {
23
+ cancelRead()
24
+ setPending(true)
25
+ return new Promise<string | null>((resolve, reject) => {
26
+ const reader = new FileReader()
27
+ let settled = false
28
+ const finish = (value: string | null, error?: Error) => {
29
+ if (settled) return
30
+ settled = true
31
+ reader.onload = reader.onerror = reader.onabort = null
32
+ cancelRef.current = null
33
+ setPending(false)
34
+ if (error) reject(error)
35
+ else resolve(value)
36
+ }
37
+ cancelRef.current = () => {
38
+ if (settled) return
39
+ settled = true
40
+ reader.onload = reader.onerror = reader.onabort = null
41
+ if (reader.readyState === FileReader.LOADING) reader.abort()
42
+ resolve(null)
43
+ }
44
+ reader.onload = () => {
45
+ if (typeof reader.result === 'string') finish(reader.result)
46
+ else finish(null, new Error('Unable to read image file.'))
47
+ }
48
+ reader.onerror = () =>
49
+ finish(null, new Error('Unable to read image file.'))
50
+ reader.onabort = () => finish(null)
51
+ try {
52
+ reader.readAsDataURL(file)
53
+ } catch {
54
+ finish(null, new Error('Unable to read image file.'))
55
+ }
56
+ })
57
+ },
58
+ [cancelRead],
59
+ )
60
+ return { dataUrl, setDataUrl, read, cancelRead, pending }
61
+ }
@@ -0,0 +1,18 @@
1
+ import { useEffect } from 'react'
2
+ import { toast } from 'sonner'
3
+
4
+ export function useRefreshError(error: unknown, id: string) {
5
+ useEffect(() => {
6
+ if (error) {
7
+ toast.error(
8
+ 'Unable to refresh. Displayed information may be out of date. Please reload.',
9
+ { id },
10
+ )
11
+ } else {
12
+ toast.dismiss(id)
13
+ }
14
+ return () => {
15
+ toast.dismiss(id)
16
+ }
17
+ }, [error, id])
18
+ }
@@ -0,0 +1,23 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ // Clean forms adopt an authoritative snapshot. Dirty forms keep the version
4
+ // they started from, so a refresh cannot silently turn a stale draft into a save.
5
+ export function useSettingsVersion({
6
+ version,
7
+ dirty,
8
+ saving,
9
+ refresh,
10
+ }: {
11
+ version: number
12
+ dirty: boolean
13
+ saving: boolean
14
+ refresh: () => void
15
+ }) {
16
+ const originalVersion = useRef(version)
17
+ useEffect(() => {
18
+ if (dirty || saving || version <= originalVersion.current) return
19
+ originalVersion.current = version
20
+ refresh()
21
+ }, [version, dirty, saving, refresh])
22
+ return originalVersion
23
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,5 @@
1
+ export function isValidEmail(value: string) {
2
+ return /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9-]*\.)+[A-Za-z]{2,}$/.test(
3
+ value,
4
+ )
5
+ }
@@ -0,0 +1,53 @@
1
+ const connections = new Set<string>()
2
+ export type UpdateKind = 'deployments' | 'servers' | 'logs'
3
+
4
+ export function setWorkspaceConnected(slug: string, connected: boolean) {
5
+ if (connected) connections.add(slug)
6
+ else connections.delete(slug)
7
+ }
8
+
9
+ export function workspacePollInterval(slug: string, fallback: number) {
10
+ return connections.has(slug) ? 60_000 : fallback
11
+ }
12
+
13
+ export function matchesWorkspaceUpdate(
14
+ key: readonly unknown[],
15
+ slug: string,
16
+ kind?: UpdateKind,
17
+ ) {
18
+ if (key[1] !== slug) return false
19
+ const family = String(key[0])
20
+ if (!kind)
21
+ return [
22
+ 'team-context',
23
+ 'project-context',
24
+ 'server-context',
25
+ 'server-metrics',
26
+ 'manual-deploy-options',
27
+ 'operation-logs',
28
+ 'deployment-context',
29
+ 'deployment-logs',
30
+ 'project-logs',
31
+ ].includes(family)
32
+ if (kind === 'logs') return family === 'project-logs'
33
+ if (kind === 'servers')
34
+ return (
35
+ family === 'server-context' ||
36
+ (family === 'team-context' &&
37
+ ['shell', 'servers'].includes(String(key.at(-1)))) ||
38
+ (family === 'project-context' && key.at(-1) === 'shell')
39
+ )
40
+ return (
41
+ [
42
+ 'deployment-context',
43
+ 'deployment-logs',
44
+ 'project-logs',
45
+ 'manual-deploy-options',
46
+ ].includes(family) ||
47
+ (family === 'team-context' && key.at(-1) === 'overview') ||
48
+ (family === 'project-context' &&
49
+ ['overview', 'deployments', 'shell', 'backups'].includes(
50
+ String(key.at(-1)),
51
+ ))
52
+ )
53
+ }
@@ -0,0 +1,10 @@
1
+ import type { DevpushPlugin } from './plugins'
2
+
3
+ export interface DevpushOptions {
4
+ /** Consumer project directory. Defaults to process.cwd(). */
5
+ root?: string
6
+ plugins?: readonly DevpushPlugin[]
7
+ target?: 'node' | 'cloudflare'
8
+ /** Wrangler configuration owned by the consumer. */
9
+ wranglerConfig?: string
10
+ }
@@ -0,0 +1,54 @@
1
+ import { parseEnv } from "node:util";
2
+
3
+ // Accept only encodings that round-trip through the runtime's dotenv parser.
4
+ export function encodeEnvValue(value) {
5
+ const candidates = [JSON.stringify(value)];
6
+ for (const quote of ["'", '"', "`"]) {
7
+ if (!value.includes(quote)) candidates.push(`${quote}${value}${quote}`);
8
+ }
9
+ candidates.push(value);
10
+ const encoded = candidates.find(
11
+ (candidate) => parseEnv(`VALUE=${candidate}\n`).VALUE === value,
12
+ );
13
+ if (encoded === undefined)
14
+ throw new Error("An environment value cannot be represented safely.");
15
+ return encoded;
16
+ }
17
+
18
+ export function updateEnvSource(source, updates) {
19
+ const lines = source.split(/\r?\n/u);
20
+ const seen = new Set();
21
+ const output = [];
22
+ for (let index = 0; index < lines.length; index++) {
23
+ const line = lines[index];
24
+ const match = line.match(
25
+ /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/u,
26
+ );
27
+ if (!match) {
28
+ output.push(line);
29
+ continue;
30
+ }
31
+ const [, key, value] = match;
32
+ const block = [line];
33
+ const quote = value[0];
34
+ if (["'", '"', "`"].includes(quote) && !value.slice(1).includes(quote)) {
35
+ while (++index < lines.length) {
36
+ block.push(lines[index]);
37
+ if (lines[index].includes(quote)) break;
38
+ }
39
+ if (index === lines.length)
40
+ throw new Error(
41
+ "Cannot update an unterminated quoted environment value.",
42
+ );
43
+ }
44
+ if (Object.hasOwn(updates, key) && updates[key] !== undefined) {
45
+ output.push(`${key}=${encodeEnvValue(String(updates[key]))}`);
46
+ seen.add(key);
47
+ } else output.push(...block);
48
+ }
49
+ for (const [key, value] of Object.entries(updates)) {
50
+ if (value !== undefined && !seen.has(key))
51
+ output.push(`${key}=${encodeEnvValue(String(value))}`);
52
+ }
53
+ return `${output.join("\n").replace(/\n+$/gu, "")}\n`;
54
+ }
@@ -0,0 +1,5 @@
1
+ /** Apply the packaged main and log migrations to the configured Node databases. */
2
+ export declare function migrateNode(
3
+ environment?: Record<string, string | undefined>,
4
+ options?: { migrationsDirectory?: string },
5
+ ): Promise<void>
@@ -0,0 +1,56 @@
1
+ import { createClient } from '@libsql/client/web'
2
+ import { migrateLibsql } from '../server/db/migrate-libsql'
3
+ import { remoteDatabaseConfig } from '../server/db/remote-config'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { join } from 'node:path'
6
+
7
+ import { migrateSqliteFile } from '../server/db/migrate-sqlite'
8
+ import { assertSeparateSqliteFiles } from '../server/db/sqlite-files'
9
+
10
+ export async function migrateNode(
11
+ environment: Record<string, string | undefined> = process.env,
12
+ options: { migrationsDirectory?: string } = {},
13
+ ) {
14
+ const migrationsDirectory =
15
+ options.migrationsDirectory ??
16
+ fileURLToPath(new URL('../../src/server/db', import.meta.url))
17
+ const remote = remoteDatabaseConfig(environment)
18
+ if (remote) {
19
+ for (const [database, directory] of [
20
+ [remote.main, 'migrations-sqlite'],
21
+ [remote.logs, 'migrations-logs'],
22
+ ] as const) {
23
+ const client = createClient(database)
24
+ try {
25
+ await migrateLibsql(client, join(migrationsDirectory, directory))
26
+ } finally {
27
+ client.close()
28
+ }
29
+ }
30
+ console.log('Remote libSQL database migrations applied.')
31
+ } else {
32
+ const path = environment.DEVPUSH_DATABASE_PATH
33
+ const logPath = environment.DEVPUSH_LOG_DATABASE_PATH
34
+ if (!path && environment.NODE_ENV === 'production') {
35
+ throw new Error('DEVPUSH_DATABASE_PATH is required in production.')
36
+ }
37
+ if (!logPath && environment.NODE_ENV === 'production') {
38
+ throw new Error('DEVPUSH_LOG_DATABASE_PATH is required in production.')
39
+ }
40
+
41
+ assertSeparateSqliteFiles(
42
+ path ?? '.data/devpush.sqlite',
43
+ logPath ?? '.data/logs.sqlite',
44
+ )
45
+
46
+ migrateSqliteFile(
47
+ path ?? '.data/devpush.sqlite',
48
+ join(migrationsDirectory, 'migrations-sqlite'),
49
+ )
50
+ migrateSqliteFile(
51
+ logPath ?? '.data/logs.sqlite',
52
+ join(migrationsDirectory, 'migrations-logs'),
53
+ )
54
+ console.log('SQLite database migrations applied.')
55
+ }
56
+ }