mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat(cli): add alchemy and improve cli tooling and structure (#520)
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
"!bts.jsonc",
|
||||
"!**/.expo",
|
||||
"!**/.wrangler",
|
||||
"!**/.alchemy",
|
||||
"!**/wrangler.jsonc",
|
||||
"!**/.source"
|
||||
]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["-y", "@upstash/context7-mcp"]
|
||||
}{{#if (or (eq runtime "workers") (eq webDeploy "workers"))}},
|
||||
}{{#if (or (eq runtime "workers") (eq webDeploy "wrangler"))}},
|
||||
"cloudflare": {
|
||||
"command": "npx",
|
||||
"args": ["mcp-remote", "https://docs.mcp.cloudflare.com/sse"]
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"!bts.jsonc",
|
||||
"!**/.expo",
|
||||
"!**/.wrangler",
|
||||
"!**/.alchemy",
|
||||
"!**/wrangler.jsonc",
|
||||
"!**/.source"
|
||||
]
|
||||
|
||||
@@ -21,6 +21,13 @@ export const auth = betterAuth({
|
||||
],
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
advanced: {
|
||||
defaultCookieAttributes: {
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
},
|
||||
}
|
||||
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
|
||||
, plugins: [expo()]
|
||||
@@ -54,8 +61,13 @@ export const auth = betterAuth({
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
secret: process.env.BETTER_AUTH_SECRET,
|
||||
baseURL: process.env.BETTER_AUTH_URL,
|
||||
advanced: {
|
||||
defaultCookieAttributes: {
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
},
|
||||
},
|
||||
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
|
||||
plugins: [expo()],
|
||||
{{/if}}
|
||||
@@ -73,7 +85,7 @@ import * as schema from "../db/schema/auth";
|
||||
import { env } from "cloudflare:workers";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
database: drizzleAdapter(db, {
|
||||
{{#if (eq database "postgres")}}provider: "pg",{{/if}}
|
||||
{{#if (eq database "sqlite")}}provider: "sqlite",{{/if}}
|
||||
{{#if (eq database "mysql")}}provider: "mysql",{{/if}}
|
||||
@@ -85,6 +97,13 @@ export const auth = betterAuth({
|
||||
},
|
||||
secret: env.BETTER_AUTH_SECRET,
|
||||
baseURL: env.BETTER_AUTH_URL,
|
||||
advanced: {
|
||||
defaultCookieAttributes: {
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
},
|
||||
},
|
||||
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
|
||||
plugins: [expo()],
|
||||
{{/if}}
|
||||
@@ -110,6 +129,13 @@ export const auth = betterAuth({
|
||||
],
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
advanced: {
|
||||
defaultCookieAttributes: {
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
},
|
||||
}
|
||||
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
|
||||
, plugins: [expo()]
|
||||
@@ -133,9 +159,16 @@ export const auth = betterAuth({
|
||||
],
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
advanced: {
|
||||
defaultCookieAttributes: {
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
},
|
||||
}
|
||||
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
|
||||
, plugins: [expo()]
|
||||
{{/if}}
|
||||
});
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -16,6 +16,7 @@ dist/
|
||||
.idea/usage.statistics.xml
|
||||
.idea/shelf
|
||||
.wrangler
|
||||
.alchemy
|
||||
/.next/
|
||||
.vercel
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{{else if (eq runtime "bun")}}
|
||||
"bun"
|
||||
{{else if (eq runtime "workers")}}
|
||||
"./worker-configuration",
|
||||
"@cloudflare/workers-types",
|
||||
"node"
|
||||
{{else}}
|
||||
"node",
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
node_modules
|
||||
.turbo
|
||||
.alchemy
|
||||
.env
|
||||
@@ -7,11 +7,13 @@ export default defineConfig({
|
||||
// DOCS: https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit
|
||||
dialect: "sqlite",
|
||||
driver: "d1-http",
|
||||
{{#if (eq serverDeploy "wrangler")}}
|
||||
dbCredentials: {
|
||||
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
|
||||
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
|
||||
token: process.env.CLOUDFLARE_D1_TOKEN!,
|
||||
},
|
||||
{{/if}}
|
||||
{{else}}
|
||||
dialect: "turso",
|
||||
dbCredentials: {
|
||||
|
||||
208
apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
Normal file
208
apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
Normal file
@@ -0,0 +1,208 @@
|
||||
import alchemy from "alchemy";
|
||||
{{#if (eq webDeploy "alchemy")}}
|
||||
{{#if (includes frontend "next")}}
|
||||
import { Next } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "nuxt")}}
|
||||
import { Nuxt } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "svelte")}}
|
||||
import { SvelteKit } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "tanstack-start")}}
|
||||
import { TanStackStart } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "tanstack-router")}}
|
||||
import { Vite } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "react-router")}}
|
||||
import { ReactRouter } from "alchemy/cloudflare";
|
||||
{{else if (includes frontend "solid")}}
|
||||
import { Vite } from "alchemy/cloudflare";
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (eq serverDeploy "alchemy")}}
|
||||
import { Worker, WranglerJson } from "alchemy/cloudflare";
|
||||
{{#if (eq dbSetup "d1")}}
|
||||
import { D1Database } from "alchemy/cloudflare";
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (and (eq serverDeploy "alchemy") (eq dbSetup "d1"))}}
|
||||
import { Exec } from "alchemy/os";
|
||||
{{/if}}
|
||||
import { config } from "dotenv";
|
||||
|
||||
{{#if (and (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
|
||||
config({ path: "./.env" });
|
||||
config({ path: "./apps/web/.env" });
|
||||
config({ path: "./apps/server/.env" });
|
||||
{{else if (or (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
|
||||
config({ path: "./.env" });
|
||||
{{/if}}
|
||||
|
||||
const app = await alchemy("{{projectName}}");
|
||||
|
||||
{{#if (and (eq serverDeploy "alchemy") (eq dbSetup "d1"))}}
|
||||
await Exec("db-generate", {
|
||||
{{#if (and (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}cwd: "apps/server",{{/if}}
|
||||
command: "{{packageManager}} run db:generate",
|
||||
});
|
||||
|
||||
const db = await D1Database("database", {
|
||||
name: `${app.name}-${app.stage}-db`,
|
||||
migrationsDir: "apps/server/src/db/migrations",
|
||||
});
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq webDeploy "alchemy")}}
|
||||
{{#if (includes frontend "next")}}
|
||||
export const web = await Next("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
NEXT_PUBLIC_CONVEX_URL: process.env.NEXT_PUBLIC_CONVEX_URL || "",
|
||||
{{else}}
|
||||
NEXT_PUBLIC_SERVER_URL: process.env.NEXT_PUBLIC_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "nuxt")}}
|
||||
export const web = await Nuxt("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
NUXT_PUBLIC_CONVEX_URL: process.env.NUXT_PUBLIC_CONVEX_URL || "",
|
||||
{{else}}
|
||||
NUXT_PUBLIC_SERVER_URL: process.env.NUXT_PUBLIC_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "svelte")}}
|
||||
export const web = await SvelteKit("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
PUBLIC_CONVEX_URL: process.env.PUBLIC_CONVEX_URL || "",
|
||||
{{else}}
|
||||
PUBLIC_SERVER_URL: process.env.PUBLIC_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "tanstack-start")}}
|
||||
export const web = await TanStackStart("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
VITE_CONVEX_URL: process.env.VITE_CONVEX_URL || "",
|
||||
{{else}}
|
||||
VITE_SERVER_URL: process.env.VITE_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "tanstack-router")}}
|
||||
export const web = await Vite("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
assets: "dist",
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
VITE_CONVEX_URL: process.env.VITE_CONVEX_URL || "",
|
||||
{{else}}
|
||||
VITE_SERVER_URL: process.env.VITE_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "react-router")}}
|
||||
export const web = await ReactRouter("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
VITE_CONVEX_URL: process.env.VITE_CONVEX_URL || "",
|
||||
{{else}}
|
||||
VITE_SERVER_URL: process.env.VITE_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{else if (includes frontend "solid")}}
|
||||
export const web = await Vite("web", {
|
||||
{{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
|
||||
name: `${app.name}-${app.stage}-web`,
|
||||
assets: "dist",
|
||||
bindings: {
|
||||
{{#if (eq backend "convex")}}
|
||||
VITE_CONVEX_URL: process.env.VITE_CONVEX_URL || "",
|
||||
{{else}}
|
||||
VITE_SERVER_URL: process.env.VITE_SERVER_URL || "",
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
command: "{{packageManager}} run dev"
|
||||
}
|
||||
});
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq serverDeploy "alchemy")}}
|
||||
export const server = await Worker("server", {
|
||||
{{#if (eq webDeploy "alchemy")}}cwd: "apps/server",{{/if}}
|
||||
name: `${app.name}-${app.stage}`,
|
||||
entrypoint: "src/index.ts",
|
||||
compatibility: "node",
|
||||
bindings: {
|
||||
{{#if (eq dbSetup "d1")}}
|
||||
DB: db,
|
||||
{{else if (and (ne database "none") (ne dbSetup "none"))}}
|
||||
DATABASE_URL: alchemy.secret(process.env.DATABASE_URL),
|
||||
{{/if}}
|
||||
CORS_ORIGIN: process.env.CORS_ORIGIN || "",
|
||||
{{#if auth}}
|
||||
BETTER_AUTH_SECRET: alchemy.secret(process.env.BETTER_AUTH_SECRET),
|
||||
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL || "",
|
||||
{{/if}}
|
||||
{{#if (includes examples "ai")}}
|
||||
GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret(process.env.GOOGLE_GENERATIVE_AI_API_KEY),
|
||||
{{/if}}
|
||||
{{#if (eq dbSetup "turso")}}
|
||||
DATABASE_AUTH_TOKEN: alchemy.secret(process.env.DATABASE_AUTH_TOKEN),
|
||||
{{/if}}
|
||||
},
|
||||
dev: {
|
||||
port: 3000,
|
||||
},
|
||||
});
|
||||
|
||||
await WranglerJson("wrangler", {
|
||||
worker: server,
|
||||
});
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
{{#if (and (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
|
||||
console.log(`Web -> ${web.url}`);
|
||||
console.log(`Server -> ${server.url}`);
|
||||
{{else if (eq webDeploy "alchemy")}}
|
||||
console.log(`Web -> ${web.url}`);
|
||||
{{else if (eq serverDeploy "alchemy")}}
|
||||
console.log(`Server -> ${server.url}`);
|
||||
{{/if}}
|
||||
|
||||
await app.finalize();
|
||||
20
apps/cli/templates/deploy/alchemy/env.d.ts.hbs
Normal file
20
apps/cli/templates/deploy/alchemy/env.d.ts.hbs
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file infers types for the cloudflare:workers environment from your Alchemy Worker.
|
||||
// @see https://alchemy.run/concepts/bindings/#type-safe-bindings
|
||||
|
||||
{{#if (eq webDeploy "alchemy")}}
|
||||
import type { server } from "../../alchemy.run";
|
||||
{{else}}
|
||||
import type { server } from "./alchemy.run";
|
||||
{{/if}}
|
||||
|
||||
export type CloudflareEnv = typeof server.Env;
|
||||
|
||||
declare global {
|
||||
type Env = CloudflareEnv;
|
||||
}
|
||||
|
||||
declare module "cloudflare:workers" {
|
||||
namespace Cloudflare {
|
||||
export interface Env extends CloudflareEnv {}
|
||||
}
|
||||
}
|
||||
11
apps/cli/templates/deploy/alchemy/wrangler.jsonc.hbs
Normal file
11
apps/cli/templates/deploy/alchemy/wrangler.jsonc.hbs
Normal file
@@ -0,0 +1,11 @@
|
||||
// This is a temporary wrangler.jsonc file that will be overwritten by alchemy
|
||||
// It's only here so that `wrangler dev` can work or use alchemy dev instead
|
||||
{
|
||||
"name": "{{projectName}}",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-08-16",
|
||||
"compatibility_flags": [
|
||||
"nodejs_compat",
|
||||
"nodejs_compat_populate_process_env"
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* https://developers.cloudflare.com/workers/wrangler/configuration/
|
||||
*/
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"main": "./.output/server/index.mjs",
|
||||
"compatibility_date": "2025-07-01",
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"main": ".open-next/worker.js",
|
||||
"name": "{{projectName}}",
|
||||
"compatibility_date": "2025-07-05",
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"compatibility_date": "2025-04-03",
|
||||
"assets": {
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"compatibility_date": "2025-04-03",
|
||||
"assets": {
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"main": ".output/server/index.mjs",
|
||||
"compatibility_date": "2025-07-05",
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"compatibility_date": "2025-04-03",
|
||||
"assets": {
|
||||
@@ -3,7 +3,7 @@
|
||||
* https://developers.cloudflare.com/workers/wrangler/configuration/
|
||||
*/
|
||||
{
|
||||
"$schema": "../../node_modules/wrangler/config-schema.json",
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "{{projectName}}",
|
||||
"main": ".svelte-kit/cloudflare/_worker.js",
|
||||
"compatibility_date": "2025-07-05",
|
||||
@@ -5,6 +5,8 @@
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
.wrangler
|
||||
.alchemy
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
@@ -22,3 +24,4 @@ logs
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./.nuxt/tsconfig.node.json"
|
||||
}
|
||||
{{#unless (or (eq backend "convex") (eq backend "none"))}}
|
||||
,
|
||||
}{{#unless (or (eq backend "convex") (eq backend "none"))}},
|
||||
{
|
||||
"path": "../server"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
.alchemy
|
||||
|
||||
# Environment & local files
|
||||
.env*
|
||||
|
||||
@@ -6,7 +6,6 @@ import { NavLink } from "react-router";
|
||||
{{else if (or (includes frontend "tanstack-router") (includes frontend "tanstack-start"))}}
|
||||
import { Link } from "@tanstack/react-router";
|
||||
{{/if}}
|
||||
|
||||
{{#unless (includes frontend "tanstack-start")}}
|
||||
import { ModeToggle } from "./mode-toggle";
|
||||
{{/unless}}
|
||||
|
||||
@@ -7,4 +7,5 @@ dist-ssr
|
||||
.env.*
|
||||
|
||||
.wrangler
|
||||
.alchemy
|
||||
.dev.vars*
|
||||
@@ -13,7 +13,6 @@
|
||||
"@tanstack/router-plugin": "^1.109.2",
|
||||
"@tanstack/solid-form": "^1.9.0",
|
||||
"@tanstack/solid-router": "^1.110.0",
|
||||
"@tanstack/solid-router-devtools": "^1.109.2",
|
||||
"lucide-solid": "^0.507.0",
|
||||
"solid-js": "^1.9.4",
|
||||
"tailwindcss": "^4.0.6",
|
||||
|
||||
@@ -5,6 +5,7 @@ node_modules
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
.alchemy
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
|
||||
@@ -12,20 +12,18 @@
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^6.0.0",
|
||||
"@sveltejs/kit": "^2.20.7",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@tailwindcss/vite": "^4.1.4",
|
||||
"svelte": "^5.28.2",
|
||||
"svelte-check": "^4.1.6",
|
||||
"tailwindcss": "^4.1.4",
|
||||
"typescript": "^5.8.3",
|
||||
"@tanstack/svelte-query-devtools": "^5.74.6",
|
||||
"vite": "^7.0.2"
|
||||
"@sveltejs/adapter-auto": "^6.1.0",
|
||||
"@sveltejs/kit": "^2.31.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.1.2",
|
||||
"@tailwindcss/vite": "^4.1.12",
|
||||
"svelte": "^5.38.1",
|
||||
"svelte-check": "^4.3.1",
|
||||
"tailwindcss": "^4.1.12",
|
||||
"typescript": "^5.9.2",
|
||||
"vite": "^7.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/svelte-form": "^1.7.0",
|
||||
"@tanstack/svelte-query": "^5.74.4",
|
||||
"zod": "^4.0.2"
|
||||
"@tanstack/svelte-form": "^1.19.2",
|
||||
"zod": "^4.0.17"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user