create-questpie 2.0.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/dist/index.mjs +362 -119
  2. package/package.json +2 -3
  3. package/templates/elysia/AGENTS.md +56 -0
  4. package/templates/elysia/CLAUDE.md +39 -0
  5. package/templates/elysia/Dockerfile +24 -0
  6. package/templates/elysia/README.md +148 -0
  7. package/templates/elysia/docker/init-extensions.sql +11 -0
  8. package/templates/elysia/docker-compose.yml +21 -0
  9. package/templates/elysia/env.example +16 -0
  10. package/templates/elysia/gitignore +6 -0
  11. package/templates/elysia/package.json +47 -0
  12. package/templates/elysia/questpie.config.ts +12 -0
  13. package/templates/elysia/src/index.ts +21 -0
  14. package/templates/elysia/src/lib/auth-client.ts +32 -0
  15. package/templates/elysia/src/lib/client.ts +13 -0
  16. package/templates/elysia/src/lib/env.ts +24 -0
  17. package/templates/elysia/src/lib/query-client.ts +18 -0
  18. package/templates/elysia/src/lib/query.ts +18 -0
  19. package/templates/elysia/src/questpie/server/.generated/context.gen.ts +200 -0
  20. package/templates/elysia/src/questpie/server/.generated/entities.gen.ts +84 -0
  21. package/templates/elysia/src/questpie/server/.generated/factories.ts +65 -0
  22. package/templates/elysia/src/questpie/server/.generated/index.ts +131 -0
  23. package/templates/elysia/src/questpie/server/.generated/names.gen.ts +25 -0
  24. package/templates/elysia/src/questpie/server/app.ts +10 -0
  25. package/templates/elysia/src/questpie/server/collections/index.ts +1 -0
  26. package/templates/elysia/src/questpie/server/collections/posts.collection.ts +10 -0
  27. package/templates/elysia/src/questpie/server/config/auth.ts +8 -0
  28. package/templates/elysia/src/questpie/server/config/openapi.ts +10 -0
  29. package/templates/elysia/src/questpie/server/globals/index.ts +1 -0
  30. package/templates/elysia/src/questpie/server/globals/site-settings.global.ts +10 -0
  31. package/templates/elysia/src/questpie/server/modules.ts +8 -0
  32. package/templates/elysia/src/questpie/server/questpie.config.ts +21 -0
  33. package/templates/elysia/tsconfig.json +28 -0
  34. package/templates/hono/AGENTS.md +56 -0
  35. package/templates/hono/CLAUDE.md +39 -0
  36. package/templates/hono/Dockerfile +24 -0
  37. package/templates/hono/README.md +148 -0
  38. package/templates/hono/docker/init-extensions.sql +11 -0
  39. package/templates/hono/docker-compose.yml +21 -0
  40. package/templates/hono/env.example +16 -0
  41. package/templates/hono/gitignore +6 -0
  42. package/templates/hono/package.json +47 -0
  43. package/templates/hono/questpie.config.ts +12 -0
  44. package/templates/hono/src/index.ts +30 -0
  45. package/templates/hono/src/lib/auth-client.ts +32 -0
  46. package/templates/hono/src/lib/client.ts +13 -0
  47. package/templates/hono/src/lib/env.ts +24 -0
  48. package/templates/hono/src/lib/query-client.ts +18 -0
  49. package/templates/hono/src/lib/query.ts +18 -0
  50. package/templates/hono/src/questpie/server/.generated/context.gen.ts +200 -0
  51. package/templates/hono/src/questpie/server/.generated/entities.gen.ts +84 -0
  52. package/templates/hono/src/questpie/server/.generated/factories.ts +65 -0
  53. package/templates/hono/src/questpie/server/.generated/index.ts +131 -0
  54. package/templates/hono/src/questpie/server/.generated/names.gen.ts +25 -0
  55. package/templates/hono/src/questpie/server/app.ts +10 -0
  56. package/templates/hono/src/questpie/server/collections/index.ts +1 -0
  57. package/templates/hono/src/questpie/server/collections/posts.collection.ts +10 -0
  58. package/templates/hono/src/questpie/server/config/auth.ts +8 -0
  59. package/templates/hono/src/questpie/server/config/openapi.ts +10 -0
  60. package/templates/hono/src/questpie/server/globals/index.ts +1 -0
  61. package/templates/hono/src/questpie/server/globals/site-settings.global.ts +10 -0
  62. package/templates/hono/src/questpie/server/modules.ts +8 -0
  63. package/templates/hono/src/questpie/server/questpie.config.ts +21 -0
  64. package/templates/hono/tsconfig.json +28 -0
  65. package/templates/next/AGENTS.md +55 -0
  66. package/templates/next/CLAUDE.md +39 -0
  67. package/templates/next/Dockerfile +25 -0
  68. package/templates/next/README.md +148 -0
  69. package/templates/next/components.json +22 -0
  70. package/templates/next/docker/init-extensions.sql +11 -0
  71. package/templates/next/docker-compose.yml +21 -0
  72. package/templates/next/env.example +16 -0
  73. package/templates/next/gitignore +10 -0
  74. package/templates/next/next-env.d.ts +5 -0
  75. package/templates/next/next.config.ts +20 -0
  76. package/templates/next/package.json +54 -0
  77. package/templates/next/postcss.config.mjs +8 -0
  78. package/templates/next/public/.gitkeep +0 -0
  79. package/templates/next/questpie.config.ts +12 -0
  80. package/templates/next/src/app/admin/[[...all]]/page.tsx +34 -0
  81. package/templates/next/src/app/admin/admin.css +4 -0
  82. package/templates/next/src/app/admin/layout.tsx +63 -0
  83. package/templates/next/src/app/api/[...all]/route.ts +24 -0
  84. package/templates/next/src/app/layout.tsx +24 -0
  85. package/templates/next/src/app/not-found.tsx +18 -0
  86. package/templates/next/src/app/page.tsx +74 -0
  87. package/templates/next/src/app/providers.tsx +11 -0
  88. package/templates/next/src/lib/auth-client.ts +12 -0
  89. package/templates/next/src/lib/client.ts +13 -0
  90. package/templates/next/src/lib/env.ts +24 -0
  91. package/templates/next/src/lib/query-client.ts +18 -0
  92. package/templates/next/src/lib/query.ts +18 -0
  93. package/templates/next/src/questpie/admin/.generated/client.ts +13 -0
  94. package/templates/next/src/questpie/admin/admin.ts +9 -0
  95. package/templates/next/src/questpie/admin/modules.ts +3 -0
  96. package/templates/next/src/questpie/server/.generated/context.gen.ts +204 -0
  97. package/templates/next/src/questpie/server/.generated/entities.gen.ts +100 -0
  98. package/templates/next/src/questpie/server/.generated/factories.ts +204 -0
  99. package/templates/next/src/questpie/server/.generated/index.ts +139 -0
  100. package/templates/next/src/questpie/server/.generated/names.gen.ts +31 -0
  101. package/templates/next/src/questpie/server/app.ts +10 -0
  102. package/templates/next/src/questpie/server/collections/index.ts +1 -0
  103. package/templates/next/src/questpie/server/collections/posts.collection.ts +58 -0
  104. package/templates/next/src/questpie/server/config/admin.ts +80 -0
  105. package/templates/next/src/questpie/server/config/auth.ts +8 -0
  106. package/templates/next/src/questpie/server/config/openapi.ts +10 -0
  107. package/templates/next/src/questpie/server/globals/index.ts +1 -0
  108. package/templates/next/src/questpie/server/globals/site-settings.global.ts +19 -0
  109. package/templates/next/src/questpie/server/modules.ts +9 -0
  110. package/templates/next/src/questpie/server/questpie.config.ts +21 -0
  111. package/templates/next/src/styles.css +125 -0
  112. package/templates/next/tsconfig.json +37 -0
  113. package/templates/tanstack-start/AGENTS.md +35 -607
  114. package/templates/tanstack-start/CLAUDE.md +26 -134
  115. package/templates/tanstack-start/README.md +13 -1
  116. package/templates/tanstack-start/docker/init-extensions.sql +11 -0
  117. package/templates/tanstack-start/docker-compose.yml +1 -0
  118. package/templates/tanstack-start/src/lib/auth-client.ts +1 -1
  119. package/templates/tanstack-start/src/lib/client.ts +1 -1
  120. package/templates/tanstack-start/src/lib/query.ts +18 -0
  121. package/templates/tanstack-start/src/questpie/server/collections/index.ts +1 -1
  122. package/templates/tanstack-start/src/questpie/server/globals/index.ts +1 -1
  123. package/templates/tanstack-start/src/questpie/server/questpie.config.ts +1 -1
  124. package/templates/tanstack-start/src/routes/__root.tsx +31 -1
  125. package/templates/tanstack-start/src/routes/api/$.ts +1 -1
  126. package/templates/tanstack-start/src/routes/index.tsx +97 -0
  127. package/skills/questpie/AGENTS.md +0 -2871
  128. package/skills/questpie/SKILL.md +0 -293
  129. package/skills/questpie/coverage.json +0 -213
  130. package/skills/questpie/references/auth.md +0 -236
  131. package/skills/questpie/references/business-logic.md +0 -620
  132. package/skills/questpie/references/codegen-plugin-api.md +0 -382
  133. package/skills/questpie/references/crud-api.md +0 -580
  134. package/skills/questpie/references/data-modeling.md +0 -509
  135. package/skills/questpie/references/extend.md +0 -584
  136. package/skills/questpie/references/field-types.md +0 -398
  137. package/skills/questpie/references/infrastructure-adapters.md +0 -720
  138. package/skills/questpie/references/mcp.md +0 -147
  139. package/skills/questpie/references/multi-tenancy.md +0 -363
  140. package/skills/questpie/references/production.md +0 -640
  141. package/skills/questpie/references/query-operators.md +0 -125
  142. package/skills/questpie/references/quickstart.md +0 -562
  143. package/skills/questpie/references/rules.md +0 -454
  144. package/skills/questpie/references/sandbox.md +0 -110
  145. package/skills/questpie/references/tanstack-query.md +0 -543
  146. package/skills/questpie/references/type-inference.md +0 -167
  147. package/skills/questpie/references/workflows.md +0 -155
  148. package/skills/questpie-admin/AGENTS.md +0 -1515
  149. package/skills/questpie-admin/SKILL.md +0 -443
  150. package/skills/questpie-admin/references/blocks.md +0 -331
  151. package/skills/questpie-admin/references/custom-ui.md +0 -305
  152. package/skills/questpie-admin/references/views.md +0 -449
