create-questpie 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +10 -6
  2. package/dist/index.mjs +139 -24
  3. package/package.json +5 -3
  4. package/skills/questpie/AGENTS.md +2670 -0
  5. package/skills/questpie/SKILL.md +260 -0
  6. package/skills/questpie/references/auth.md +121 -0
  7. package/skills/questpie/references/business-logic.md +550 -0
  8. package/skills/questpie/references/codegen-plugin-api.md +382 -0
  9. package/skills/questpie/references/crud-api.md +378 -0
  10. package/skills/questpie/references/data-modeling.md +493 -0
  11. package/skills/questpie/references/extend.md +557 -0
  12. package/skills/questpie/references/field-types.md +386 -0
  13. package/skills/questpie/references/infrastructure-adapters.md +545 -0
  14. package/skills/questpie/references/multi-tenancy.md +364 -0
  15. package/skills/questpie/references/production.md +475 -0
  16. package/skills/questpie/references/query-operators.md +125 -0
  17. package/skills/questpie/references/quickstart.md +564 -0
  18. package/skills/questpie/references/rules.md +389 -0
  19. package/skills/questpie/references/tanstack-query.md +520 -0
  20. package/skills/questpie-admin/AGENTS.md +1508 -0
  21. package/skills/questpie-admin/SKILL.md +436 -0
  22. package/skills/questpie-admin/references/blocks.md +331 -0
  23. package/skills/questpie-admin/references/custom-ui.md +305 -0
  24. package/skills/questpie-admin/references/views.md +449 -0
  25. package/templates/tanstack-start/AGENTS.md +17 -13
  26. package/templates/tanstack-start/CLAUDE.md +15 -12
  27. package/templates/tanstack-start/README.md +19 -13
  28. package/templates/tanstack-start/env.example +1 -1
  29. package/templates/tanstack-start/package.json +20 -6
  30. package/templates/tanstack-start/src/lib/env.ts +1 -1
  31. package/templates/tanstack-start/src/lib/query-client.ts +10 -1
  32. package/templates/tanstack-start/src/questpie/server/config/admin.ts +27 -30
  33. package/templates/tanstack-start/src/routeTree.gen.ts +138 -0
  34. package/templates/tanstack-start/src/routes/__root.tsx +0 -2
  35. package/templates/tanstack-start/src/routes/admin/$.tsx +12 -1
  36. package/templates/tanstack-start/src/routes/admin/index.tsx +12 -5
  37. package/templates/tanstack-start/src/routes/admin.tsx +8 -1
  38. package/templates/tanstack-start/src/tanstack-start.d.ts +1 -0
  39. package/templates/tanstack-start/src/vite-env.d.ts +1 -0
  40. package/templates/tanstack-start/vite.config.ts +1 -3
@@ -11,9 +11,20 @@
11
11
  "dev": "bun --bun vite dev --port 3000",
12
12
  "build": "vite build",
13
13
  "start": "bun run .output/server/index.mjs",
14
- "check-types": "tsc --noEmit"
14
+ "check-types": "tsc --noEmit",
15
+ "routes:generate": "tsr generate",
16
+ "questpie:generate": "questpie generate -c src/questpie/server/questpie.config.ts",
17
+ "scaffold:generate": "bun run routes:generate && bun run questpie:generate",
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"
15
25
  },
16
26
  "dependencies": {
27
+ "@electric-sql/pglite": "^0.3.14",
17
28
  "@questpie/admin": "latest",
18
29
  "@questpie/openapi": "latest",
19
30
  "@questpie/tanstack-query": "latest",
@@ -22,28 +33,31 @@
22
33
  "@tanstack/react-router": "^1.132.0",
23
34
  "@tanstack/react-start": "^1.132.0",
24
35
  "drizzle-orm": "1.0.0-beta.6-4414a19",
36
+ "nodemailer": "^7.0.12",
37
+ "pg": "^8.13.1",
38
+ "pg-boss": "^12.5.4",
25
39
  "questpie": "latest",
26
40
  "react": "^19.0.0",
27
41
  "react-dom": "^19.0.0",
28
42
  "zod": "^4.2.1"
29
43
  },
