diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a27c7da5c5..c0374a4230 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1246,7 +1246,7 @@ importers: version: 0.31.9 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@25.5.0) + version: 29.7.0 typescript: specifier: 'catalog:' version: 5.9.3 @@ -1615,6 +1615,9 @@ importers: '@sentry/cloudflare': specifier: ^10.43.0 version: 10.43.0(@cloudflare/workers-types@4.20260430.1) + drizzle-orm: + specifier: ^0.45.2 + version: 0.45.2(@cloudflare/workers-types@4.20260430.1)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(bun-types@1.3.13)(pg@8.20.0) hono: specifier: ^4.12.18 version: 4.12.18 @@ -1646,6 +1649,9 @@ importers: '@typescript/native-preview': specifier: 'catalog:' version: 7.0.0-dev.20260319.1 + drizzle-kit: + specifier: 'catalog:' + version: 0.31.9 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@24.12.0) @@ -1691,7 +1697,7 @@ importers: version: 7.0.0-dev.20260319.1 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@24.12.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + version: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) typescript: specifier: 'catalog:' version: 5.9.3 @@ -8328,6 +8334,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} @@ -17030,7 +17037,7 @@ snapshots: '@storybook/csf': 0.1.13 '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/server-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@rspack/core' @@ -17054,9 +17061,9 @@ snapshots: '@chromaui/rrweb-snapshot': 2.0.0-alpha.18-noAbsolute '@playwright/test': 1.58.2 '@segment/analytics-node': 2.1.3 - '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) '@storybook/csf': 0.1.13 - '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) '@storybook/server-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))(typescript@5.9.3) storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 @@ -21985,7 +21992,7 @@ snapshots: '@stitches/core@1.2.8': {} - '@storybook/addon-actions@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/addon-actions@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: '@storybook/global': 5.0.0 '@types/uuid': 9.0.8 @@ -21993,20 +22000,60 @@ snapshots: polished: 4.3.1 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) uuid: 9.0.1 + optional: true + + '@storybook/addon-actions@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + uuid: 9.0.1 + + '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + optional: true '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 memoizerific: 1.11.3 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ts-dedent: 2.2.0 + + '@storybook/addon-controls@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 + optional: true '@storybook/addon-controls@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 dequal: 2.0.3 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ts-dedent: 2.2.0 + + '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) + '@storybook/blocks': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/csf-plugin': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + optional: true '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: @@ -22016,7 +22063,7 @@ snapshots: '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' @@ -22034,6 +22081,23 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/addon-actions': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-backgrounds': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-controls': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-docs': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-highlight': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-measure': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-outline': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/addon-viewport': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + optional: true + '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/addon-actions': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) @@ -22045,15 +22109,21 @@ snapshots: '@storybook/addon-outline': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/addon-viewport': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-highlight@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/addon-highlight@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: '@storybook/global': 5.0.0 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + + '@storybook/addon-highlight@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@storybook/addon-links@9.1.20(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: @@ -22062,37 +22132,73 @@ snapshots: optionalDependencies: react: 19.2.4 - '@storybook/addon-measure@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/addon-measure@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: '@storybook/global': 5.0.0 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) tiny-invariant: 1.3.3 + optional: true - '@storybook/addon-outline@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/addon-measure@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + tiny-invariant: 1.3.3 + + '@storybook/addon-outline@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: '@storybook/global': 5.0.0 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 + optional: true + + '@storybook/addon-outline@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ts-dedent: 2.2.0 '@storybook/addon-themes@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 + '@storybook/addon-toolbars@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + '@storybook/addon-toolbars@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + '@storybook/addon-viewport@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + memoizerific: 1.11.3 storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true '@storybook/addon-viewport@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: memoizerific: 1.11.3 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/csf': 0.1.12 + '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optional: true '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/csf': 0.1.12 '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 optionalDependencies: react: 19.2.4 @@ -22114,7 +22220,7 @@ snapshots: path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.4 - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) style-loader: 3.3.4(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4)) terser-webpack-plugin: 5.4.0(@swc/core@1.15.18)(esbuild@0.27.4)(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4)) ts-dedent: 2.2.0 @@ -22136,7 +22242,7 @@ snapshots: '@storybook/builder-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))(typescript@5.9.3)': dependencies: - '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) '@types/semver': 7.7.1 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 @@ -22198,13 +22304,24 @@ snapshots: - uglify-js - webpack-cli + '@storybook/components@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + '@storybook/components@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + '@storybook/core-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + optional: true '@storybook/core-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 '@storybook/core-webpack@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': @@ -22212,10 +22329,16 @@ snapshots: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) ts-dedent: 2.2.0 - '@storybook/csf-plugin@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/csf-plugin@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) unplugin: 1.16.1 + optional: true + + '@storybook/csf-plugin@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) + unplugin: 1.16.1 '@storybook/csf-plugin@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: @@ -22237,9 +22360,14 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/manager-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/manager-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + + '@storybook/manager-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@storybook/nextjs@9.1.20(patch_hash=e1857649664eed8f87877c352d277c90d4af5a58d0ad931105f033c8c08165c1)(esbuild@0.27.4)(next@16.2.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4))': dependencies: @@ -22325,19 +22453,35 @@ snapshots: - uglify-js - webpack-cli + '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/global': 5.0.0 + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + safe-identifier: 0.4.2 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + yaml-loader: 0.8.1 + optional: true + '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/global': 5.0.0 '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) safe-identifier: 0.4.2 - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 yaml-loader: 0.8.1 - '@storybook/preview-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/preview-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + + '@storybook/preview-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.4))': dependencies: @@ -22353,11 +22497,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + + '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@storybook/react-dom-shim@9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: @@ -22380,7 +22531,7 @@ snapshots: '@storybook/builder-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3) '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -22392,8 +22543,8 @@ snapshots: '@storybook/server-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))(typescript@5.9.3)': dependencies: '@storybook/builder-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))(typescript@5.9.3) - '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) transitivePeerDependencies: - '@rspack/core' @@ -22404,6 +22555,19 @@ snapshots: - webpack-cli optional: true + '@storybook/server@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': + dependencies: + '@storybook/components': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/csf': 0.1.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/preview-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + '@storybook/theming': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4))) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + ts-dedent: 2.2.0 + yaml: 2.8.4 + optional: true + '@storybook/server@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/components': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) @@ -22412,7 +22576,7 @@ snapshots: '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/preview-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/theming': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 yaml: 2.8.4 @@ -22446,9 +22610,14 @@ snapshots: - supports-color - ts-node - '@storybook/theming@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@storybook/theming@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)))': dependencies: storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + optional: true + + '@storybook/theming@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@streamparser/json@0.0.22': {} @@ -26595,6 +26764,25 @@ snapshots: - babel-plugin-macros - supports-color + jest-cli@29.7.0: + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@24.12.0) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@24.12.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@29.7.0(@types/node@24.12.0): dependencies: '@jest/core': 29.7.0 @@ -26652,6 +26840,25 @@ snapshots: - supports-color - ts-node + jest-cli@30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)): + dependencies: + '@jest/core': 30.3.0(esbuild-register@3.6.0(esbuild@0.27.4)) + '@jest/test-result': 30.3.0 + '@jest/types': 30.3.0 + chalk: 4.1.2 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + jest-util: 30.3.0 + jest-validate: 30.3.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jest-config@29.7.0(@types/node@24.12.0): dependencies: '@babel/core': 7.29.0 @@ -27266,6 +27473,18 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 + jest@29.7.0: + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@24.12.0): dependencies: '@jest/core': 29.7.0 @@ -27303,6 +27522,19 @@ snapshots: - supports-color - ts-node + jest@30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)): + dependencies: + '@jest/core': 30.3.0(esbuild-register@3.6.0(esbuild@0.27.4)) + '@jest/types': 30.3.0 + import-local: 3.2.0 + jest-cli: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jimp-compact@0.16.1: {} jiti@2.6.1: {} @@ -30537,6 +30769,28 @@ snapshots: stoppable@1.1.0: {} + storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@storybook/global': 5.0.0 + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@8.0.10(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)) + '@vitest/spy': 3.2.4 + better-opn: 3.0.2 + esbuild: 0.27.4 + esbuild-register: 3.6.0(esbuild@0.27.4) + recast: 0.23.11 + semver: 7.7.4 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - '@testing-library/dom' + - bufferutil + - msw + - supports-color + - utf-8-validate + - vite + storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.10(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4)): dependencies: '@storybook/global': 5.0.0 diff --git a/services/deploy-infra/builder/drizzle.config.ts b/services/deploy-infra/builder/drizzle.config.ts new file mode 100644 index 0000000000..27cf9ffb72 --- /dev/null +++ b/services/deploy-infra/builder/drizzle.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + out: './drizzle', + schema: './src/db/sqlite-schema.ts', + dialect: 'sqlite', + driver: 'durable-sqlite', +}); diff --git a/services/deploy-infra/builder/drizzle/0000_html_deployments.sql b/services/deploy-infra/builder/drizzle/0000_html_deployments.sql new file mode 100644 index 0000000000..e8e366a630 --- /dev/null +++ b/services/deploy-infra/builder/drizzle/0000_html_deployments.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS `html_deployments` ( + `slug` text PRIMARY KEY NOT NULL, + `expires_at` integer NOT NULL +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `idx_html_dep_expires_at` ON `html_deployments` (`expires_at`); diff --git a/services/deploy-infra/builder/drizzle/meta/0000_snapshot.json b/services/deploy-infra/builder/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000000..71ef41cae3 --- /dev/null +++ b/services/deploy-infra/builder/drizzle/meta/0000_snapshot.json @@ -0,0 +1,48 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "3f2a1b4c-8e7d-4c9a-b5f0-1d2e3c4a5b6f", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "html_deployments": { + "name": "html_deployments", + "columns": { + "slug": { + "name": "slug", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_html_dep_expires_at": { + "name": "idx_html_dep_expires_at", + "columns": ["expires_at"], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} diff --git a/services/deploy-infra/builder/drizzle/meta/_journal.json b/services/deploy-infra/builder/drizzle/meta/_journal.json new file mode 100644 index 0000000000..cbf8aa7a59 --- /dev/null +++ b/services/deploy-infra/builder/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "sqlite", + "entries": [ + { + "idx": 0, + "version": "6", + "when": 1747076668000, + "tag": "0000_html_deployments", + "breakpoints": true + } + ] +} diff --git a/services/deploy-infra/builder/drizzle/migrations.ts b/services/deploy-infra/builder/drizzle/migrations.ts new file mode 100644 index 0000000000..6c1e08d098 --- /dev/null +++ b/services/deploy-infra/builder/drizzle/migrations.ts @@ -0,0 +1,28 @@ +// Auto-generated migration barrel — do not hand-edit. +// Regenerate with: pnpm drizzle-kit generate (from the builder directory) + +const m0000 = ` +CREATE TABLE IF NOT EXISTS \`html_deployments\` ( +\t\`slug\` text PRIMARY KEY NOT NULL, +\t\`expires_at\` integer NOT NULL +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS \`idx_html_dep_expires_at\` ON \`html_deployments\` (\`expires_at\`); +`; + +export default { + journal: { + version: '7', + dialect: 'sqlite', + entries: [ + { + idx: 0, + version: '6', + when: 1747076668000, + tag: '0000_html_deployments', + breakpoints: true, + }, + ], + }, + migrations: { m0000 }, +}; diff --git a/services/deploy-infra/builder/package.json b/services/deploy-infra/builder/package.json index eae7383336..374193c1ed 100644 --- a/services/deploy-infra/builder/package.json +++ b/services/deploy-infra/builder/package.json @@ -19,6 +19,7 @@ "dependencies": { "@kilocode/encryption": "workspace:*", "@kilocode/worker-utils": "workspace:*", + "drizzle-orm": "catalog:", "zod": "catalog:", "@sentry/cloudflare": "^10.43.0", "hono": "catalog:", @@ -32,6 +33,7 @@ "@types/node": ">=24 <25", "@types/tar-stream": "^3.1.4", "@typescript/native-preview": "catalog:", + "drizzle-kit": "catalog:", "jest": "^29.7.0", "ts-jest": "^29.4.6", "tsx": "^4.21.0", diff --git a/services/deploy-infra/builder/src/db/sqlite-schema.ts b/services/deploy-infra/builder/src/db/sqlite-schema.ts new file mode 100644 index 0000000000..e168600097 --- /dev/null +++ b/services/deploy-infra/builder/src/db/sqlite-schema.ts @@ -0,0 +1,10 @@ +import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core'; + +export const htmlDeployments = sqliteTable( + 'html_deployments', + { + slug: text('slug').primaryKey(), + expiresAt: integer('expires_at').notNull(), + }, + table => [index('idx_html_dep_expires_at').on(table.expiresAt)] +); diff --git a/services/deploy-infra/builder/src/html-deploy/handler.ts b/services/deploy-infra/builder/src/html-deploy/handler.ts new file mode 100644 index 0000000000..6faa25bdb0 --- /dev/null +++ b/services/deploy-infra/builder/src/html-deploy/handler.ts @@ -0,0 +1,122 @@ +import type { Context } from 'hono'; +import type { HonoEnv, HtmlDeployResponse, DeploymentArtifacts } from '../types'; +import { verifyKiloBearerAgainstCurrentPepper } from '@kilocode/worker-utils/kilo-token-auth'; +import { CloudflareAPI } from '../cloudflare-api'; +import { Deployer } from '../deployer'; +import { validateStaticAssets, parseMultipartFiles, parseTtlHeader } from './validator'; +import { generateDeploymentSlug } from './slug'; +import * as Sentry from '@sentry/cloudflare'; +import staticWorkerContent from '../assets/static.worker.js'; + +const MAX_TOTAL_BYTES = 10 * 1024 * 1024; // 10 MB +const DEFAULT_HOSTNAME_BASE = 'd.kiloapps.io'; +const DEFAULT_TTL_SECONDS = 24 * 60 * 60; // 24 hours +const MAX_TTL_SECONDS = 7 * 24 * 60 * 60; // 7 days + +export async function htmlDeployHandler(c: Context): Promise { + const authHeader = c.req.header('Authorization'); + const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null; + + const authResult = await verifyKiloBearerAgainstCurrentPepper({ + token, + nextAuthSecret: c.env.NEXTAUTH_SECRET, + workerEnv: c.env.WORKER_ENV, + connectionString: c.env.HYPERDRIVE.connectionString, + }); + + if (!authResult) { + return c.json({ error: 'Invalid or expired token' }, 401); + } + + const contentType = c.req.header('Content-Type') ?? ''; + let assets; + + if (contentType.includes('multipart/form-data')) { + try { + assets = await parseMultipartFiles(c); + } catch (err) { + const msg = err instanceof Error ? err.message : 'Failed to parse multipart body'; + return c.json({ error: msg }, 400); + } + } else { + const html = await c.req.text(); + if (!html || html.length === 0) { + return c.json({ error: 'Empty body' }, 400); + } + if (html.length > MAX_TOTAL_BYTES) { + return c.json({ error: `Body exceeds the ${MAX_TOTAL_BYTES / (1024 * 1024)} MB limit` }, 400); + } + assets = [{ path: 'index.html', content: Buffer.from(html, 'utf-8'), mimeType: 'text/html' }]; + } + + if (assets.length === 0) { + return c.json({ error: 'No files provided' }, 400); + } + + const validationError = validateStaticAssets(assets); + if (validationError) { + return c.json({ error: validationError }, 400); + } + + const slug = generateDeploymentSlug(null); + const hostnameBase = c.env.DEPLOY_HOSTNAME_BASE || DEFAULT_HOSTNAME_BASE; + const ttlSeconds = parseTtlHeader(c.req.header('X-Expires-In') ?? null, { + defaultTtl: DEFAULT_TTL_SECONDS, + maxTtl: MAX_TTL_SECONDS, + }); + const expiresAt = Date.now() + ttlSeconds * 1000; + + const artifacts: DeploymentArtifacts = { + workerScript: { + path: 'index.js', + content: Buffer.from(staticWorkerContent, 'utf-8'), + mimeType: 'application/javascript+module', + }, + artifacts: [], + assets, + }; + + const cloudflareApi = new CloudflareAPI(c.env.CLOUDFLARE_ACCOUNT_ID, c.env.CLOUDFLARE_API_TOKEN); + const deployer = new Deployer(cloudflareApi); + + try { + await deployer.deploy({ + artifacts, + workerName: slug, + logger: (msg: string) => console.log(`[deploy-html ${slug}] ${msg}`), + }); + } catch (error) { + Sentry.captureException(error, { + extra: { slug, path: '/deploy-html', method: 'POST' }, + }); + const msg = error instanceof Error ? error.message : 'Unknown deployment error'; + return c.json({ error: `Deployment failed: ${msg}` }, 500); + } + + const registryId = c.env.HtmlDeployRegistry.idFromName('singleton'); + const registry = c.env.HtmlDeployRegistry.get(registryId); + + try { + await registry.register(slug, expiresAt); + } catch (registryError) { + Sentry.captureException(registryError, { + extra: { slug, action: 'html-deploy-registry-write' }, + }); + try { + await cloudflareApi.deleteWorker(slug, 'kilo-deploy'); + } catch (rollbackError) { + Sentry.captureException(rollbackError, { + extra: { slug, action: 'html-deploy-rollback' }, + }); + } + return c.json({ error: 'Failed to record deployment — site rolled back' }, 500); + } + + const response: HtmlDeployResponse = { + slug, + url: `https://${slug}.${hostnameBase}`, + expires_at: new Date(expiresAt).toISOString(), + }; + + return c.json(response, 200); +} diff --git a/services/deploy-infra/builder/src/html-deploy/registry.ts b/services/deploy-infra/builder/src/html-deploy/registry.ts new file mode 100644 index 0000000000..0cb036ea9a --- /dev/null +++ b/services/deploy-infra/builder/src/html-deploy/registry.ts @@ -0,0 +1,97 @@ +/** + * HtmlDeployRegistry — singleton Durable Object that tracks ephemeral HTML deployments. + * + * Replaces the KV-based tracking approach with a SQLite-backed registry that: + * - Stores deployment records with their expiry timestamp + * - Uses DO alarms to trigger cleanup exactly when the next deployment expires + * - Exposes an RPC method so the hourly cron can trigger cleanup as a safety net + */ + +import { DurableObject } from 'cloudflare:workers'; +import { drizzle } from 'drizzle-orm/durable-sqlite'; +import type { DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite'; +import { migrate } from 'drizzle-orm/durable-sqlite/migrator'; +import { eq, lte, asc } from 'drizzle-orm'; +import migrations from '../../drizzle/migrations'; +import { htmlDeployments } from '../db/sqlite-schema'; +import type { Env } from '../types'; +import { CloudflareAPI } from '../cloudflare-api'; +import * as Sentry from '@sentry/cloudflare'; + +const DISPATCH_NAMESPACE = 'kilo-deploy'; + +export class HtmlDeployRegistry extends DurableObject { + private db: DrizzleSqliteDODatabase; + + constructor(ctx: DurableObjectState, env: Env) { + super(ctx, env); + this.db = drizzle(ctx.storage, { logger: false }); + void ctx.blockConcurrencyWhile(() => migrate(this.db, migrations)); + } + + /** Record a new deployment and arm (or advance) the cleanup alarm. */ + async register(slug: string, expiresAt: number): Promise { + await this.db.insert(htmlDeployments).values({ slug, expiresAt }); + + const currentAlarm = await this.ctx.storage.getAlarm(); + if (currentAlarm === null || expiresAt < currentAlarm) { + await this.ctx.storage.setAlarm(expiresAt); + } + } + + /** Remove a single deployment record (e.g. on manual delete). */ + async deleteDeployment(slug: string): Promise { + await this.db.delete(htmlDeployments).where(eq(htmlDeployments.slug, slug)); + } + + /** + * Delete all expired deployments. + * Called by the alarm and also exposed as an RPC for the hourly cron safety net. + */ + async triggerCleanup(): Promise { + await this.cleanupExpiredAt(Date.now()); + } + + async alarm(): Promise { + await this.cleanupExpiredAt(Date.now()); + + // Re-arm for the next soonest expiry, if any remain. + const [next] = await this.db + .select({ expiresAt: htmlDeployments.expiresAt }) + .from(htmlDeployments) + .orderBy(asc(htmlDeployments.expiresAt)) + .limit(1); + + if (next) { + await this.ctx.storage.setAlarm(next.expiresAt); + } + } + + private async cleanupExpiredAt(now: number): Promise { + const expired = await this.db + .select({ slug: htmlDeployments.slug }) + .from(htmlDeployments) + .where(lte(htmlDeployments.expiresAt, now)); + + if (expired.length === 0) return; + + const cloudflareApi = new CloudflareAPI( + this.env.CLOUDFLARE_ACCOUNT_ID, + this.env.CLOUDFLARE_API_TOKEN + ); + + for (const { slug } of expired) { + try { + await cloudflareApi.deleteWorker(slug, DISPATCH_NAMESPACE); + console.log(`[html-deploy-registry] Deleted expired deployment: ${slug}`); + } catch (error) { + Sentry.captureException(error, { extra: { slug, action: 'html-deploy-cleanup' } }); + console.error( + `[html-deploy-registry] Failed to delete worker ${slug}: ${error instanceof Error ? error.message : String(error)}` + ); + } + // Always remove from registry, even if CF delete fails, to avoid retrying broken workers forever. + await this.db.delete(htmlDeployments).where(eq(htmlDeployments.slug, slug)); + } + } +} diff --git a/services/deploy-infra/builder/src/html-deploy/slug.ts b/services/deploy-infra/builder/src/html-deploy/slug.ts new file mode 100644 index 0000000000..90b7c4a6a3 --- /dev/null +++ b/services/deploy-infra/builder/src/html-deploy/slug.ts @@ -0,0 +1 @@ +export { generateDeploymentSlug } from '../../../../../apps/web/src/lib/user-deployments/slug-generator'; diff --git a/services/deploy-infra/builder/src/html-deploy/validator.ts b/services/deploy-infra/builder/src/html-deploy/validator.ts new file mode 100644 index 0000000000..3a6b19844a --- /dev/null +++ b/services/deploy-infra/builder/src/html-deploy/validator.ts @@ -0,0 +1,122 @@ +import type { Context } from 'hono'; +import type { HonoEnv } from '../types'; +import type { DeploymentFile } from '../types'; +import { getMimeType } from '../utils'; + +const MAX_TOTAL_BYTES = 10 * 1024 * 1024; // 10 MB across all files + +// Allowlist of permitted static file extensions. +// Any file whose extension is not in this set is rejected. +const ALLOWED_EXTENSIONS = new Set([ + // markup + 'html', + 'htm', + 'xhtml', + // styles + 'css', + // scripts (compiled/bundled — no server-side execution) + 'js', + 'mjs', + 'cjs', + // data / config + 'json', + 'xml', + 'yaml', + 'yml', + 'toml', + 'csv', + 'txt', + 'md', + 'markdown', + // images + 'jpg', + 'jpeg', + 'png', + 'gif', + 'svg', + 'webp', + 'avif', + 'ico', + 'bmp', + 'tiff', + 'tif', + // fonts + 'woff', + 'woff2', + 'ttf', + 'otf', + 'eot', + // video / audio + 'mp4', + 'webm', + 'mp3', + 'wav', + 'ogg', + 'oga', + 'ogv', + // wasm + 'wasm', + // source maps + 'map', + // other + 'pdf', +]); + +export function validateStaticAssets(assets: DeploymentFile[]): string | null { + const hasIndexHtml = assets.some(a => a.path === 'index.html' || a.path.endsWith('/index.html')); + if (!hasIndexHtml) { + return 'index.html is required'; + } + + for (const file of assets) { + const ext = file.path.split('.').pop()?.toLowerCase(); + if (ext && !ALLOWED_EXTENSIONS.has(ext)) { + return `File "${file.path}" has a disallowed extension (.${ext}) — only static files are allowed`; + } + } + + return null; +} + +export async function parseMultipartFiles(c: Context): Promise { + const formData = await c.req.formData(); + const files: DeploymentFile[] = []; + let totalBytes = 0; + + for (const [key, value] of formData.entries()) { + if (!(value instanceof File)) continue; + + const normalizedPath = key.replace(/\\/g, '/'); + if (normalizedPath.includes('..') || normalizedPath.startsWith('/')) { + throw new Error(`Invalid file path: ${key}`); + } + if (normalizedPath.split('/').some(segment => segment.startsWith('.'))) { + throw new Error(`Hidden files are not allowed: "${key}"`); + } + + const buffer = Buffer.from(await value.arrayBuffer()); + + totalBytes += buffer.byteLength; + if (totalBytes > MAX_TOTAL_BYTES) { + throw new Error(`Total size exceeds the ${MAX_TOTAL_BYTES / (1024 * 1024)} MB limit`); + } + + files.push({ + path: normalizedPath, + content: buffer, + mimeType: getMimeType(normalizedPath), + }); + } + + return files; +} + +export function parseTtlHeader( + header: string | null, + defaults: { defaultTtl: number; maxTtl: number } +): number { + if (!header) return defaults.defaultTtl; + const seconds = parseInt(header, 10); + if (isNaN(seconds) || seconds <= 0) return defaults.defaultTtl; + return Math.min(seconds, defaults.maxTtl); +} diff --git a/services/deploy-infra/builder/src/index.ts b/services/deploy-infra/builder/src/index.ts index 440902b5dc..f8bc2f8320 100644 --- a/services/deploy-infra/builder/src/index.ts +++ b/services/deploy-infra/builder/src/index.ts @@ -1,5 +1,5 @@ import { Hono, type Context } from 'hono'; -import type { Env, DeployRequest, DeployResponse, StatusResponse } from './types'; +import type { Env, HonoEnv, DeployRequest, DeployResponse, StatusResponse } from './types'; import { backendAuthMiddleware, createErrorHandler, @@ -12,6 +12,8 @@ import * as Sentry from '@sentry/cloudflare'; // Import base Durable Objects import { DeploymentOrchestrator as DeploymentOrchestratorBase } from './deployment-orchestrator'; import { EventsManager as EventsManagerBase } from './events-manager'; +import { HtmlDeployRegistry as HtmlDeployRegistryBase } from './html-deploy/registry'; +import { htmlDeployHandler } from './html-deploy/handler'; export { Sandbox } from '@cloudflare/sandbox'; // Export Sentry-instrumented Durable Objects @@ -35,14 +37,29 @@ export const EventsManager = Sentry.instrumentDurableObjectWithSentry( EventsManagerBase ); +export const HtmlDeployRegistry = Sentry.instrumentDurableObjectWithSentry( + (env: Env) => ({ + dsn: env.SENTRY_DSN, + release: env.CF_VERSION_METADATA.id, + sendDefaultPii: true, + environment: env.ENVIRONMENT || 'production', + }), + HtmlDeployRegistryBase +); + function createDurableObjectBuilderID() { return crypto.randomUUID(); } // Create Hono app with Env type -type HonoEnv = { Bindings: Env }; const app = new Hono(); +// ── /deploy-html — Kilo JWT auth, no sandbox, synchronous ───────────────── + +app.post('/deploy-html', htmlDeployHandler); + +// ── Backend-authenticated routes ─────────────────────────────────────────── + // Authentication middleware app.use( '*', @@ -293,7 +310,7 @@ app.onError((err, c) => { // 404 handler app.notFound(createNotFoundHandler()); -export default Sentry.withSentry((env: Env) => { +const fetchHandler = Sentry.withSentry((env: Env) => { const { id: versionId } = env.CF_VERSION_METADATA; return { @@ -303,3 +320,20 @@ export default Sentry.withSentry((env: Env) => { environment: env.ENVIRONMENT || 'production', }; }, app); + +export default { + fetch: fetchHandler, + + // ── Scheduled handler: hourly safety-net cleanup ──────────────────────── + // The HtmlDeployRegistry DO handles cleanup via alarms at exact expiry times. + // This cron is a fallback in case an alarm is missed. + async scheduled( + _controller: ScheduledController, + env: Env, + ctx: ExecutionContext + ): Promise { + const id = env.HtmlDeployRegistry.idFromName('singleton'); + const registry = env.HtmlDeployRegistry.get(id); + ctx.waitUntil(registry.triggerCleanup()); + }, +}; diff --git a/services/deploy-infra/builder/src/types.ts b/services/deploy-infra/builder/src/types.ts index 2b912ddb21..db51b86bd9 100644 --- a/services/deploy-infra/builder/src/types.ts +++ b/services/deploy-infra/builder/src/types.ts @@ -6,6 +6,7 @@ import { z } from 'zod'; import type { Sandbox } from '@cloudflare/sandbox'; import type { DeploymentOrchestrator } from './deployment-orchestrator'; import type { EventsManager } from './events-manager'; +import type { HtmlDeployRegistry } from './html-deploy/registry'; // Import and re-export shared types from backend import type { @@ -189,8 +190,19 @@ export type Env = { Sandbox: DurableObjectNamespace; DeploymentOrchestrator: DurableObjectNamespace; EventsManager: DurableObjectNamespace; + + NEXTAUTH_SECRET: SecretsStoreSecret; + HYPERDRIVE: Hyperdrive; + WORKER_ENV: string; + DEPLOY_HOSTNAME_BASE: string; + + /** Singleton DO registry tracking ephemeral HTML deployments for alarm-driven cleanup */ + HtmlDeployRegistry: DurableObjectNamespace; }; +/** Hono app environment with Worker bindings. */ +export type HonoEnv = { Bindings: Env }; + /** * Request body for POST /deploy */ @@ -235,3 +247,14 @@ export type CloudflareApiResponse = { result?: T; errors?: Array<{ code: number; message: string }>; }; + +export type HtmlDeployResponse = { + slug: string; + url: string; + expires_at: string; +}; + +export type HtmlDeployRecord = { + slug: string; + expiresAt: number; +}; diff --git a/services/deploy-infra/builder/tsconfig.json b/services/deploy-infra/builder/tsconfig.json index e69eb4fc2e..6725871805 100644 --- a/services/deploy-infra/builder/tsconfig.json +++ b/services/deploy-infra/builder/tsconfig.json @@ -11,5 +11,5 @@ "skipLibCheck": true, "noEmit": true }, - "include": ["src/**/*.ts", "scripts/**/*.ts"] + "include": ["src/**/*.ts", "scripts/**/*.ts", "drizzle/**/*.ts"] } diff --git a/services/deploy-infra/builder/wrangler.jsonc b/services/deploy-infra/builder/wrangler.jsonc index 4110b4669b..04c3872814 100644 --- a/services/deploy-infra/builder/wrangler.jsonc +++ b/services/deploy-infra/builder/wrangler.jsonc @@ -18,7 +18,7 @@ "rules": [ { "type": "Text", - "globs": ["**/*.worker.js"], + "globs": ["**/*.worker.js", "**/*.sql"], "fallthrough": true, }, ], @@ -34,6 +34,25 @@ "BACKEND_EVENTS_URL": "https://app.kilo.ai/api/user-deployments/webhook", "SENTRY_DSN": "https://1f07992a2811f3e5fc4d578527ab3d64@o4509356317474816.ingest.us.sentry.io/4510379756945409", "ENVIRONMENT": "production", + "WORKER_ENV": "production", + "DEPLOY_HOSTNAME_BASE": "d.kiloapps.io", + }, + "secrets_store_secrets": [ + { + "binding": "NEXTAUTH_SECRET", + "store_id": "342a86d9e3a94da698e82d0c6e2a36f0", + "secret_name": "NEXTAUTH_SECRET_PROD", + }, + ], + "hyperdrive": [ + { + "binding": "HYPERDRIVE", + "id": "624ec80650dd414199349f4e217ddb10", + "localConnectionString": "postgres://postgres:postgres@localhost:5432/postgres", + }, + ], + "triggers": { + "crons": ["0 * * * *"], }, "containers": [ { @@ -57,6 +76,10 @@ "class_name": "Sandbox", "name": "Sandbox", }, + { + "name": "HtmlDeployRegistry", + "class_name": "HtmlDeployRegistry", + }, ], }, "migrations": [ @@ -64,5 +87,9 @@ "tag": "v1", "new_sqlite_classes": ["Sandbox", "DeploymentOrchestrator", "EventsManager"], }, + { + "tag": "v2", + "new_sqlite_classes": ["HtmlDeployRegistry"], + }, ], }