@@ -0,0 +1,56 @@
1
+ # AGENTS.md
2
+
3
+ Guidance for AI agents working in this [QUESTPIE](https://questpie.com) project.
4
+
5
+ ## Use the QUESTPIE skills
6
+
7
+ This project is built on QUESTPIE. Do not work from memory — the framework is
8
+ codegen-driven and the APIs evolve. Lean on the installed skill:
9
+
10
+ - **`questpie`** — collections, globals, routes, jobs, codegen, auth, business
11
+ logic, the typed client + TanStack Query. Invoke it for any server/data work.
12
+
13
+ Invoke skills by name (the `/skill` convention) — they are commands, not files
14
+ to read. This is a **headless API** template (no admin UI), so the
15
+ `questpie-admin` skill does not apply here.
16
+
17
+ **If the skill is NOT installed**, install it first, then trim this file:
18
+
19
+ ```bash
20
+ bunx skills add questpie/questpie
21
+ ```
22
+
23
+ After installing, replace the body of this file with a one-line pointer to the
24
+ skill above — it is the always-current source of truth and this doc should not
25
+ duplicate it.
26
+
27
+ ## Docs for LLMs
28
+
29
+ When the skill isn't enough, consult:
30
+
31
+ - https://questpie.com/llms.txt — doc sitemap
32
+ - https://questpie.com/llms-full.txt — full docs in one LLM-optimized file
33
+ - http://localhost:3000/api/docs — live API reference (Scalar, dev server running)
34
+
35
+ ## This project
36
+
37
+ - **Runtime**: Elysia on **Bun** (no bundler — the QUESTPIE `.js` ESM import
38
+ convention resolves natively). Package manager **Bun**.
39
+ - **Shape**: headless API only — no admin UI, no React. The fetch handler is
40
+ mounted at `src/index.ts` under `/api`.
41
+ - **Database**: PostgreSQL via Drizzle ORM (Postgres extensions are not
42
+ auto-created — see `README.md`)
43
+ - **Auth**: Better Auth (email/password). The typed `better-auth/client` lives
44
+ in `src/lib/auth-client.ts` for a consuming frontend or scripts.
45
+ - **Validation**: Zod **v4** (not v3)
46
+ - **Source layout**: server contracts in `src/questpie/server/`, HTTP mount in
47
+ `src/index.ts`, typed client + TanStack Query in `src/lib/`
48
+
49
+ ## Key scripts
50
+
51
+ ```bash
52
+ bun dev # Start dev server with watch (port 3000)
53
+ bun run scaffold:verify # Regenerate codegen + type-check
54
+ bun run db:push # Push schema to the local dev database
55
+ bun questpie add collection <name> # Scaffold an entity (auto-runs codegen)
56
+ ```
@@ -0,0 +1,39 @@
1
+ # CLAUDE.md
2
+
3
+ This is a [QUESTPIE](https://questpie.com) project. See **`AGENTS.md`** for the
4
+ full agent guide — it is the source of truth and this file mirrors it.
5
+
6
+ ## Use the QUESTPIE skill
7
+
8
+ - **`questpie`** — collections, globals, routes, jobs, codegen, auth, business
9
+ logic, typed client + TanStack Query.
10
+
11
+ Invoke skills by name (the `/skill` convention); don't work from memory. This is
12
+ a **headless API** template (no admin UI), so `questpie-admin` does not apply.
13
+
14
+ **If it isn't installed**, install it and then trim this file to a pointer:
15
+
16
+ ```bash
17
+ bunx skills add questpie/questpie
18
+ ```
19
+
20
+ ## Docs for LLMs
21
+
22
+ - https://questpie.com/llms.txt — doc sitemap
23
+ - https://questpie.com/llms-full.txt — full docs in one LLM-optimized file
24
+ - http://localhost:3000/api/docs — live API reference (dev server running)
25
+
26
+ ## This project
27
+
28
+ - **Runtime**: Elysia on **Bun** (no bundler — `.js` ESM imports resolve natively)
29
+ - **Shape**: headless API — no admin UI, no React; fetch handler at `src/index.ts`
30
+ - **Database**: PostgreSQL (Drizzle ORM)
31
+ - **Auth**: Better Auth (email/password); typed `better-auth/client` in `src/lib/`
32
+ - **Validation**: Zod **v4**
33
+
34
+ ```bash
35
+ bun dev # Dev server with watch (port 3000)
36
+ bun run scaffold:verify # Regenerate codegen + type-check
37
+ bun run db:push # Push schema to local dev DB
38
+ bun questpie add collection <name> # Scaffold an entity (auto-runs codegen)
39
+ ```
@@ -0,0 +1,24 @@
1
+ FROM oven/bun:1.3-alpine AS base
2
+
3
+ WORKDIR /app
4
+
5
+ # Install dependencies
6
+ FROM base AS deps
7
+ COPY package.json bun.lock* ./
8
+ RUN bun install --frozen-lockfile
9
+
10
+ # Build application (bundles the entry to dist/ with the Bun target)
11
+ FROM base AS builder
12
+ COPY --from=deps /app/node_modules ./node_modules
13
+ COPY . .
14
+ RUN bun run scaffold:generate
15
+ RUN bun run build
16
+
17
+ # Production image
18
+ FROM base AS runner
19
+ ENV NODE_ENV=production
20
+ ENV PORT=3000
21
+ COPY --from=builder /app/dist ./dist
22
+ COPY --from=builder /app/package.json ./package.json
23
+ EXPOSE 3000
24
+ CMD ["bun", "run", "dist/index.js"]
@@ -0,0 +1,148 @@
1
+ # {{projectName}}
2
+
3
+ A [QUESTPIE](https://questpie.com) **headless API** built with [Elysia](https://elysiajs.com),
4
+ running on [Bun](https://bun.sh). No admin UI, no React — just a typed REST API
5
+ with Scalar docs and a typed client you can consume from any frontend.
6
+
7
+ ## Quick Start
8
+
9
+ ### Prerequisites
10
+
11
+ - [Bun](https://bun.sh) v1.3+
12
+ - [Docker](https://docker.com) (for local PostgreSQL)
13
+
14
+ ### Setup
15
+
16
+ ```bash
17
+ # 1) Start PostgreSQL (also provisions required extensions for local dev)
18
+ docker compose up -d
19
+
20
+ # 2) Regenerate codegen and type-check
21
+ bun run scaffold:verify
22
+
23
+ # 3) Create local database tables
24
+ bun run db:push
25
+
26
+ # 4) Start the development server (watch mode)
27
+ bun dev
28
+ ```
29
+
30
+ - API docs (Scalar): `http://localhost:3000/api/docs` (the root `/` redirects here)
31
+ - REST API: `http://localhost:3000/api/*`
32
+
33
+ ## What you get
34
+
35
+ - **Headless REST API** — every collection and global is exposed under `/api`.
36
+ - **Scalar API reference** at `/api/docs` (the `openapi` module).
37
+ - **Auth** — Better Auth (email/password) mounted at `/api/auth`.
38
+ - **Typed client + TanStack Query** in `src/lib/` — `client.ts`
39
+ (`createClient<AppConfig>`), `query.ts` (`createQuestpieQueryOptions`), and
40
+ `auth-client.ts` (`better-auth/client`). A separate frontend or scripts import
41
+ these for end-to-end type safety against your server schema.
42
+
43
+ ## Running on Node instead of Bun
44
+
45
+ The entry (`src/index.ts`) calls `.listen()`, which serves on Bun directly. To
46
+ run on Node, install `@elysiajs/node` and pass its adapter:
47
+
48
+ ```ts
49
+ import { node } from "@elysiajs/node";
50
+ new Elysia({ adapter: node() }) /* …routes… */ .listen(env.PORT ?? 3000);
51
+ ```
52
+
53
+ ## Database extensions
54
+
55
+ QUESTPIE is drizzle-native and does **not** auto-create Postgres extensions. The
56
+ starter's full-text search relies on `pg_trgm` (trigram matching).
57
+
58
+ - **Local dev:** `docker compose up` provisions `pg_trgm` via
59
+ `docker/init-extensions.sql`, mounted into the postgres container's
60
+ `/docker-entrypoint-initdb.d/` and run once on first cluster init — so
61
+ `db:push` works out of the box.
62
+ - **Managed Postgres:** enable required extensions through your provider before
63
+ deploying. See [the QUESTPIE docs](https://questpie.com/docs/deployment) for details.
64
+
65
+ ## Project Structure
66
+
67
+ ```text
68
+ src/
69
+ index.ts # Elysia entry — mounts the fetch handler at /api
70
+ questpie/
71
+ server/
72
+ questpie.config.ts # Runtime config
73
+ modules.ts # Module list (openapi/...)
74
+ config/
75
+ auth.ts # Auth config
76
+ openapi.ts # OpenAPI/Scalar config
77
+ app.ts # Re-export of generated app
78
+ .generated/ # Codegen output (do not edit manually)
79
+ collections/
80
+ posts.collection.ts
81
+ globals/
82
+ site-settings.global.ts
83
+ lib/
84
+ env.ts
85
+ client.ts # Typed REST client (createClient<AppConfig>)
86
+ auth-client.ts # Typed Better Auth client
87
+ query.ts # TanStack Query option builders
88
+ query-client.ts
89
+ migrations/
90
+ ```
91
+
92
+ ## Scripts
93
+
94
+ | Command | Description |
95
+ | -------------------------------- | --------------------------------------------- |
96
+ | `bun dev` | Start development server (watch) |
97
+ | `bun run build` | Bundle the entry to `dist/` |
98
+ | `bun run start` | Run the server (no watch) |
99
+ | `bun run check-types` | Type check |
100
+ | `bun run scaffold:generate` | Regenerate QUESTPIE codegen |
101
+ | `bun run scaffold:verify` | Regenerate codegen and type-check |
102
+ | `bun run questpie:generate` | Regenerate `src/questpie/server/.generated/*` |
103
+ | `bun questpie add <type> <name>` | Scaffold entity files (auto-runs codegen) |
104
+ | `bun run db:push` | Push schema directly to local dev database |
105
+ | `bun run migrate` | Run migrations |
106
+ | `bun run migrate:create` | Create migration |
107
+
108
+ ## Learn more
109
+
110
+ - [Quickstart](https://questpie.com/docs/quickstart)
111
+ - [Data modeling](https://questpie.com/docs/data-modeling)
112
+ - [Auth](https://questpie.com/docs/auth)
113
+ - [TanStack Query](https://questpie.com/docs/tanstack-query)
114
+ - [Deployment](https://questpie.com/docs/deployment)
115
+
116
+ ## Adding a Collection
117
+
118
+ Preferred workflow:
119
+
120
+ 1. Run `bun questpie add collection products`.
121
+ 2. The CLI creates the file and runs codegen automatically.
122
+ 3. Run `bun run db:push` for local development, or `bun run migrate:create` for production migrations.
123
+
124
+ Manual workflow (when you create files by hand):
125
+
126
+ 1. Create a file in `src/questpie/server/collections/`.
127
+ 2. Export a collection builder from that file.
128
+ 3. Run `bun run questpie:generate`.
129
+ 4. Run `bun run db:push` for local development, or `bun run migrate:create` for production migrations.
130
+
131
+ Collections are discovered automatically by codegen. No manual `app.ts` registration is required.
132
+
133
+ ## Adding a Global
134
+
135
+ Preferred workflow:
136
+
137
+ 1. Run `bun questpie add global marketing`.
138
+ 2. The CLI creates the file and runs codegen automatically.
139
+ 3. Run `bun run db:push` for local development, or `bun run migrate:create` for production migrations.
140
+
141
+ Manual workflow (when you create files by hand):
142
+
143
+ 1. Create a file in `src/questpie/server/globals/`.
144
+ 2. Export a global builder from that file.
145
+ 3. Run `bun run questpie:generate`.
146
+ 4. Run `bun run db:push` for local development, or `bun run migrate:create` for production migrations.
147
+
148
+ Globals are discovered automatically by codegen. No manual `app.ts` registration is required.
@@ -0,0 +1,11 @@
1
+ -- Postgres extensions provisioned for local development.
2
+ -- Mounted into the postgres container at /docker-entrypoint-initdb.d/ and run
3
+ -- once, on first cluster init, before the app connects.
4
+ --
5
+ -- QUESTPIE is drizzle-native: the app does NOT auto-create extensions. The
6
+ -- starter's full-text search uses pg_trgm (trigram matching), so we provision
7
+ -- it here to keep `db:push` working out-of-the-box while you prototype.
8
+ --
9
+ -- On managed Postgres, enable required extensions via your provider instead.
10
+ -- See https://questpie.com/docs for details.
11
+ CREATE EXTENSION IF NOT EXISTS "pg_trgm";
@@ -0,0 +1,21 @@
1
+ services:
2
+ postgres:
3
+ image: postgres:17
4
+ container_name: {{projectName}}-postgres
5
+ environment:
6
+ POSTGRES_DB: {{databaseName}}
7
+ POSTGRES_USER: {{databaseUser}}
8
+ POSTGRES_PASSWORD: {{databasePassword}}
9
+ ports:
10
+ - "5432:5432"
11
+ volumes:
12
+ - postgres_data:/var/lib/postgresql/data
13
+ - ./docker/init-extensions.sql:/docker-entrypoint-initdb.d/init-extensions.sql:ro
14
+ healthcheck:
15
+ test: ["CMD-SHELL", "pg_isready -U {{databaseUser}}"]
16
+ interval: 5s
17
+ timeout: 5s
18
+ retries: 5
19
+
20
+ volumes:
21
+ postgres_data:
@@ -0,0 +1,16 @@
1
+ # Database
2
+ DATABASE_URL=postgresql://{{databaseUser}}:{{databasePassword}}@localhost:5432/{{databaseName}}
3
+
4
+ # Application
5
+ APP_URL=http://localhost:3000
6
+ PORT=3000
7
+
8
+ # Auth (Better Auth)
9
+ BETTER_AUTH_SECRET={{authSecret}}
10
+
11
+ # Email Adapter (console | smtp)
12
+ MAIL_ADAPTER=console
13
+
14
+ # SMTP (if using smtp adapter)
15
+ # SMTP_HOST=localhost
16
+ # SMTP_PORT=1025
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ .DS_Store
3
+ dist
4
+ *.local
5
+ .env
6
+ uploads
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "imports": {
7
+ "#questpie": "./src/questpie/server/.generated/index.ts",
8
+ "#questpie/*": "./src/questpie/server/.generated/*"
9
+ },
10
+ "scripts": {
11
+ "dev": "bun --watch src/index.ts",
12
+ "start": "bun run src/index.ts",
13
+ "build": "bun build src/index.ts --target=bun --outdir=dist",
14
+ "check-types": "tsc --noEmit",
15
+ "questpie:generate": "questpie generate -c src/questpie/server/questpie.config.ts",
16
+ "scaffold:generate": "bun run questpie:generate",
17
+ "db:push": "questpie push -c questpie.config.ts",
18
+ "migrate": "questpie migrate -c questpie.config.ts",
19
+ "migrate:create": "questpie migrate:create -c questpie.config.ts",
20
+ "migrate:status": "questpie migrate:status -c questpie.config.ts",
21
+ "migrate:down": "questpie migrate:down -c questpie.config.ts",
22
+ "migrate:reset": "questpie migrate:reset -c questpie.config.ts",
23
+ "migrate:fresh": "questpie migrate:fresh -c questpie.config.ts",
24
+ "scaffold:verify": "bun run scaffold:generate && bun run check-types"
25
+ },
26
+ "dependencies": {
27
+ "@electric-sql/pglite": "^0.3.14",
28
+ "@questpie/openapi": "latest",
29
+ "@questpie/tanstack-query": "latest",
30
+ "@t3-oss/env-core": "^0.12.0",
31
+ "@tanstack/react-query": "^5.62.11",
32
+ "better-auth": "^1.6.11",
33
+ "drizzle-orm": "1.0.0-beta.6-4414a19",
34
+ "elysia": "^1.4.29",
35
+ "nodemailer": "^7.0.12",
36
+ "pg": "^8.13.1",
37
+ "pg-boss": "^12.5.4",
38
+ "questpie": "latest",
39
+ "zod": "^4.2.1"
40
+ },
41
+ "devDependencies": {
42
+ "@types/pg": "^8.11.10",
43
+ "bun-types": "latest",
44
+ "drizzle-kit": "1.0.0-beta.6-4414a19",
45
+ "typescript": "^5.9.2"
46
+ }
47
+ }
@@ -0,0 +1,12 @@
1
+ import { app } from "@/questpie/server/app";
2
+
3
+ export const config = {
4
+ app: app,
5
+ cli: {
6
+ migrations: {
7
+ directory: "./src/migrations",
8
+ },
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Elysia entrypoint (headless QUESTPIE API).
3
+ *
4
+ * Mounts the framework-agnostic fetch handler under `/api` and redirects the
5
+ * root to the Scalar API reference. Elysia runs on Bun and begins serving as
6
+ * soon as `.listen()` is called — `bun run src/index.ts` boots the server.
7
+ */
8
+ import { Elysia } from "elysia";
9
+ import { createFetchHandler } from "questpie/http";
10
+
11
+ import { env } from "@/lib/env";
12
+ import { app as questpie } from "@/questpie/server/app";
13
+
14
+ const handler = createFetchHandler(questpie, { basePath: "/api" });
15
+
16
+ new Elysia()
17
+ .all("/api/*", async ({ request }) => (await handler(request)) ?? new Response("Not Found", { status: 404 }))
18
+ .get("/", () => new Response(null, { status: 302, headers: { Location: "/api/docs" } }))
19
+ .listen(env.PORT ?? 3000);
20
+
21
+ console.log(`🚀 QUESTPIE headless API on http://localhost:${env.PORT ?? 3000}`);
@@ -0,0 +1,32 @@
1
+ import type { BetterAuthOptions } from "better-auth";
2
+ import { createAuthClient } from "better-auth/client";
3
+
4
+ import type { AppConfig } from "@/questpie/server/app";
5
+
6
+ /**
7
+ * Type-safe Better Auth client (vanilla, no React).
8
+ *
9
+ * `signIn`, `signUp`, `signOut`, `getSession`, etc. are fully typed from the
10
+ * app's auth configuration via `AppConfig["auth"]`. This headless template
11
+ * ships the framework-agnostic `better-auth/client` so a separate frontend or
12
+ * scripts can consume it.
13
+ */
14
+ type AppAuthOptions = AppConfig["auth"] extends BetterAuthOptions
15
+ ? AppConfig["auth"]
16
+ : BetterAuthOptions;
17
+
18
+ type AuthClientOptions = {
19
+ baseURL: string;
20
+ fetchOptions?: { credentials?: RequestCredentials };
21
+ $InferAuth: AppAuthOptions;
22
+ };
23
+
24
+ export const authClient = createAuthClient<AuthClientOptions>({
25
+ baseURL:
26
+ typeof window !== "undefined"
27
+ ? `${window.location.origin}/api/auth`
28
+ : `${process.env.APP_URL || "http://localhost:3000"}/api/auth`,
29
+ fetchOptions: { credentials: "include" },
30
+ } as AuthClientOptions);
31
+
32
+ export type AuthClient = typeof authClient;
@@ -0,0 +1,13 @@
1
+ import { createClient } from "questpie/client";
2
+
3
+ import type { AppConfig } from "@/questpie/server/app";
4
+
5
+ export const client = createClient<AppConfig>({
6
+ baseURL:
7
+ typeof window !== "undefined"
8
+ ? window.location.origin
9
+ : process.env.APP_URL || "http://localhost:3000",
10
+ basePath: "/api",
11
+ });
12
+
13
+ export type AppClient = typeof client;
@@ -0,0 +1,24 @@
1
+ import { createEnv } from "@t3-oss/env-core";
2
+ import { z } from "zod";
3
+
4
+ export const env = createEnv({
5
+ server: {
6
+ DATABASE_URL: z.string().url(),
7
+ APP_URL: z.string().url().default("http://localhost:3000"),
8
+ PORT: z
9
+ .string()
10
+ .transform(Number)
11
+ .pipe(z.number().int().positive())
12
+ .default(3000),
13
+ BETTER_AUTH_SECRET: z.string().min(1).default("change-me-in-production"),
14
+ MAIL_ADAPTER: z.enum(["console", "smtp"]).default("console"),
15
+ SMTP_HOST: z.string().optional(),
16
+ SMTP_PORT: z
17
+ .string()
18
+ .transform(Number)
19
+ .pipe(z.number().int().positive())
20
+ .optional(),
21
+ },
22
+ runtimeEnv: process.env,
23
+ emptyStringAsUndefined: true,
24
+ });
@@ -0,0 +1,18 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+
3
+ const ONE_MINUTE = 60 * 1000;
4
+ const FIVE_MINUTES = 5 * ONE_MINUTE;
5
+
6
+ export const queryClient = new QueryClient({
7
+ defaultOptions: {
8
+ queries: {
9
+ staleTime: ONE_MINUTE,
10
+ gcTime: FIVE_MINUTES,
11
+ refetchOnWindowFocus: false,
12
+ retry: 1,
13
+ },
14
+ mutations: {
15
+ retry: 0,
16
+ },
17
+ },
18
+ });
@@ -0,0 +1,18 @@
1
+ import { createQuestpieQueryOptions } from "@questpie/tanstack-query";
2
+
3
+ import { client } from "@/lib/client";
4
+
5
+ /**
6
+ * Typed TanStack Query option builders for this project.
7
+ *
8
+ * `q.collections.*`, `q.globals.*`, and `q.routes.*` return `queryOptions()` /
9
+ * `mutationOptions()` objects you pass straight into `useQuery` / `useMutation`.
10
+ * Full type inference flows from the server schema via `AppConfig`.
11
+ *
12
+ * @example
13
+ * const { data } = useQuery(q.collections.posts.find({ limit: 10 }));
14
+ * const create = useMutation(q.collections.posts.create());
15
+ */
16
+ export const q = createQuestpieQueryOptions(client);
17
+
18
+ export type QueryOptions = typeof q;