30
44
  "devDependencies": {
31
- "@iconify/json": ">=2",
32
- "@questpie/vite-plugin-iconify": "latest",
33
45
  "@tailwindcss/vite": "^4.0.0",
34
46
  "@tanstack/devtools-vite": "latest",
35
47
  "@tanstack/react-devtools": "latest",
36
48
  "@tanstack/react-router-devtools": "latest",
49
+ "@tanstack/router-cli": "^1.132.0",
37
50
  "@types/react": "^19.0.0",
38
51
  "@types/react-dom": "^19.0.0",
39
- "@vitejs/plugin-react": "^4.4.1",
52
+ "@vitejs/plugin-react": "^6.0.1",
40
53
  "bun-types": "latest",
41
54
  "drizzle-kit": "1.0.0-beta.6-4414a19",
42
55
  "nitro": "latest",
56
+ "shadcn": "^3.6.1",
43
57
  "tailwindcss": "^4.0.0",
44
58
  "tw-animate-css": "^1.0.0",
45
59
  "typescript": "^5.9.2",
46
- "vite": "^6.3.0",
47
- "vite-tsconfig-paths": "^4.3.2"
60
+ "vite": "^8.0.0",
61
+ "vite-tsconfig-paths": "^6.1.1"
48
62
  }
49
63
  }
