@fougere/cli 0.2.0-alpha.1 → 0.3.0-alpha.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.
- package/README.md +10 -1
- package/app/commands/BuildCommand.ts +39 -0
- package/app/commands/CallCommand.ts +4 -4
- package/app/commands/CheckCommand.ts +3 -2
- package/app/commands/ExplainCommand.ts +77 -0
- package/app/commands/FreezeCommand.ts +107 -0
- package/app/commands/GrantCommand.ts +44 -0
- package/app/commands/GraphCommand.ts +1 -1
- package/app/commands/KeysCommand.ts +56 -0
- package/app/commands/MigrateCommand.ts +54 -0
- package/app/commands/NewCommand.ts +6 -6
- package/app/commands/ServeCommand.ts +85 -9
- package/app/commands/grant-material.ts +5 -0
- package/dist/bin.js +54 -8
- package/dist/bin.js.map +1 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +6 -6
- package/dist/bridge.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +7 -7
- package/dist/runner.js.map +1 -1
- package/dist/theme.d.ts +10 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +10 -0
- package/dist/theme.js.map +1 -0
- package/dist/ui.d.ts +74 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +111 -0
- package/dist/ui.js.map +1 -0
- package/fronds/analysis/entities/Build.ts +7 -0
- package/fronds/analysis/entities/Explain.ts +8 -0
- package/fronds/analysis/entities/Freeze.ts +7 -0
- package/fronds/analysis/entities/Migrate.ts +7 -0
- package/fronds/analysis/handlers/BuildHandler.ts +60 -0
- package/fronds/analysis/handlers/CheckHandler.ts +61 -35
- package/fronds/analysis/handlers/ExplainHandler.ts +214 -0
- package/fronds/analysis/handlers/FreezeHandler.ts +172 -0
- package/fronds/analysis/handlers/MigrateHandler.ts +97 -0
- package/fronds/analysis/services/ProjectScan.ts +23 -7
- package/fronds/analysis/versions.ts +58 -0
- package/fronds/scaffold/entities/Grant.ts +6 -0
- package/fronds/scaffold/entities/Keys.ts +4 -0
- package/fronds/scaffold/entities/Serve.ts +2 -1
- package/fronds/scaffold/handlers/BuildFrondHandler.ts +11 -13
- package/fronds/scaffold/handlers/GrantHandler.ts +8 -0
- package/fronds/scaffold/handlers/KeysHandler.ts +8 -0
- package/fronds/scaffold/handlers/SyncHandler.ts +27 -24
- package/fronds/scaffold/services/ProjectWriter.ts +29 -10
- package/package.json +10 -8
- package/templates/admin/fronds/admin/handlers/UserHandler.ts +3 -5
- package/templates/admin/fronds/admin/package.json +1 -1
- package/templates/api/fronds/api/handlers/TaskHandler.ts +3 -5
- package/templates/api/fronds/api/package.json +1 -1
- package/templates/apps/nuxt/app/pages/index.vue +1 -1
- package/templates/apps/nuxt/package.json +1 -1
- package/templates/blog/app/pages/posts/index.vue +1 -1
- package/templates/blog/app/pages/posts/manage.vue +1 -1
- package/templates/blog/app/pages/posts/new.vue +1 -1
- package/templates/blog/fronds/blog/handlers/PostHandler.ts +3 -5
- package/templates/blog/fronds/blog/package.json +1 -1
- package/templates/flat/AGENTS.md +14 -0
- package/templates/flat/CLAUDE.md +27 -5
- package/templates/flat/package.json +1 -1
- package/templates/frond/AGENTS.md +14 -0
- package/templates/frond/CLAUDE.md +27 -5
- package/templates/frond/fronds/__name__/handlers/PostHandler.ts +3 -5
- package/templates/frond/fronds/__name__/package.json +1 -1
- package/templates/frond/package.json +1 -1
- package/templates/frond/serve.mjs +4 -3
- package/templates/fronds/blank/package.json +1 -1
- package/templates/fronds/blog/handlers/PostHandler.ts +2 -4
- package/templates/fronds/blog/package.json +1 -1
- package/templates/workspace/AGENTS.md +14 -0
- package/templates/workspace/CLAUDE.md +27 -5
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Working in this application
|
|
2
|
+
|
|
3
|
+
This project is built with **Fougere**. Read `CLAUDE.md` for the model and architecture guidance
|
|
4
|
+
that applies to every coding agent.
|
|
5
|
+
|
|
6
|
+
## Required verification workflow
|
|
7
|
+
|
|
8
|
+
After every change to handlers, entities, Fronds, configuration, or topology:
|
|
9
|
+
|
|
10
|
+
1. Run `fougere check`.
|
|
11
|
+
2. Fix every deterministic error it reports before continuing.
|
|
12
|
+
3. Run the relevant tests, then run `npx tsc -p fronds --noEmit`.
|
|
13
|
+
|
|
14
|
+
`fougere check` is the Fougere model barrier; tests and TypeScript come after it passes.
|
|
@@ -35,8 +35,8 @@ Before adding a surface, reach for its **projection**:
|
|
|
35
35
|
|
|
36
36
|
| surface | the call |
|
|
37
37
|
|---|---|
|
|
38
|
-
| REST | `generateRoutes(app)` then `registerRoutes(router, routes)` — `@fougere/
|
|
39
|
-
| GraphQL | `registerAll(builder, app)` then `registerGraphQL(router, builder.toSchema())` — `@fougere/
|
|
38
|
+
| REST | `generateRoutes(app)` then `registerRoutes(router, routes)` — `@fougere/adapter-rest` |
|
|
39
|
+
| GraphQL | `registerAll(builder, app)` then `registerGraphQL(router, builder.toSchema())` — `@fougere/adapter-graphql` |
|
|
40
40
|
|
|
41
41
|
Hand-writing the types (`buildSchema`, raw SDL, one Pothos resolver per field) rebuilds what the
|
|
42
42
|
projection already derives, and drops the judge on the way. `registerType` / `registerOperations`
|
|
@@ -44,7 +44,18 @@ exist to add what a projection cannot derive — never to replace it.
|
|
|
44
44
|
|
|
45
45
|
## Reading data
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Storage is reached through a repository. Never inject `EntityOrm` directly into a handler,
|
|
48
|
+
presenter or collector — the boot refuses it. With no repository file, ask for the default shape:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import type { RepositoryOf } from '@fougere/core';
|
|
52
|
+
import Product from '../entities/Product.js';
|
|
53
|
+
|
|
54
|
+
constructor(private products: RepositoryOf<Product>) {}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If the handler extends `Crud(Product)`, its inherited `this.orm` is already backed by that
|
|
58
|
+
repository; do not add a constructor. The repository forwards the guarded storage gestures:
|
|
48
59
|
|
|
49
60
|
```
|
|
50
61
|
list(options?) every row — `options.where` filters, plus paging and sorting
|
|
@@ -56,10 +67,21 @@ create / update / delete
|
|
|
56
67
|
|
|
57
68
|
Read a relation with `findAllBy`. Never read a whole table to filter it in memory.
|
|
58
69
|
|
|
70
|
+
When a query deserves a domain name, add `repositories/ProductRepository.ts` with
|
|
71
|
+
`class ProductRepository extends Repository(Product)`, put the query there, and inject
|
|
72
|
+
`ProductRepository`. A repository is registered as a provider and remains the only route to storage.
|
|
73
|
+
|
|
59
74
|
## Checking your work
|
|
60
75
|
|
|
76
|
+
After every change to handlers, entities, Fronds, configuration, or topology:
|
|
77
|
+
|
|
78
|
+
1. Run `fougere check`.
|
|
79
|
+
2. Fix every deterministic error it reports before continuing.
|
|
80
|
+
3. Run the relevant tests, then run the project typecheck.
|
|
81
|
+
|
|
61
82
|
```bash
|
|
62
|
-
|
|
83
|
+
fougere check
|
|
84
|
+
npx tsc -p fronds --noEmit
|
|
63
85
|
```
|
|
64
86
|
|
|
65
|
-
|
|
87
|
+
`fougere check` is the Fougere model barrier; tests and TypeScript come after it passes.
|
|
@@ -10,7 +10,7 @@ export default class PostHandler extends Crud(Post) {
|
|
|
10
10
|
if (!post) {
|
|
11
11
|
throw new FougereError({ code: ErrorCode.NOT_FOUND, message: `Post '${id}' not found`, entity: 'post', operation: 'publish' });
|
|
12
12
|
}
|
|
13
|
-
if (
|
|
13
|
+
if (post.status === 'published') {
|
|
14
14
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already published', entity: 'post', operation: 'publish' });
|
|
15
15
|
}
|
|
16
16
|
return this.orm.update(id, { status: 'published' });
|
|
@@ -18,9 +18,7 @@ export default class PostHandler extends Crud(Post) {
|
|
|
18
18
|
|
|
19
19
|
/** Only published posts, projected to the card. */
|
|
20
20
|
async published(): Promise<PostCard[]> {
|
|
21
|
-
const
|
|
22
|
-
return
|
|
23
|
-
.filter((p) => (p as { status?: string }).status === 'published')
|
|
24
|
-
.map((p) => ({ id: String(p.id), title: String(p.title), status: 'published' })) as PostCard[];
|
|
21
|
+
const posts = await this.orm.list({ where: { status: 'published' } });
|
|
22
|
+
return posts.map(({ id, title, status }) => ({ id, title, status }));
|
|
25
23
|
}
|
|
26
24
|
}
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
* Nothing in the frond changes — only where it runs.
|
|
9
9
|
*/
|
|
10
10
|
import { createJiti } from 'jiti';
|
|
11
|
-
import { createLocalRunner,
|
|
12
|
-
import {
|
|
11
|
+
import { createLocalRunner, Logger } from '@fougere/core';
|
|
12
|
+
import { setModuleLoader, frondAliases } from '@fougere/core/node';
|
|
13
|
+
import { bootAppFromConfig } from '@fougere/defaults';
|
|
13
14
|
import { serve } from '@fougere/transport-http';
|
|
14
15
|
|
|
15
|
-
// `frondAliases` is what makes `@
|
|
16
|
+
// `frondAliases` is what makes `@fronds/<neighbour>/entities/X.js` resolve — the
|
|
16
17
|
// named form a frond uses for its neighbour. A bare jiti loads frond sources but
|
|
17
18
|
// not that convention, so a collector or handler importing across fronds dies here
|
|
18
19
|
// while the same code works in-process.
|
|
@@ -30,9 +30,7 @@ export default class PostHandler extends Crud(Post) {
|
|
|
30
30
|
|
|
31
31
|
/** Only published posts, projected to the card. */
|
|
32
32
|
async published(): Promise<PostCard[]> {
|
|
33
|
-
const
|
|
34
|
-
return
|
|
35
|
-
.filter((p) => p.status === 'published')
|
|
36
|
-
.map(({ id, title, status }) => ({ id, title, status }));
|
|
33
|
+
const posts = await this.orm.list({ where: { status: 'published' } });
|
|
34
|
+
return posts.map(({ id, title, status }) => ({ id, title, status }));
|
|
37
35
|
}
|
|
38
36
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Working in this application
|
|
2
|
+
|
|
3
|
+
This project is built with **Fougere**. Read `CLAUDE.md` for the model and architecture guidance
|
|
4
|
+
that applies to every coding agent.
|
|
5
|
+
|
|
6
|
+
## Required verification workflow
|
|
7
|
+
|
|
8
|
+
After every change to handlers, entities, Fronds, configuration, or topology:
|
|
9
|
+
|
|
10
|
+
1. Run `fougere check`.
|
|
11
|
+
2. Fix every deterministic error it reports before continuing.
|
|
12
|
+
3. Run the relevant tests, then run `pnpm typecheck`.
|
|
13
|
+
|
|
14
|
+
`fougere check` is the Fougere model barrier; tests and TypeScript come after it passes.
|
|
@@ -35,8 +35,8 @@ Before adding a surface, reach for its **projection**:
|
|
|
35
35
|
|
|
36
36
|
| surface | the call |
|
|
37
37
|
|---|---|
|
|
38
|
-
| REST | `generateRoutes(app)` then `registerRoutes(router, routes)` — `@fougere/
|
|
39
|
-
| GraphQL | `registerAll(builder, app)` then `registerGraphQL(router, builder.toSchema())` — `@fougere/
|
|
38
|
+
| REST | `generateRoutes(app)` then `registerRoutes(router, routes)` — `@fougere/adapter-rest` |
|
|
39
|
+
| GraphQL | `registerAll(builder, app)` then `registerGraphQL(router, builder.toSchema())` — `@fougere/adapter-graphql` |
|
|
40
40
|
|
|
41
41
|
Hand-writing the types (`buildSchema`, raw SDL, one Pothos resolver per field) rebuilds what the
|
|
42
42
|
projection already derives, and drops the judge on the way. `registerType` / `registerOperations`
|
|
@@ -44,7 +44,18 @@ exist to add what a projection cannot derive — never to replace it.
|
|
|
44
44
|
|
|
45
45
|
## Reading data
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Storage is reached through a repository. Never inject `EntityOrm` directly into a handler,
|
|
48
|
+
presenter or collector — the boot refuses it. With no repository file, ask for the default shape:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import type { RepositoryOf } from '@fougere/core';
|
|
52
|
+
import Product from '../entities/Product.js';
|
|
53
|
+
|
|
54
|
+
constructor(private products: RepositoryOf<Product>) {}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If the handler extends `Crud(Product)`, its inherited `this.orm` is already backed by that
|
|
58
|
+
repository; do not add a constructor. The repository forwards the guarded storage gestures:
|
|
48
59
|
|
|
49
60
|
```
|
|
50
61
|
list(options?) every row — `options.where` filters, plus paging and sorting
|
|
@@ -56,10 +67,21 @@ create / update / delete
|
|
|
56
67
|
|
|
57
68
|
Read a relation with `findAllBy`. Never read a whole table to filter it in memory.
|
|
58
69
|
|
|
70
|
+
When a query deserves a domain name, add `repositories/ProductRepository.ts` with
|
|
71
|
+
`class ProductRepository extends Repository(Product)`, put the query there, and inject
|
|
72
|
+
`ProductRepository`. A repository is registered as a provider and remains the only route to storage.
|
|
73
|
+
|
|
59
74
|
## Checking your work
|
|
60
75
|
|
|
76
|
+
After every change to handlers, entities, Fronds, configuration, or topology:
|
|
77
|
+
|
|
78
|
+
1. Run `fougere check`.
|
|
79
|
+
2. Fix every deterministic error it reports before continuing.
|
|
80
|
+
3. Run the relevant tests, then run the project typecheck.
|
|
81
|
+
|
|
61
82
|
```bash
|
|
62
|
-
|
|
83
|
+
fougere check
|
|
84
|
+
pnpm typecheck
|
|
63
85
|
```
|
|
64
86
|
|
|
65
|
-
|
|
87
|
+
`fougere check` is the Fougere model barrier; tests and TypeScript come after it passes.
|