@ghentcdh/crouton-core 0.0.1-alpha.82 → 0.0.1-alpha.83
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.
- package/agent-docs/1.getting-started/index.md +194 -0
- package/agent-docs/1.getting-started/manual-setup.md +478 -0
- package/agent-docs/1.getting-started/project-structure.md +59 -0
- package/agent-docs/2.resources/actions.md +143 -0
- package/agent-docs/2.resources/columns.md +278 -0
- package/agent-docs/2.resources/custom-resource.md +465 -0
- package/agent-docs/2.resources/extensions.md +187 -0
- package/agent-docs/2.resources/field-inputs/array.md +5 -0
- package/agent-docs/2.resources/field-inputs/autocomplete.md +42 -0
- package/agent-docs/2.resources/field-inputs/boolean.md +5 -0
- package/agent-docs/2.resources/field-inputs/common-options.md +5 -0
- package/agent-docs/2.resources/field-inputs/custom.md +87 -0
- package/agent-docs/2.resources/field-inputs/date-range.md +5 -0
- package/agent-docs/2.resources/field-inputs/date.md +5 -0
- package/agent-docs/2.resources/field-inputs/index.md +40 -0
- package/agent-docs/2.resources/field-inputs/markdown.md +5 -0
- package/agent-docs/2.resources/field-inputs/number.md +5 -0
- package/agent-docs/2.resources/field-inputs/relation.md +5 -0
- package/agent-docs/2.resources/field-inputs/select.md +20 -0
- package/agent-docs/2.resources/field-inputs/string.md +5 -0
- package/agent-docs/2.resources/field-inputs/textarea.md +5 -0
- package/agent-docs/2.resources/field-inputs/toggle.md +20 -0
- package/agent-docs/2.resources/hooks.md +203 -0
- package/agent-docs/2.resources/index.md +212 -0
- package/agent-docs/2.resources/layout.md +362 -0
- package/agent-docs/2.resources/operations.md +210 -0
- package/agent-docs/2.resources/relations.md +155 -0
- package/agent-docs/2.resources/security.md +158 -0
- package/agent-docs/2.resources/unique.md +90 -0
- package/agent-docs/2.resources/versioning.md +154 -0
- package/agent-docs/3.backend/data-sources.md +210 -0
- package/agent-docs/3.backend/index.md +117 -0
- package/agent-docs/3.backend/status.md +219 -0
- package/agent-docs/4.frontend/croutonform.md +172 -0
- package/agent-docs/4.frontend/custom-renderers.md +230 -0
- package/agent-docs/4.frontend/index.md +151 -0
- package/agent-docs/4.frontend/modals-and-relations.md +64 -0
- package/agent-docs/4.frontend/styling.md +82 -0
- package/agent-docs/4.frontend/translations.md +298 -0
- package/agent-docs/4.frontend/use-crouton.md +143 -0
- package/agent-docs/5.tooling/cli.md +225 -0
- package/agent-docs/5.tooling/migrate.md +50 -0
- package/agent-docs/5.tooling/resource-editor.md +59 -0
- package/agent-docs/5.tooling/validator.md +21 -0
- package/agent-docs/6.recipes/add-enum-select.md +113 -0
- package/agent-docs/6.recipes/add-relation.md +146 -0
- package/agent-docs/6.recipes/add-resource.md +104 -0
- package/agent-docs/6.recipes/common-mistakes.md +118 -0
- package/agent-docs/6.recipes/config-only-resource.md +131 -0
- package/agent-docs/6.recipes/custom-field-input.md +141 -0
- package/agent-docs/6.recipes/decision-tables.md +53 -0
- package/agent-docs/README.md +65 -0
- package/agent-docs/components/index.md +9 -0
- package/agent-docs/reference/crouton-json.md +69 -0
- package/agent-docs/reference/endpoints.md +75 -0
- package/agent-docs/reference/enums.md +85 -0
- package/agent-docs/reference/normalize-schema.md +98 -0
- package/agent-docs/reference/packages.md +48 -0
- package/agent-docs/reference/parse-schema.md +103 -0
- package/dist/crouton.schema.json +936 -0
- package/dist/datasource.schema.json +84 -0
- package/dist/field-input-schemas/array.field-input.schema.json +24 -12
- package/dist/field-input-schemas/array.field-input.schema.v1.json +24 -12
- package/dist/field-input-schemas/autocomplete.field-input.schema.json +2 -1
- package/dist/field-input-schemas/autocomplete.field-input.schema.v1.json +2 -1
- package/dist/field-input-schemas/boolean.field-input.schema.json +18 -9
- package/dist/field-input-schemas/boolean.field-input.schema.v1.json +18 -9
- package/dist/field-input-schemas/custom.field-input.schema.json +18 -9
- package/dist/field-input-schemas/custom.field-input.schema.v1.json +18 -9
- package/dist/field-input-schemas/date-range.field-input.schema.json +26 -13
- package/dist/field-input-schemas/date-range.field-input.schema.v1.json +26 -13
- package/dist/field-input-schemas/date.field-input.schema.json +28 -14
- package/dist/field-input-schemas/date.field-input.schema.v1.json +28 -14
- package/dist/field-input-schemas/markdown.field-input.schema.json +20 -10
- package/dist/field-input-schemas/markdown.field-input.schema.v1.json +20 -10
- package/dist/field-input-schemas/number.field-input.schema.json +18 -9
- package/dist/field-input-schemas/number.field-input.schema.v1.json +18 -9
- package/dist/field-input-schemas/relation.field-input.schema.json +28 -14
- package/dist/field-input-schemas/relation.field-input.schema.v1.json +28 -14
- package/dist/field-input-schemas/select.field-input.schema.json +36 -18
- package/dist/field-input-schemas/select.field-input.schema.v1.json +36 -18
- package/dist/field-input-schemas/string.field-input.schema.json +20 -10
- package/dist/field-input-schemas/string.field-input.schema.v1.json +20 -10
- package/dist/field-input-schemas/textarea.field-input.schema.json +18 -9
- package/dist/field-input-schemas/textarea.field-input.schema.v1.json +18 -9
- package/dist/field-input-schemas/toggle.field-input.schema.json +34 -17
- package/dist/field-input-schemas/toggle.field-input.schema.v1.json +34 -17
- package/dist/index.cjs +2679 -1777
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4610 -3217
- package/dist/index.d.ts +4610 -3217
- package/dist/index.js +2618 -1767
- package/dist/index.js.map +1 -1
- package/dist/resource.schema.json +1801 -976
- package/dist/resource.schema.v1.json +1801 -976
- package/package.json +3 -2
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold a new Crouton project with create-crouton, or add Crouton to an existing NestJS + Vue app using add-crouton.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Getting started
|
|
6
|
+
|
|
7
|
+
> Last verified against crouton `0.0.1-alpha.81`
|
|
8
|
+
|
|
9
|
+
Two ways to start with crouton: **create a new project** from scratch, or **add crouton** to an existing one.
|
|
10
|
+
|
|
11
|
+
## @ghentcdh/create-crouton
|
|
12
|
+
|
|
13
|
+
Scaffold a complete crouton project — a NestJS backend with Prisma, pre-configured datasource, Docker Compose, and optionally an Nx monorepo layout with a Vue frontend.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm create @ghentcdh/crouton my-app
|
|
17
|
+
# or
|
|
18
|
+
npx @ghentcdh/create-crouton my-app
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Local development
|
|
22
|
+
|
|
23
|
+
To test a locally built version of the CLI:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
# Build and link globally
|
|
27
|
+
pnpm nx build create-crouton
|
|
28
|
+
pnpm link ./packages/create-crouton --global
|
|
29
|
+
|
|
30
|
+
# Now use it anywhere
|
|
31
|
+
create-crouton my-test-app --prefix split
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or run directly without linking:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
pnpm nx build create-crouton
|
|
38
|
+
node packages/create-crouton/dist/index.js my-test-app
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Flags
|
|
42
|
+
|
|
43
|
+
| Flag | Default | Description |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `--nx` | prompt | Use Nx monorepo layout (backend + frontend + shared libs). |
|
|
46
|
+
| `--no-nx` | — | Skip Nx layout (scaffold a regular single-app project). |
|
|
47
|
+
| `--no-frontend` | — | Skip Vue frontend generation (Nx layout only). |
|
|
48
|
+
| `--no-postgres` | — | Skip PostgreSQL setup (Prisma schema, adapter, Docker). |
|
|
49
|
+
| `--sample` | — | Include a sample resource. |
|
|
50
|
+
| `--pm <manager>` | prompt | Package manager: `pnpm`, `npm`, `yarn`, or `bun`. |
|
|
51
|
+
| `--no-install` | — | Skip dependency installation. |
|
|
52
|
+
| `--no-git` | — | Skip `git init`. |
|
|
53
|
+
| `--no-docker` | — | Skip Docker files (Dockerfile, compose.yml). |
|
|
54
|
+
| `--prefix <name>` | prompt | Subfolder prefix for apps/config (e.g. `split`). Implies Nx layout. |
|
|
55
|
+
| `--db-url <url>` | prompt | Database connection URL. |
|
|
56
|
+
| `-y, --yes` | — | Accept all defaults (non-interactive). |
|
|
57
|
+
| `--force` | — | Overwrite existing files. |
|
|
58
|
+
|
|
59
|
+
### Layouts
|
|
60
|
+
|
|
61
|
+
#### Regular (single app)
|
|
62
|
+
|
|
63
|
+
A standalone NestJS backend — best for APIs, small projects, or when you already have a separate frontend.
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
my-app/
|
|
67
|
+
├── src/
|
|
68
|
+
│ ├── main.ts
|
|
69
|
+
│ ├── app.module.ts
|
|
70
|
+
│ ├── data-sources/default/
|
|
71
|
+
│ │ ├── data-source.json
|
|
72
|
+
│ │ └── index.ts
|
|
73
|
+
│ └── resources/ # generated by `crouton update resources`
|
|
74
|
+
├── prisma/default/
|
|
75
|
+
│ ├── schema.prisma
|
|
76
|
+
│ └── prisma.config.ts
|
|
77
|
+
├── crouton.json
|
|
78
|
+
├── crouton.enums.json
|
|
79
|
+
├── package.json
|
|
80
|
+
├── compose.yml
|
|
81
|
+
└── .env
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Nx monorepo
|
|
85
|
+
|
|
86
|
+
A full-stack workspace with separate backend and frontend apps, shared generated types, and workspace-level tooling.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
my-app/
|
|
90
|
+
├── apps/
|
|
91
|
+
│ ├── backend/
|
|
92
|
+
│ │ ├── src/
|
|
93
|
+
│ │ │ ├── main.ts
|
|
94
|
+
│ │ │ └── app/
|
|
95
|
+
│ │ │ ├── app.module.ts
|
|
96
|
+
│ │ │ ├── data-sources/default/
|
|
97
|
+
│ │ │ └── resources/
|
|
98
|
+
│ │ └── package.json
|
|
99
|
+
│ └── frontend/ # Vue + Vite (skipped with --no-frontend)
|
|
100
|
+
│ ├── src/
|
|
101
|
+
│ │ ├── main.ts
|
|
102
|
+
│ │ └── App.vue
|
|
103
|
+
│ └── package.json
|
|
104
|
+
├── generated/default/
|
|
105
|
+
│ ├── types/ # crouton-prisma zod output
|
|
106
|
+
│ └── client/ # Prisma client output
|
|
107
|
+
├── prisma/default/
|
|
108
|
+
├── crouton.json
|
|
109
|
+
├── nx.json
|
|
110
|
+
├── pnpm-workspace.yaml
|
|
111
|
+
└── package.json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Nx monorepo with prefix
|
|
115
|
+
|
|
116
|
+
When using `--prefix split`, apps and generated code live under a subfolder. This is useful when the Nx workspace also contains non-crouton projects.
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
my-app/
|
|
120
|
+
├── split/
|
|
121
|
+
│ ├── apps/
|
|
122
|
+
│ │ ├── backend/
|
|
123
|
+
│ │ └── frontend/
|
|
124
|
+
│ ├── generated/default/
|
|
125
|
+
│ │ ├── types/
|
|
126
|
+
│ │ └── client/
|
|
127
|
+
│ ├── prisma/default/
|
|
128
|
+
│ └── crouton.json
|
|
129
|
+
├── nx.json
|
|
130
|
+
├── tsconfig.base.json
|
|
131
|
+
├── pnpm-workspace.yaml
|
|
132
|
+
└── package.json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### What happens after scaffolding
|
|
136
|
+
|
|
137
|
+
The CLI runs these steps automatically (unless skipped via flags):
|
|
138
|
+
|
|
139
|
+
1. **`git init`** — initialises a repository with an initial commit.
|
|
140
|
+
2. **`<pm> install`** — installs all dependencies.
|
|
141
|
+
3. **`crouton update resources`** — introspects the database and generates resource CRUD (best-effort; warns on failure if DB is not running).
|
|
142
|
+
|
|
143
|
+
Then follow the printed next-steps:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
docker compose up -d # start postgres
|
|
147
|
+
pnpm prisma:migrate # create initial migration
|
|
148
|
+
crouton update resources # generate resource CRUD from your schema
|
|
149
|
+
pnpm dev # start dev server
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
When using a prefix, add the `--prefix` flag:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
crouton update resources --prefix split
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## @ghentcdh/add-crouton
|
|
159
|
+
|
|
160
|
+
Add crouton to an **existing** NestJS project — regular or Nx. This command is additive: it never overwrites existing files.
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
npx @ghentcdh/add-crouton
|
|
164
|
+
# or from outside the project:
|
|
165
|
+
npx @ghentcdh/add-crouton --cwd /path/to/project
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Flags
|
|
169
|
+
|
|
170
|
+
| Flag | Default | Description |
|
|
171
|
+
| --- | --- | --- |
|
|
172
|
+
| `--cwd <dir>` | `.` | Project directory. |
|
|
173
|
+
| `--backend <app>` | auto-detect | Backend app name (Nx only). |
|
|
174
|
+
| `--frontend <app>` | auto-detect | Frontend app name (Nx only). |
|
|
175
|
+
| `--no-frontend` | — | Skip frontend detection. |
|
|
176
|
+
| `--pm <manager>` | auto-detect | Package manager. |
|
|
177
|
+
| `--no-install` | — | Skip dependency installation. |
|
|
178
|
+
| `--no-docker` | — | Skip Docker file generation. |
|
|
179
|
+
| `-y, --yes` | — | Accept all defaults (non-interactive). |
|
|
180
|
+
|
|
181
|
+
### What it does
|
|
182
|
+
|
|
183
|
+
1. **Detects project type** — checks for `nx.json` at or above the current directory to distinguish Nx workspaces from regular projects.
|
|
184
|
+
2. **Discovers apps** (Nx only) — scans `apps/` subdirs, classifies them as backend (`@nestjs/core` in deps) or frontend (`vue`/`vite` in deps), and prompts which to use.
|
|
185
|
+
3. **Detects package manager** — from lockfile presence (pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lockb).
|
|
186
|
+
4. **Scans dependencies** — reports missing backend deps (`@ghentcdh/crouton-api`, `@ghentcdh/crouton-core`, `prisma`, etc.).
|
|
187
|
+
5. **Writes config files** (if absent):
|
|
188
|
+
- `crouton.json` — with detected `resourcesDir` and `dataSourcesDir`
|
|
189
|
+
- `crouton.enums.json` — empty enum registry
|
|
190
|
+
- `data-sources/default/` — default datasource with Prisma schema and config
|
|
191
|
+
- `.env.example` — with `DATABASE_URL` placeholder
|
|
192
|
+
6. **Installs dependencies** — runs `<pm> install` if missing deps were detected.
|
|
193
|
+
|
|
194
|
+
After running `@ghentcdh/add-crouton`, wire `CroutonApiModule` into your NestJS app module — see [Backend setup](backend.md).
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Step-by-step guide to add Crouton to an existing NestJS project without using the CLI scaffolding tools.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Manual setup
|
|
6
|
+
|
|
7
|
+
Add crouton to an existing NestJS project without using the CLI scaffolding tools (`create-crouton` or `add-crouton`).
|
|
8
|
+
|
|
9
|
+
## 1. Install dependencies
|
|
10
|
+
|
|
11
|
+
### Backend
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
# Runtime
|
|
15
|
+
pnpm add @ghentcdh/crouton-api @prisma/adapter-pg @prisma/client dotenv tslib zod
|
|
16
|
+
|
|
17
|
+
# Dev
|
|
18
|
+
pnpm add -D @ghentcdh/crouton-cli @ghentcdh/crouton-prisma prisma
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Frontend (optional, Vue 3)
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pnpm add @ghentcdh/crouton-vue vue
|
|
25
|
+
pnpm add -D vite @vitejs/plugin-vue
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 2. Create the project config
|
|
29
|
+
|
|
30
|
+
### crouton.json
|
|
31
|
+
|
|
32
|
+
Create `crouton.json` at the project root (or workspace root for Nx):
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"title": "My App",
|
|
37
|
+
"resourcesDir": "src/app/resources",
|
|
38
|
+
"dataSourcesDir": "src/app/data-sources",
|
|
39
|
+
"enumsFile": "crouton.enums.json"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For Nx monorepos with apps in subdirectories, adjust paths accordingly:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"title": "My App",
|
|
48
|
+
"resourcesDir": "apps/backend/src/app/resources",
|
|
49
|
+
"dataSourcesDir": "apps/backend/src/app/data-sources",
|
|
50
|
+
"enumsFile": "crouton.enums.json"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### crouton.enums.json
|
|
55
|
+
|
|
56
|
+
Create an empty enum registry:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 3. Set up a data source
|
|
63
|
+
|
|
64
|
+
### Prisma schema
|
|
65
|
+
|
|
66
|
+
Create `prisma/default/schema.prisma`:
|
|
67
|
+
|
|
68
|
+
```prisma
|
|
69
|
+
generator client {
|
|
70
|
+
provider = "prisma-client-js"
|
|
71
|
+
output = "../../generated/default/client/src"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
generator crouton {
|
|
75
|
+
provider = "crouton-prisma"
|
|
76
|
+
zodOutput = "../../generated/default/types/src"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
datasource db {
|
|
80
|
+
provider = "postgresql"
|
|
81
|
+
// url is provided by prisma.config.ts (Prisma 7 forbids url here)
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Prisma config
|
|
86
|
+
|
|
87
|
+
Create `prisma/default/prisma.config.ts`:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import 'dotenv/config';
|
|
91
|
+
import { defineConfig, env } from 'prisma/config';
|
|
92
|
+
|
|
93
|
+
export default defineConfig({
|
|
94
|
+
schema: 'prisma/default/schema.prisma',
|
|
95
|
+
migrations: {
|
|
96
|
+
path: 'prisma/default/migrations',
|
|
97
|
+
},
|
|
98
|
+
datasource: {
|
|
99
|
+
url: env('DATABASE_URL'),
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Data source folder
|
|
105
|
+
|
|
106
|
+
Create `src/app/data-sources/default/data-source.json`:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"type": "postgres",
|
|
111
|
+
"name": "default",
|
|
112
|
+
"default": true,
|
|
113
|
+
"prismaSchema": "prisma/default/schema.prisma",
|
|
114
|
+
"urlEnv": "DATABASE_URL",
|
|
115
|
+
"generatedTypesImport": "@my-app/generated/default/types",
|
|
116
|
+
"zodOutput": "generated/default/types/src",
|
|
117
|
+
"prismaConfig": "prisma/default/prisma.config.ts"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Create `src/app/data-sources/default/index.ts`:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { PrismaClient } from '../../generated/default/client/src';
|
|
125
|
+
import { PrismaPg } from '@prisma/adapter-pg';
|
|
126
|
+
|
|
127
|
+
const adapter = new PrismaPg({
|
|
128
|
+
connectionString: process.env.DATABASE_URL,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const client = new PrismaClient({ adapter });
|
|
132
|
+
|
|
133
|
+
export default client;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 4. Configure TypeScript paths
|
|
137
|
+
|
|
138
|
+
### Standalone project
|
|
139
|
+
|
|
140
|
+
In `tsconfig.json`, add path aliases for the generated types and client:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"compilerOptions": {
|
|
145
|
+
"paths": {
|
|
146
|
+
"@my-app/generated/default/types": [
|
|
147
|
+
"./generated/default/types/src"
|
|
148
|
+
],
|
|
149
|
+
"@my-app/generated/default/client": [
|
|
150
|
+
"./generated/default/client/src"
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Nx monorepo
|
|
158
|
+
|
|
159
|
+
In `tsconfig.base.json` at the workspace root:
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"compilerOptions": {
|
|
164
|
+
"baseUrl": ".",
|
|
165
|
+
"paths": {
|
|
166
|
+
"@my-app/generated/default/types": [
|
|
167
|
+
"./generated/default/types/src"
|
|
168
|
+
],
|
|
169
|
+
"@my-app/generated/default/client": [
|
|
170
|
+
"./generated/default/client/src"
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
If using a prefix subfolder (e.g. `split`), adjust the paths:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"compilerOptions": {
|
|
182
|
+
"paths": {
|
|
183
|
+
"@my-app/generated/default/types": [
|
|
184
|
+
"./split/generated/default/types/src"
|
|
185
|
+
],
|
|
186
|
+
"@my-app/generated/default/client": [
|
|
187
|
+
"./split/generated/default/client/src"
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 5. Register the NestJS module
|
|
195
|
+
|
|
196
|
+
In your app module:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import { resolve } from 'node:path';
|
|
200
|
+
import { Module } from '@nestjs/common';
|
|
201
|
+
import { ConfigModule } from '@nestjs/config';
|
|
202
|
+
import { CroutonApiModule } from '@ghentcdh/crouton-api';
|
|
203
|
+
|
|
204
|
+
@Module({
|
|
205
|
+
imports: [
|
|
206
|
+
ConfigModule.forRoot({ isGlobal: true, envFilePath: ['.env.local', '.env'] }),
|
|
207
|
+
CroutonApiModule.forResourceDir(
|
|
208
|
+
resolve(__dirname, 'resources'),
|
|
209
|
+
resolve(__dirname, 'data-sources'),
|
|
210
|
+
{
|
|
211
|
+
baseUrl: '/api',
|
|
212
|
+
title: 'My App',
|
|
213
|
+
enumsFile: resolve(__dirname, '..', '..', 'crouton.enums.json'),
|
|
214
|
+
},
|
|
215
|
+
),
|
|
216
|
+
],
|
|
217
|
+
})
|
|
218
|
+
export class AppModule {
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 6. Environment file
|
|
223
|
+
|
|
224
|
+
Create `.env`:
|
|
225
|
+
|
|
226
|
+
```env
|
|
227
|
+
DATABASE_URL=postgresql://crouton:crouton@localhost:5432/my_app?schema=public
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## 7. Generate Prisma client and types
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
npx prisma migrate dev --config prisma/default/prisma.config.ts
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
This creates the initial migration, generates the Prisma client, and runs `crouton-prisma` (which normalizes the schema and generates Zod types).
|
|
237
|
+
|
|
238
|
+
## 8. Generate resources
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
npx crouton update resources
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
For Nx workspaces with a prefix subfolder:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
npx crouton update resources --prefix split
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
This introspects your database, lets you pick which models to expose, and generates `resource.json` + `schema.ts` files
|
|
251
|
+
per resource.
|
|
252
|
+
|
|
253
|
+
### CLI flags
|
|
254
|
+
|
|
255
|
+
| Flag | Description |
|
|
256
|
+
|---------------------------|------------------------------------------------------|
|
|
257
|
+
| `-d, --datasource <name>` | Datasource to use (from crouton.config). |
|
|
258
|
+
| `-m, --models <list>` | Comma-separated models to limit to. |
|
|
259
|
+
| `--cwd <dir>` | Project directory (defaults to cwd). |
|
|
260
|
+
| `--prefix <name>` | Subfolder prefix (resolves cwd to `<cwd>/<prefix>`). |
|
|
261
|
+
| `--dry-run` | Show planned changes without writing files. |
|
|
262
|
+
| `-y, --yes` | Accept all defaults (non-interactive). |
|
|
263
|
+
| `--skip-pull` | Do not run `prisma db pull`. |
|
|
264
|
+
| `--skip-generate` | Do not run `prisma generate` after pulling. |
|
|
265
|
+
|
|
266
|
+
## 9. Frontend app (Vue 3)
|
|
267
|
+
|
|
268
|
+
### Install dependencies
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
pnpm add @ghentcdh/crouton-vue axios vue vue-router
|
|
272
|
+
pnpm add -D vite @vitejs/plugin-vue @types/node typescript
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### index.html
|
|
276
|
+
|
|
277
|
+
```html
|
|
278
|
+
<!DOCTYPE html>
|
|
279
|
+
<html lang="en">
|
|
280
|
+
<head>
|
|
281
|
+
<meta charset="UTF-8" />
|
|
282
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
283
|
+
<title>My App</title>
|
|
284
|
+
</head>
|
|
285
|
+
<body>
|
|
286
|
+
<div id="app"></div>
|
|
287
|
+
<script type="module" src="/src/main.ts"></script>
|
|
288
|
+
</body>
|
|
289
|
+
</html>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### API client
|
|
293
|
+
|
|
294
|
+
Create `src/api.ts`:
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
import axios from 'axios';
|
|
298
|
+
|
|
299
|
+
export const api = axios.create({
|
|
300
|
+
baseURL: '/api',
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Entry point
|
|
305
|
+
|
|
306
|
+
Create `src/main.ts`:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { createApp } from 'vue';
|
|
310
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
311
|
+
import { CroutonPlugin, CroutonRouter } from '@ghentcdh/crouton-vue';
|
|
312
|
+
import '@ghentcdh/crouton-vue/styles.css';
|
|
313
|
+
import { api } from './api';
|
|
314
|
+
import App from './App.vue';
|
|
315
|
+
|
|
316
|
+
const router = createRouter({
|
|
317
|
+
history: createWebHistory(),
|
|
318
|
+
routes: [
|
|
319
|
+
{
|
|
320
|
+
path: '/',
|
|
321
|
+
name: 'admin',
|
|
322
|
+
children: [...CroutonRouter],
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
const app = createApp(App);
|
|
328
|
+
app.use(CroutonPlugin(api, { title: 'My App', router }));
|
|
329
|
+
app.use(router);
|
|
330
|
+
app.mount('#app');
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### App component
|
|
334
|
+
|
|
335
|
+
Create `src/App.vue`:
|
|
336
|
+
|
|
337
|
+
```vue
|
|
338
|
+
|
|
339
|
+
<template>
|
|
340
|
+
<router-view />
|
|
341
|
+
</template>
|
|
342
|
+
|
|
343
|
+
<script setup lang="ts">
|
|
344
|
+
</script>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Vite config
|
|
348
|
+
|
|
349
|
+
Create `vite.config.ts`:
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
import { defineConfig } from 'vite';
|
|
353
|
+
import vue from '@vitejs/plugin-vue';
|
|
354
|
+
|
|
355
|
+
export default defineConfig({
|
|
356
|
+
plugins: [vue()],
|
|
357
|
+
server: {
|
|
358
|
+
port: 4200,
|
|
359
|
+
proxy: {
|
|
360
|
+
'/api': {
|
|
361
|
+
target: 'http://localhost:3000',
|
|
362
|
+
changeOrigin: true,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The proxy forwards `/api` requests to the NestJS backend during development.
|
|
370
|
+
|
|
371
|
+
### Frontend tsconfig.json (Nx only)
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"extends": "../../tsconfig.base.json",
|
|
376
|
+
"compilerOptions": {
|
|
377
|
+
"outDir": "./dist",
|
|
378
|
+
"rootDir": "./src",
|
|
379
|
+
"jsx": "preserve",
|
|
380
|
+
"jsxImportSource": "vue"
|
|
381
|
+
},
|
|
382
|
+
"include": [
|
|
383
|
+
"src/**/*.ts",
|
|
384
|
+
"src/**/*.vue"
|
|
385
|
+
],
|
|
386
|
+
"exclude": [
|
|
387
|
+
"node_modules",
|
|
388
|
+
"dist"
|
|
389
|
+
]
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## 10. Start the dev server
|
|
394
|
+
|
|
395
|
+
```sh
|
|
396
|
+
pnpm dev
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
For more frontend configuration, see [Frontend setup](frontend.md).
|
|
400
|
+
|
|
401
|
+
## Nx workspace extras
|
|
402
|
+
|
|
403
|
+
For Nx monorepos, you also need:
|
|
404
|
+
|
|
405
|
+
### pnpm-workspace.yaml
|
|
406
|
+
|
|
407
|
+
```yaml
|
|
408
|
+
packages:
|
|
409
|
+
- apps/*
|
|
410
|
+
- generated/default/*
|
|
411
|
+
- libs/*
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### nx.json
|
|
415
|
+
|
|
416
|
+
```json
|
|
417
|
+
{
|
|
418
|
+
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
|
419
|
+
"defaultBase": "main"
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Backend tsconfig.json
|
|
424
|
+
|
|
425
|
+
Backend app tsconfigs should extend the base:
|
|
426
|
+
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"extends": "../../tsconfig.base.json",
|
|
430
|
+
"compilerOptions": {
|
|
431
|
+
"module": "commonjs",
|
|
432
|
+
"moduleResolution": "node",
|
|
433
|
+
"emitDecoratorMetadata": true,
|
|
434
|
+
"experimentalDecorators": true,
|
|
435
|
+
"allowSyntheticDefaultImports": true,
|
|
436
|
+
"outDir": "./dist",
|
|
437
|
+
"sourceMap": true,
|
|
438
|
+
"incremental": true,
|
|
439
|
+
"skipLibCheck": true
|
|
440
|
+
},
|
|
441
|
+
"include": [
|
|
442
|
+
"src/**/*.ts"
|
|
443
|
+
],
|
|
444
|
+
"exclude": [
|
|
445
|
+
"node_modules",
|
|
446
|
+
"dist"
|
|
447
|
+
]
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Generated package.json files
|
|
452
|
+
|
|
453
|
+
Each generated output needs a `../../../package.json` for workspace resolution:
|
|
454
|
+
|
|
455
|
+
`generated/default/types/package.json`:
|
|
456
|
+
|
|
457
|
+
```json
|
|
458
|
+
{
|
|
459
|
+
"name": "@my-app/generated-default-types",
|
|
460
|
+
"version": "0.0.1",
|
|
461
|
+
"private": true,
|
|
462
|
+
"main": "./src/index.ts",
|
|
463
|
+
"dependencies": {
|
|
464
|
+
"zod": "^4.0.0"
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
`generated/default/client/package.json`:
|
|
470
|
+
|
|
471
|
+
```json
|
|
472
|
+
{
|
|
473
|
+
"name": "@my-app/generated-default-client",
|
|
474
|
+
"version": "0.0.1",
|
|
475
|
+
"private": true,
|
|
476
|
+
"main": "./src/index.ts"
|
|
477
|
+
}
|
|
478
|
+
```
|