@@ -9,7 +9,7 @@ export const env = createEnv({
9
9
  .string()
10
10
  .transform(Number)
11
11
  .pipe(z.number().int().positive())
12
- .default("3000"),
12
+ .default(3000),
13
13
  BETTER_AUTH_SECRET: z.string().min(1).default("change-me-in-production"),
14
14
  MAIL_ADAPTER: z.enum(["console", "smtp"]).default("console"),
15
15
  SMTP_HOST: z.string().optional(),
@@ -1,9 +1,18 @@
1
1
  import { QueryClient } from "@tanstack/react-query";
2
2
 
3
+ const ONE_MINUTE = 60 * 1000;
4
+ const FIVE_MINUTES = 5 * ONE_MINUTE;
5
+
3
6
  export const queryClient = new QueryClient({
4
7
  defaultOptions: {
5
8
  queries: {
6
- staleTime: 60 * 1000,
9
+ staleTime: ONE_MINUTE,
10
+ gcTime: FIVE_MINUTES,
11
+ refetchOnWindowFocus: false,
12
+ retry: 1,
13
+ },
14
+ mutations: {
15
+ retry: 0,
7
16
  },
8
17
  },
9
18
  });
@@ -9,23 +9,40 @@ export default adminConfig({
9
9
  {
10
10
  id: "main",
11
11
  title: "Content",
12
- items: [
13
- {
14
- type: "link",
15
- label: "Dashboard",
16
- href: "/admin",
17
- icon: { type: "icon", props: { name: "ph:house" } },
18
- },
19
- { type: "collection", collection: "posts" },
20
- { type: "global", global: "siteSettings" },
21
- ],
22
12
  },
23
13
  ],
14
+ items: [
15
+ {
16
+ sectionId: "main",
17
+ type: "link",
18
+ label: "Dashboard",
19
+ href: "/admin",
20
+ icon: { type: "icon", props: { name: "ph:house" } },
21
+ },
22
+ { sectionId: "main", type: "collection", collection: "posts" },
23
+ { sectionId: "main", type: "global", global: "siteSettings" },
24
+ ],
24
25
  },
25
26
  dashboard: {
26
27
  title: "Dashboard",
27
28
  description: "Overview of your content",
28
29
  columns: 4,
30
+ actions: [
31
+ {
32
+ id: "new-post",
33
+ label: "New Post",
34
+ href: "/admin/collections/posts/create",
35
+ icon: { type: "icon", props: { name: "ph:article" } },
36
+ variant: "primary",
37
+ },
38
+ {
39
+ id: "site-settings",
40
+ label: "Site Settings",
41
+ href: "/admin/globals/siteSettings",
42
+ icon: { type: "icon", props: { name: "ph:gear" } },
43
+ variant: "outline",
44
+ },
45
+ ],
29
46
  sections: [
30
47
  { id: "content", label: "Content", layout: "grid", columns: 2 },
31
48
  { id: "recent", label: "Recent", layout: "grid", columns: 4 },
@@ -58,26 +75,6 @@ export default adminConfig({
58
75
  limit: 5,
59
76
  span: 2,
60
77
  },
61
- {
62
- sectionId: "recent",
63
- id: "quick-actions",
64
- type: "quickActions",
65
- label: "Quick Actions",
66
- actions: [
67
- {
68
- label: "New Post",
69
- action: { type: "create", collection: "posts" },
70
- },
71
- {
72
- label: "Site Settings",
73
- action: {
74
- type: "link",
75
- href: "/admin/globals/siteSettings",
76
- },
77
- },
78
- ],
79
- span: 2,
80
- },
81
78
  ],
82
79
  },
83
80
  });
@@ -0,0 +1,138 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as AdminRouteImport } from './routes/admin'
13
+ import { Route as AdminIndexRouteImport } from './routes/admin/index'
14
+ import { Route as ApiSplatRouteImport } from './routes/api/$'
15
+ import { Route as AdminLoginRouteImport } from './routes/admin/login'
16
+ import { Route as AdminSplatRouteImport } from './routes/admin/$'
17
+
18
+ const AdminRoute = AdminRouteImport.update({
19
+ id: '/admin',
20
+ path: '/admin',
21
+ getParentRoute: () => rootRouteImport,
22
+ } as any)
23
+ const AdminIndexRoute = AdminIndexRouteImport.update({
24
+ id: '/',
25
+ path: '/',
26
+ getParentRoute: () => AdminRoute,
27
+ } as any)
28
+ const ApiSplatRoute = ApiSplatRouteImport.update({
29
+ id: '/api/$',
30
+ path: '/api/$',
31
+ getParentRoute: () => rootRouteImport,
32
+ } as any)
33
+ const AdminLoginRoute = AdminLoginRouteImport.update({
34
+ id: '/login',
35
+ path: '/login',
36
+ getParentRoute: () => AdminRoute,
37
+ } as any)
38
+ const AdminSplatRoute = AdminSplatRouteImport.update({
39
+ id: '/$',
40
+ path: '/$',
41
+ getParentRoute: () => AdminRoute,
42
+ } as any)
43
+
44
+ export interface FileRoutesByFullPath {
45
+ '/admin': typeof AdminRouteWithChildren
46
+ '/admin/$': typeof AdminSplatRoute
47
+ '/admin/login': typeof AdminLoginRoute
48
+ '/api/$': typeof ApiSplatRoute
49
+ '/admin/': typeof AdminIndexRoute
50
+ }
51
+ export interface FileRoutesByTo {
52
+ '/admin/$': typeof AdminSplatRoute
53
+ '/admin/login': typeof AdminLoginRoute
54
+ '/api/$': typeof ApiSplatRoute
55
+ '/admin': typeof AdminIndexRoute
56
+ }
57
+ export interface FileRoutesById {
58
+ __root__: typeof rootRouteImport
59
+ '/admin': typeof AdminRouteWithChildren
60
+ '/admin/$': typeof AdminSplatRoute
61
+ '/admin/login': typeof AdminLoginRoute
62
+ '/api/$': typeof ApiSplatRoute
63
+ '/admin/': typeof AdminIndexRoute
64
+ }
65
+ export interface FileRouteTypes {
66
+ fileRoutesByFullPath: FileRoutesByFullPath
67
+ fullPaths: '/admin' | '/admin/$' | '/admin/login' | '/api/$' | '/admin/'
68
+ fileRoutesByTo: FileRoutesByTo
69
+ to: '/admin/$' | '/admin/login' | '/api/$' | '/admin'
70
+ id: '__root__' | '/admin' | '/admin/$' | '/admin/login' | '/api/$' | '/admin/'
71
+ fileRoutesById: FileRoutesById
72
+ }
73
+ export interface RootRouteChildren {
74
+ AdminRoute: typeof AdminRouteWithChildren
75
+ ApiSplatRoute: typeof ApiSplatRoute
76
+ }
77
+
78
+ declare module '@tanstack/react-router' {
79
+ interface FileRoutesByPath {
80
+ '/admin': {
81
+ id: '/admin'
82
+ path: '/admin'
83
+ fullPath: '/admin'
84
+ preLoaderRoute: typeof AdminRouteImport
85
+ parentRoute: typeof rootRouteImport
86
+ }
87
+ '/admin/': {
88
+ id: '/admin/'
89
+ path: '/'
90
+ fullPath: '/admin/'
91
+ preLoaderRoute: typeof AdminIndexRouteImport
92
+ parentRoute: typeof AdminRoute
93
+ }
94
+ '/api/$': {
95
+ id: '/api/$'
96
+ path: '/api/$'
97
+ fullPath: '/api/$'
98
+ preLoaderRoute: typeof ApiSplatRouteImport
99
+ parentRoute: typeof rootRouteImport
100
+ }
101
+ '/admin/login': {
102
+ id: '/admin/login'
103
+ path: '/login'
104
+ fullPath: '/admin/login'
105
+ preLoaderRoute: typeof AdminLoginRouteImport
106
+ parentRoute: typeof AdminRoute
107
+ }
108
+ '/admin/$': {
109
+ id: '/admin/$'
110
+ path: '/$'
111
+ fullPath: '/admin/$'
112
+ preLoaderRoute: typeof AdminSplatRouteImport
113
+ parentRoute: typeof AdminRoute
114
+ }
115
+ }
116
+ }
117
+
118
+ interface AdminRouteChildren {
119
+ AdminSplatRoute: typeof AdminSplatRoute
120
+ AdminLoginRoute: typeof AdminLoginRoute
121
+ AdminIndexRoute: typeof AdminIndexRoute
122
+ }
123
+
124
+ const AdminRouteChildren: AdminRouteChildren = {
125
+ AdminSplatRoute: AdminSplatRoute,
126
+ AdminLoginRoute: AdminLoginRoute,
127
+ AdminIndexRoute: AdminIndexRoute,
128
+ }
129
+
130
+ const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren)
131
+
132
+ const rootRouteChildren: RootRouteChildren = {
133
+ AdminRoute: AdminRouteWithChildren,
134
+ ApiSplatRoute: ApiSplatRoute,
135
+ }
136
+ export const routeTree = rootRouteImport
137
+ ._addFileChildren(rootRouteChildren)
138
+ ._addFileTypes<FileRouteTypes>()
@@ -1,5 +1,3 @@
1
- import "virtual:iconify-preload";
2
-
3
1
  import { createRootRoute } from "@tanstack/react-router";
4
2
 
5
3
  export const Route = createRootRoute({
@@ -1,17 +1,28 @@
1
1
  import { createFileRoute, useNavigate } from "@tanstack/react-router";
2
+ import { useMemo } from "react";
2
3
 
3
4
  import { AdminRouter } from "@questpie/admin/client";
4
5
 
6
+ function createAdminNavigate(navigate: ReturnType<typeof useNavigate>) {
7
+ return (path: string) => {
8
+ void navigate({ to: path });
9
+ };
10
+ }
11
+
5
12
  function AdminCatchAll() {
6
13
  const navigate = useNavigate();
7
14
  const params = Route.useParams();
8
15
  const splat = params._splat as string;
16
+ const handleNavigate = useMemo(
17
+ () => createAdminNavigate(navigate),
18
+ [navigate],
19
+ );
9
20
  const segments = splat ? splat.split("/").filter(Boolean) : [];
10
21
 
11
22
  return (
12
23
  <AdminRouter
13
24
  segments={segments}
14
- navigate={(path) => navigate({ to: path })}
25
+ navigate={handleNavigate}
15
26
  basePath="/admin"
16
27
  />
17
28
  );
@@ -1,16 +1,23 @@
1
1
  import { createFileRoute, useNavigate } from "@tanstack/react-router";
2
+ import { useMemo } from "react";
2
3
 
3
4
  import { AdminRouter } from "@questpie/admin/client";
4
5
 
6
+ function createAdminNavigate(navigate: ReturnType<typeof useNavigate>) {
7
+ return (path: string) => {
8
+ void navigate({ to: path });
9
+ };
10
+ }
11
+
5
12
  function AdminDashboard() {
6
13
  const navigate = useNavigate();
14
+ const handleNavigate = useMemo(
15
+ () => createAdminNavigate(navigate),
16
+ [navigate],
17
+ );
7
18
 
8
19
  return (
9
- <AdminRouter
10
- segments={[]}
11
- navigate={(path) => navigate({ to: path })}
12
- basePath="/admin"
13
- />
20
+ <AdminRouter segments={[]} navigate={handleNavigate} basePath="/admin" />
14
21
  );
15
22
  }
16
23
 
@@ -20,14 +20,21 @@ function AdminLink({
20
20
  className,
21
21
  children,
22
22
  activeProps,
23
+ activeOptions,
23
24
  }: {
24
25
  to: string;
25
26
  className?: string;
26
27
  children: React.ReactNode;
27
28
  activeProps?: { className?: string };
29
+ activeOptions?: { exact?: boolean };
28
30
  }) {
29
31
  return (
30
- <Link to={to} className={className} activeProps={activeProps}>
32
+ <Link
33
+ to={to}
34
+ className={className}
35
+ activeProps={activeProps}
36
+ activeOptions={activeOptions}
37
+ >
31
38
  {children}
32
39
  </Link>
33
40
  );
@@ -0,0 +1 @@
1
+ import "@tanstack/react-start";
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -1,4 +1,3 @@
1
- import { iconifyPreload } from "@questpie/vite-plugin-iconify";
2
1
  import tailwindcss from "@tailwindcss/vite";
3
2
  import { devtools } from "@tanstack/devtools-vite";
4
3
  import { tanstackStart } from "@tanstack/react-start/plugin/vite";
@@ -9,7 +8,6 @@ import viteTsConfigPaths from "vite-tsconfig-paths";
9
8
 
10
9
  export default defineConfig({
11
10
  plugins: [
12
- iconifyPreload(),
13
11
  devtools(),
14
12
  nitro({ preset: "bun" }) as any,
15
13
  viteTsConfigPaths({ projects: ["./tsconfig.json"] }),
@@ -22,7 +20,7 @@ export default defineConfig({
22
20
  },
23
21
  build: {
24
22
  rollupOptions: {
25
- external: ["bun", /^drizzle-kit/],
23
+ external: ["bun", /^drizzle-kit/, /^@aws-sdk\//],
26
24
  },
27
25
  },
28
26
  });