@fougere/cli 0.12.1-alpha.0 → 0.12.4-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/app/commands/BuildCommand.ts +1 -0
- package/app/commands/CallCommand.ts +2 -0
- package/app/commands/CheckCommand.ts +4 -0
- package/app/commands/CompletionCommand.ts +1 -0
- package/app/commands/ExplainCommand.ts +2 -0
- package/app/commands/FreezeCommand.ts +7 -0
- package/app/commands/GrantCommand.ts +2 -0
- package/app/commands/GraphCommand.ts +3 -0
- package/app/commands/KeysCommand.ts +1 -0
- package/app/commands/LoadCommand.ts +2 -0
- package/app/commands/MigrateCommand.ts +4 -0
- package/app/commands/NewCommand.ts +8 -0
- package/app/commands/ServeCommand.ts +7 -0
- package/dist/bin.js.map +1 -1
- package/dist/bridge.js +7 -7
- package/dist/bridge.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +6 -4
- package/dist/runner.js.map +1 -1
- package/dist/typescript/EntityTypes.d.ts.map +1 -1
- package/dist/typescript/EntityTypes.js +2 -2
- package/dist/typescript/EntityTypes.js.map +1 -1
- package/dist/typescript/FacadeTypes.d.ts.map +1 -1
- package/dist/typescript/FacadeTypes.js.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js.map +1 -1
- package/fronds/analysis/handlers/ExplainHandler.ts +8 -6
- package/fronds/analysis/handlers/FreezeHandler.ts +5 -0
- package/fronds/analysis/handlers/MigrateHandler.ts +8 -1
- package/fronds/analysis/versions.ts +1 -0
- package/fronds/scaffold/handlers/SyncHandler.ts +4 -0
- package/fronds/scaffold/services/ProjectWriter.ts +60 -17
- package/package.json +23 -16
- package/src/bin.ts +3 -0
- package/src/bridge.ts +7 -7
- package/src/runner.ts +8 -4
- package/src/typescript/EntityTypes.ts +8 -2
- package/src/typescript/FacadeTypes.ts +2 -0
- package/src/ui.ts +21 -0
- package/templates/admin/fronds/admin/handlers/UserHandler.ts +2 -0
- package/templates/api/fronds/api/handlers/TaskHandler.ts +2 -0
- package/templates/blog/fronds/blog/handlers/PostHandler.ts +2 -0
- package/templates/frond/fronds/__name__/handlers/PostHandler.ts +2 -0
- package/templates/fronds/blog/handlers/PostHandler.ts +2 -0
|
@@ -24,6 +24,7 @@ function parseFlags(tokens: string[]): Record<string, unknown> {
|
|
|
24
24
|
if (next === undefined || next.startsWith('--')) out[key] = true;
|
|
25
25
|
else { out[key] = next; i++; }
|
|
26
26
|
}
|
|
27
|
+
|
|
27
28
|
return out;
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -39,6 +40,7 @@ export default class CallCommand {
|
|
|
39
40
|
const target = raw.operation as string | undefined;
|
|
40
41
|
if (!target || !target.includes('.')) {
|
|
41
42
|
this.ui.error('Usage: fougere call <entity>.<op> [--field value …]');
|
|
43
|
+
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
46
|
const [entityName, op] = target.split('.');
|
|
@@ -28,6 +28,7 @@ export default class CheckCommand {
|
|
|
28
28
|
|
|
29
29
|
if (result.fronds === 0) {
|
|
30
30
|
this.ui.warn('No fronds found. Run this from a Fougere project root.');
|
|
31
|
+
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -35,6 +36,7 @@ export default class CheckCommand {
|
|
|
35
36
|
|
|
36
37
|
if (result.findings.length === 0) {
|
|
37
38
|
this.ui.success('Nothing to report.');
|
|
39
|
+
|
|
38
40
|
return;
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -50,6 +52,7 @@ function render(f: Diagnostic): string {
|
|
|
50
52
|
const mark = f.severity === 'blocking' ? pc.red('✗') : pc.yellow('⚠');
|
|
51
53
|
const where = relative(process.cwd(), f.filePath) || f.filePath;
|
|
52
54
|
const what = f.subject ? ` ${f.subject}` : '';
|
|
55
|
+
|
|
53
56
|
return ` ${mark} ${pc.bold(`[${f.code}]`)}${what}\n${wrap(f.message, 76, ' ')}\n ${pc.dim(where)}`;
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -62,5 +65,6 @@ function wrap(text: string, width: number, indent: string): string {
|
|
|
62
65
|
else line = line ? `${line} ${word}` : word;
|
|
63
66
|
}
|
|
64
67
|
if (line) lines.push(line);
|
|
68
|
+
|
|
65
69
|
return lines.map((l) => indent + l).join('\n');
|
|
66
70
|
}
|
|
@@ -38,6 +38,7 @@ export default class ExplainCommand {
|
|
|
38
38
|
? listing.fronds.map((frond) => frond.name)
|
|
39
39
|
: listing.operations;
|
|
40
40
|
if (values.length > 0) process.stdout.write(values.join('\n') + '\n');
|
|
41
|
+
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -94,6 +95,7 @@ export function renderExplain(result: ExplainResult): string {
|
|
|
94
95
|
);
|
|
95
96
|
|
|
96
97
|
if (result.handler.file) lines.push(`${pc.dim('Source:')} ${result.handler.file}`);
|
|
98
|
+
|
|
97
99
|
return lines.join('\n');
|
|
98
100
|
}
|
|
99
101
|
|
|
@@ -21,6 +21,7 @@ export default class FreezeCommand {
|
|
|
21
21
|
async run(raw: Record<string, unknown>) {
|
|
22
22
|
if (!raw.version) {
|
|
23
23
|
this.ui.error('Usage: fougere freeze <version>');
|
|
24
|
+
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -37,11 +38,13 @@ export default class FreezeCommand {
|
|
|
37
38
|
|
|
38
39
|
if (seen.entities.length === 0) {
|
|
39
40
|
this.ui.warn('No entities found. Run this from a Fougere project root.');
|
|
41
|
+
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
if (seen.written) {
|
|
44
46
|
this.report(seen);
|
|
47
|
+
|
|
45
48
|
return;
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -77,11 +80,13 @@ export default class FreezeCommand {
|
|
|
77
80
|
// record a decision nobody made.
|
|
78
81
|
if (!answer) {
|
|
79
82
|
this.ui.warn(`${entity}.${removed} treated as dropped — say so explicitly if that is right.`);
|
|
83
|
+
|
|
80
84
|
return undefined;
|
|
81
85
|
}
|
|
82
86
|
renamed[entity] = { ...renamed[entity], [removed]: answer };
|
|
83
87
|
}
|
|
84
88
|
}
|
|
89
|
+
|
|
85
90
|
return renamed;
|
|
86
91
|
}
|
|
87
92
|
|
|
@@ -89,6 +94,7 @@ export default class FreezeCommand {
|
|
|
89
94
|
const { step } = written;
|
|
90
95
|
if (!step) {
|
|
91
96
|
this.ui.success(`${written.version} recorded — ${written.entities.length} entities, and nothing before it`);
|
|
97
|
+
|
|
92
98
|
return;
|
|
93
99
|
}
|
|
94
100
|
|
|
@@ -108,5 +114,6 @@ function describeChange(change: Change): string {
|
|
|
108
114
|
if (change.kind === 'renamed') return `${change.from} → ${change.to}`;
|
|
109
115
|
// An axis that moved names WHICH: "restated title" says nothing a reader can act on.
|
|
110
116
|
if (change.kind === 'restated') return `${change.field}: ${change.axis} moved`;
|
|
117
|
+
|
|
111
118
|
return `${change.kind} ${change.field}`;
|
|
112
119
|
}
|
|
@@ -21,6 +21,7 @@ export default class GrantCommand {
|
|
|
21
21
|
const frond = raw.frond as string | undefined;
|
|
22
22
|
if (!frond) {
|
|
23
23
|
this.ui.error('Usage: fougere grant <frond>');
|
|
24
|
+
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -29,6 +30,7 @@ export default class GrantCommand {
|
|
|
29
30
|
rootPrivateKey = await readFile(join(process.cwd(), ROOT_KEY), 'utf8');
|
|
30
31
|
} catch {
|
|
31
32
|
this.ui.error(`No ${ROOT_KEY} — run \`fougere keys\` first.`);
|
|
33
|
+
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -21,6 +21,7 @@ export default class GraphCommand {
|
|
|
21
21
|
|
|
22
22
|
if (result.totalFronds === 0) {
|
|
23
23
|
this.ui.warn('No fronds found. Run this from a Fougere project root.');
|
|
24
|
+
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -71,6 +72,7 @@ function renderGraph(nodes: Record<string, EntityNode>): string {
|
|
|
71
72
|
const badge = node.referencedBy.length > 0
|
|
72
73
|
? pc.dim(` (${node.referencedBy.length} incoming)`)
|
|
73
74
|
: '';
|
|
75
|
+
|
|
74
76
|
return ` ${pc.bold(name)}${refs}${badge}`;
|
|
75
77
|
}).join('\n');
|
|
76
78
|
}
|
|
@@ -83,6 +85,7 @@ function renderClusters(clusters: DomainCluster[]): string {
|
|
|
83
85
|
? [` ${pc.dim('cross-refs:')}`, ...cluster.crossRefs.map((r) =>
|
|
84
86
|
` ${r.from} ${pc.dim('→')} ${pc.yellow(r.to)} ${pc.dim(`(${r.targetCluster})`)}`)]
|
|
85
87
|
: [];
|
|
88
|
+
|
|
86
89
|
return [header, ...entities, ...crossRefs, ''].join('\n');
|
|
87
90
|
}).join('\n');
|
|
88
91
|
}
|
|
@@ -26,6 +26,7 @@ export default class KeysCommand {
|
|
|
26
26
|
if (await exists(path)) {
|
|
27
27
|
this.ui.error(`${ROOT_KEY} already exists — a second root would split the system in two.`);
|
|
28
28
|
this.ui.info('Delete it deliberately to start over; every grant issued so far stops being recognized.');
|
|
29
|
+
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -28,11 +28,13 @@ export default class LoadCommand {
|
|
|
28
28
|
|
|
29
29
|
if (result.operations.length === 0) {
|
|
30
30
|
this.ui.warn('No operation answers the default facade — nothing to put under load.');
|
|
31
|
+
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
if (!result.file) {
|
|
35
36
|
process.stdout.write(result.script);
|
|
37
|
+
|
|
36
38
|
return;
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -26,17 +26,20 @@ export default class MigrateCommand {
|
|
|
26
26
|
|
|
27
27
|
if (result.chain.length === 0) {
|
|
28
28
|
this.ui.warn('No frozen step to apply. `fougere freeze <version>` records one.');
|
|
29
|
+
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
if (result.refusals.length > 0) {
|
|
33
34
|
this.ui.error(`This chain cannot be realised as it stands (${result.chain.join(' → ')}):`);
|
|
34
35
|
for (const one of result.refusals) this.ui.step(`${pc.bold(`${one.entity}.${one.field}`)} — ${one.reason}`);
|
|
36
|
+
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
if (result.changes.length === 0) {
|
|
39
41
|
this.ui.success(`Up to date — ${result.chain.join(' → ')} already realised.`);
|
|
42
|
+
|
|
40
43
|
return;
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -50,6 +53,7 @@ export default class MigrateCommand {
|
|
|
50
53
|
|
|
51
54
|
if (result.ran.length === 0) {
|
|
52
55
|
this.ui.info(`${result.changes.length} statement(s) — run again with ${pc.bold('--apply')} to make it so.`);
|
|
56
|
+
|
|
53
57
|
return;
|
|
54
58
|
}
|
|
55
59
|
this.ui.success(`${result.ran.length} statement(s) run.`);
|
|
@@ -30,6 +30,10 @@ export default class NewCommand {
|
|
|
30
30
|
const dir = join(process.cwd(), name);
|
|
31
31
|
if (existsSync(dir) && !raw.force) {
|
|
32
32
|
const ok = await this.ui.confirm({ message: `${name}/ existe déjà. Écraser ?` });
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
33
37
|
if (!ok) { this.ui.cancel(); return; }
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -50,6 +54,7 @@ export default class NewCommand {
|
|
|
50
54
|
this.ui.info(`${template} at the root`);
|
|
51
55
|
this.ui.note([`cd ${name}`, INSTALL, `pnpm dev`].join('\n'), `${name} — one frond, at the root`);
|
|
52
56
|
this.ui.outro('Ready.');
|
|
57
|
+
|
|
53
58
|
return;
|
|
54
59
|
}
|
|
55
60
|
|
|
@@ -59,6 +64,7 @@ export default class NewCommand {
|
|
|
59
64
|
if (raw.local) pw.linkLocal(dir); else pw.pinVersions(dir);
|
|
60
65
|
this.ui.note([`cd ${name}`, `fougere new # compose it (guided)`].join('\n'), `${name} — empty workspace`);
|
|
61
66
|
this.ui.outro('Ready.');
|
|
67
|
+
|
|
62
68
|
return;
|
|
63
69
|
}
|
|
64
70
|
|
|
@@ -97,6 +103,7 @@ export default class NewCommand {
|
|
|
97
103
|
this.ui.info(`${kind}/${itemName}`);
|
|
98
104
|
count++;
|
|
99
105
|
}
|
|
106
|
+
|
|
100
107
|
return count;
|
|
101
108
|
}
|
|
102
109
|
|
|
@@ -124,6 +131,7 @@ export default class NewCommand {
|
|
|
124
131
|
this.ui.info(`${kind}/${itemName}`);
|
|
125
132
|
count++;
|
|
126
133
|
}
|
|
134
|
+
|
|
127
135
|
return count;
|
|
128
136
|
}
|
|
129
137
|
}
|
|
@@ -27,6 +27,10 @@ export default class ServeCommand {
|
|
|
27
27
|
|
|
28
28
|
async run(raw: Record<string, unknown>) {
|
|
29
29
|
const frond = raw.frond as string | undefined;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
30
34
|
if (!frond) { this.ui.error('Usage: fougere serve <frond>'); return; }
|
|
31
35
|
|
|
32
36
|
const root = process.cwd();
|
|
@@ -39,6 +43,7 @@ export default class ServeCommand {
|
|
|
39
43
|
let hosted = await bootApp(root, { only: [frond], topology: false });
|
|
40
44
|
if (!hosted.fronds.some((f) => f.name === frond)) {
|
|
41
45
|
this.ui.error(`Frond '${frond}' introuvable dans ce projet.`);
|
|
46
|
+
|
|
42
47
|
return;
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -56,6 +61,7 @@ export default class ServeCommand {
|
|
|
56
61
|
|
|
57
62
|
if (!watching) {
|
|
58
63
|
this.ui.info('Ctrl-C pour arrêter.');
|
|
64
|
+
|
|
59
65
|
// The listening server keeps the event loop alive; the command returns and stays up.
|
|
60
66
|
return;
|
|
61
67
|
}
|
|
@@ -69,6 +75,7 @@ export default class ServeCommand {
|
|
|
69
75
|
// The previous app keeps serving: a dev loop that dies on a typo is worse than
|
|
70
76
|
// one that holds the last state which booted.
|
|
71
77
|
this.ui.error(`reload refused — ${(error as Error).message}`);
|
|
78
|
+
|
|
72
79
|
return;
|
|
73
80
|
}
|
|
74
81
|
const previous = hosted;
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge.js
CHANGED
|
@@ -18,7 +18,7 @@ function suppliedIn(fields) {
|
|
|
18
18
|
const written = Visibility.of(fields).input;
|
|
19
19
|
if (Object.keys(written).length > 0)
|
|
20
20
|
return written;
|
|
21
|
-
return Object.fromEntries(Object.entries(fields).filter(([, field]) => Role.of(field).isPrimary));
|
|
21
|
+
return Object.fromEntries(Object.entries(fields).filter(([, field]) => Role.of(field).isPrimary()));
|
|
22
22
|
}
|
|
23
23
|
/** Convert an Entity's fields into citty args definition. */
|
|
24
24
|
export function entityToArgs(fields) {
|
|
@@ -27,7 +27,7 @@ export function entityToArgs(fields) {
|
|
|
27
27
|
// The CLI additionally skips ALL relations: a ref is not a flag — supplying related rows is
|
|
28
28
|
// not a CLI gesture.
|
|
29
29
|
for (const [key, field] of Object.entries(suppliedIn(fields))) {
|
|
30
|
-
if (Role.of(field).isRelation)
|
|
30
|
+
if (Role.of(field).isRelation())
|
|
31
31
|
continue;
|
|
32
32
|
// A `default(v)` travels as the create rule `{ value }` — citty shows it.
|
|
33
33
|
const defaultValue = Lifecycle.of(field).literal?.value;
|
|
@@ -35,16 +35,16 @@ export function entityToArgs(fields) {
|
|
|
35
35
|
const type = Shapes.typeOf(field.shape);
|
|
36
36
|
// Naming a row is required by definition: a generator fills a primary the server writes,
|
|
37
37
|
// never one a caller hands in to designate.
|
|
38
|
-
const designates = Role.of(field).isPrimary;
|
|
38
|
+
const designates = Role.of(field).isPrimary();
|
|
39
39
|
const common = {
|
|
40
|
-
description: field.
|
|
41
|
-
required: designates || (!nullable && Lifecycle.of(field).requiredAtCreate),
|
|
40
|
+
description: field.shape?.description,
|
|
41
|
+
required: designates || (!nullable && Lifecycle.of(field).requiredAtCreate()),
|
|
42
42
|
};
|
|
43
43
|
// A closed set is citty's `enum`: the shape already names the legal values, so the
|
|
44
44
|
// refusal and the `--help` listing come from the declaration rather than a check
|
|
45
45
|
// written beside it.
|
|
46
|
-
const options = shape
|
|
47
|
-
? shape.enum.filter((value) => value !== null)
|
|
46
|
+
const options = shape && 'enum' in shape && shape.enum?.length
|
|
47
|
+
? shape.enum.filter((value) => value !== null).map(String)
|
|
48
48
|
: undefined;
|
|
49
49
|
// First required field becomes positional — but never a boolean, a closed set, or a
|
|
50
50
|
// date-time, which stay named flags.
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAkB,MAAM,iBAAiB,CAAC;AAGrE,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;IAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAEpD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAyCzC;;;;;;;GAOG;AACH,wBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,SAA0C,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGjG"}
|
package/dist/runner.js
CHANGED
|
@@ -3,6 +3,7 @@ import { lowerFirst } from '@fougere/core/contract';
|
|
|
3
3
|
import { defineCommand, runMain } from 'citty';
|
|
4
4
|
import { ui } from './ui.js';
|
|
5
5
|
import { machineWanted } from './machine.js';
|
|
6
|
+
import { Shapes } from '@fougere/schema';
|
|
6
7
|
import { entityToArgs } from './bridge.js';
|
|
7
8
|
import { readdir } from 'node:fs/promises';
|
|
8
9
|
import { join } from 'node:path';
|
|
@@ -92,10 +93,11 @@ export async function run(app, root = new URL('..', import.meta.url).pathname) {
|
|
|
92
93
|
if (cmdName !== 'completion' && !machineOutput)
|
|
93
94
|
terminal.intro();
|
|
94
95
|
// citty adds `_` (raw positionals) and `--` (passthrough); strip them
|
|
95
|
-
// so only the entity's own fields reach the handler
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
// so only the entity's own fields reach the handler — read as their shape says,
|
|
97
|
+
// since a flag is text.
|
|
98
|
+
const input = Object.fromEntries(Object.entries(parsed)
|
|
99
|
+
.filter(([key]) => key !== '_' && key !== '--')
|
|
100
|
+
.map(([key, value]) => [key, Shapes.fromText(fields[key]?.shape, value)]));
|
|
99
101
|
try {
|
|
100
102
|
if (AppCommand) {
|
|
101
103
|
const cmd = new AppCommand(app, terminal);
|
package/dist/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityTypes.d.ts","sourceRoot":"","sources":["../../src/typescript/EntityTypes.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"EntityTypes.d.ts","sourceRoot":"","sources":["../../src/typescript/EntityTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGlG,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2DD,qBAAa,WAAW;IACF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAA/C,OAAO,eAA8D;IAErE,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,GAAG,WAAW,CAEnD;IAED,MAAM,CAAC,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAS/C;CACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { upperFirst } from '@fougere/schema';
|
|
1
|
+
import { Shapes, upperFirst } from '@fougere/schema';
|
|
2
2
|
import { docCommentOf, propertyKey } from './syntax.js';
|
|
3
3
|
/** So a nullable field lands as a union. */
|
|
4
4
|
function typeOf(field) {
|
|
5
|
-
const types =
|
|
5
|
+
const types = Shapes.typesOf(field);
|
|
6
6
|
const nullable = types.includes('null');
|
|
7
7
|
const base = types.find((t) => t !== 'null');
|
|
8
8
|
const inner = baseTypeOf(base, field);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityTypes.js","sourceRoot":"","sources":["../../src/typescript/EntityTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA+C,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"EntityTypes.js","sourceRoot":"","sources":["../../src/typescript/EntityTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FacadeTypes.d.ts","sourceRoot":"","sources":["../../src/typescript/FacadeTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC1D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD,qBAAa,WAAW;IACF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAA/C,OAAO,eAAqE;IAE5E,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,CAE1D;IAED,MAAM,CAAC,OAAO,GAAE,kBAAuB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"FacadeTypes.d.ts","sourceRoot":"","sources":["../../src/typescript/FacadeTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC1D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD,qBAAa,WAAW;IACF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAA/C,OAAO,eAAqE;IAE5E,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,CAE1D;IAED,MAAM,CAAC,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAa/C;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FacadeTypes.js","sourceRoot":"","sources":["../../src/typescript/FacadeTypes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAexD,yEAAyE;AACzE,SAAS,YAAY,CAAC,EAAgB,EAAE,OAAe;IACrD,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC;QACvB,KAAK,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI,CAAC;QACnC,KAAK,MAAM,EAAE,OAAO,GAAG,OAAO,gEAAgE,CAAC;QAC/F,KAAK,OAAO,EAAE,OAAO,GAAG,OAAO,cAAc,CAAC;QAC9C,KAAK,KAAK,EAAE,OAAO,OAAO,CAAC;QAC3B,KAAK,MAAM,EAAE,OAAO,SAAS,CAAC;QAC9B,SAAS,OAAO,SAAS,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,OAAO,WAAW;IACe,UAAU;IAA/C,YAAqC,UAAmC;0BAAnC,UAAU;IAA4B,CAAC;IAE5E,MAAM,CAAC,EAAE,CAAC,UAAmC;QAC3C,OAAO,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,OAAO,GAAuB,EAAE;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"FacadeTypes.js","sourceRoot":"","sources":["../../src/typescript/FacadeTypes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAexD,yEAAyE;AACzE,SAAS,YAAY,CAAC,EAAgB,EAAE,OAAe;IACrD,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC;QACvB,KAAK,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI,CAAC;QACnC,KAAK,MAAM,EAAE,OAAO,GAAG,OAAO,gEAAgE,CAAC;QAC/F,KAAK,OAAO,EAAE,OAAO,GAAG,OAAO,cAAc,CAAC;QAC9C,KAAK,KAAK,EAAE,OAAO,OAAO,CAAC;QAC3B,KAAK,MAAM,EAAE,OAAO,SAAS,CAAC;QAC9B,SAAS,OAAO,SAAS,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,OAAO,WAAW;IACe,UAAU;IAA/C,YAAqC,UAAmC;0BAAnC,UAAU;IAA4B,CAAC;IAE5E,MAAM,CAAC,EAAE,CAAC,UAAmC;QAC3C,OAAO,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,OAAO,GAAuB,EAAE;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAEtD,OAAO,GAAG,GAAG,KAAK,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,sCAAsC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC;QAC1H,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,QAAQ,aAAa,IAAI,KAAK,CAAC;QAEnE,OAAO,GAAG,QAAQ,aAAa,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACpE,CAAC;CACF"}
|
package/dist/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B;AAED,wBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO;IAMhC,qDAAqD;;IAKrD,sCAAsC;mBACvB,MAAM;IAIrB,uBAAuB;;IAQvB,kBAAkB;eACD;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B;AAED,wBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO;IAMhC,qDAAqD;;IAKrD,sCAAsC;mBACvB,MAAM;IAIrB,uBAAuB;;IAQvB,kBAAkB;eACD;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;KAAE;IAWnI,2BAA2B;kBACP;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE;IAW/D,8BAA8B;iBACX;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAWD,gCAAgC;sBACR;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB;IAaD,sDAAsD;sBACpC,MAAM;QAKpB,MAAM,QAAQ,MAAM;QACpB,IAAI,SAAS,MAAM;;IAMvB,6BAA6B;kBACf,MAAM;IAIpB,uBAAuB;qBACN,MAAM;IAIvB,uBAAuB;kBACT,MAAM;IAIpB,qBAAqB;mBACN,MAAM;IAIrB,sBAAsB;kBACR,MAAM;IAIpB,6CAA6C;kBAC/B,MAAM,UAAU,MAAM;;;;;;;;;;;;;EAUvC"}
|
package/dist/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAM5D,MAAM,UAAU,EAAE,CAAC,OAAiB;IAClC,MAAM,CAAC,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC;IAElD,OAAO;QACL,iDAAiD;QAEjD,qDAAqD;QACrD,KAAK,CAAC,KAAK,GAAG,SAAS;YACrB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC;QAED,sCAAsC;QACtC,KAAK,CAAC,OAAe;YACnB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAClC,CAAC;QAED,uBAAuB;QACvB,MAAM,CAAC,OAAO,GAAG,YAAY;YAC3B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,iDAAiD;QAEjD,kBAAkB;QAClB,KAAK,CAAC,IAAI,CAAC,IAAwH;YACjI,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
addressOf,
|
|
2
3
|
resolveEffectiveOperations,
|
|
3
4
|
type EffectiveOperation,
|
|
4
5
|
type OperationContract,
|
|
5
6
|
} from '@fougere/core';
|
|
6
7
|
import { relative } from 'node:path';
|
|
7
8
|
import ProjectScan from '../services/ProjectScan.js';
|
|
8
|
-
import { ANONYMOUS_SCHEMA_NAME,
|
|
9
|
+
import { ANONYMOUS_SCHEMA_NAME, type SchemaView } from '@fougere/schema';
|
|
9
10
|
import { remotesOf } from '@fougere/core/node';
|
|
10
11
|
|
|
11
12
|
type Cardinality = NonNullable<OperationContract['cardinality']>;
|
|
@@ -112,6 +113,7 @@ export default class ExplainHandler {
|
|
|
112
113
|
|
|
113
114
|
private async modelOf(root?: string) {
|
|
114
115
|
const scan = await this.projectScan.at(root);
|
|
116
|
+
|
|
115
117
|
return {
|
|
116
118
|
scan,
|
|
117
119
|
model: resolveEffectiveOperations(scan.fronds, {
|
|
@@ -215,6 +217,7 @@ function parseSelector(value: string): Selector {
|
|
|
215
217
|
}
|
|
216
218
|
|
|
217
219
|
const qualifiers = path.slice(0, -1);
|
|
220
|
+
|
|
218
221
|
return {
|
|
219
222
|
...(qualifiers[0] ? { frond: qualifiers[0] } : {}),
|
|
220
223
|
...(qualifiers[1] ? { surface: qualifiers[1] } : {}),
|
|
@@ -230,29 +233,28 @@ function matches(operation: EffectiveOperation, selector: Selector): boolean {
|
|
|
230
233
|
&& (!selector.surface || operation.exposure.surfaces.includes(selector.surface));
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
function addressOf(value: string): string {
|
|
234
|
-
const base = value.endsWith('Handler') ? value.slice(0, -'Handler'.length) : value;
|
|
235
|
-
return lowerFirst(base);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
236
|
function inputTypeOf(operation: EffectiveOperation): string | null {
|
|
239
237
|
const body = operation.parameters.find((parameter) => parameter.binding.source.kind === 'input');
|
|
238
|
+
|
|
240
239
|
return body?.type ?? schemaName(operation.input) ?? null;
|
|
241
240
|
}
|
|
242
241
|
|
|
243
242
|
function outputOf(operation: EffectiveOperation): ExplainResult['output'] {
|
|
244
243
|
const type = schemaName(operation.output) ?? parsedOutput(operation.signature?.returnType?.raw);
|
|
244
|
+
|
|
245
245
|
return type ? { type, cardinality: operation.cardinality ?? null } : null;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
function schemaName(schema: SchemaView | undefined): string | undefined {
|
|
249
249
|
if (!schema) return undefined;
|
|
250
250
|
if (schema.name && schema.name !== ANONYMOUS_SCHEMA_NAME) return schema.name;
|
|
251
|
+
|
|
251
252
|
return schema.derivation?.sourceName;
|
|
252
253
|
}
|
|
253
254
|
|
|
254
255
|
function parsedOutput(raw: string | undefined): string | undefined {
|
|
255
256
|
if (!raw) return undefined;
|
|
257
|
+
|
|
256
258
|
return raw.startsWith('Promise<') && raw.endsWith('>') ? raw.slice(8, -1) : raw;
|
|
257
259
|
}
|
|
258
260
|
|
|
@@ -101,6 +101,7 @@ export default class FreezeHandler {
|
|
|
101
101
|
*/
|
|
102
102
|
private async read(input: Omit<Freeze, 'json'>) {
|
|
103
103
|
const scan = await this.projectScan.at(input.root ?? undefined);
|
|
104
|
+
|
|
104
105
|
return Promise.all(
|
|
105
106
|
scan.fronds
|
|
106
107
|
.filter((frond) => frond.entities.length > 0)
|
|
@@ -133,6 +134,7 @@ function declaredRenames(
|
|
|
133
134
|
const key = lowerFirst(name);
|
|
134
135
|
if (previous) out[key] = Object.fromEntries(Object.entries(previous).map(([now, was]) => [was, now]));
|
|
135
136
|
}
|
|
137
|
+
|
|
136
138
|
return out;
|
|
137
139
|
}
|
|
138
140
|
|
|
@@ -145,6 +147,7 @@ function settled(
|
|
|
145
147
|
for (const source of [...sources, answers]) {
|
|
146
148
|
for (const [entity, pairs] of Object.entries(source)) out[entity] = { ...out[entity], ...pairs };
|
|
147
149
|
}
|
|
150
|
+
|
|
148
151
|
return out;
|
|
149
152
|
}
|
|
150
153
|
|
|
@@ -160,6 +163,7 @@ function previousName(inspected: readonly Inspected[]): string | undefined {
|
|
|
160
163
|
function merge(inspected: readonly Inspected[]): SetDiff | undefined {
|
|
161
164
|
const steps = inspected.map(({ step }) => step).filter((step): step is SetDiff => Boolean(step));
|
|
162
165
|
if (steps.length === 0) return undefined;
|
|
166
|
+
|
|
163
167
|
return {
|
|
164
168
|
entities: Object.assign({}, ...steps.map((step) => step.entities)),
|
|
165
169
|
entitiesAdded: steps.flatMap((step) => step.entitiesAdded),
|
|
@@ -174,5 +178,6 @@ async function previousOf(root: string, version: string): Promise<{ name: string
|
|
|
174
178
|
if (!last) return undefined;
|
|
175
179
|
|
|
176
180
|
const raw = await readFile(join(root, VERSIONS, last, 'shape.json'), 'utf8').catch(() => undefined);
|
|
181
|
+
|
|
177
182
|
return raw ? { name: last, bundle: JSON.parse(raw) as SchemaBundle } : undefined;
|
|
178
183
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from '@fougere/core/node';
|
|
2
2
|
import { resolveStorage } from '@fougere/defaults';
|
|
3
|
-
import {
|
|
3
|
+
import type { Plan, StepChange } from '@fougere/adapter-sql';
|
|
4
4
|
import type { SetDiff } from '@fougere/schema';
|
|
5
5
|
import ProjectScan from '../services/ProjectScan.js';
|
|
6
6
|
import { chainOf } from '../versions.js';
|
|
@@ -54,6 +54,12 @@ export default class MigrateHandler {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
// Resolved from the project rather than named in this package's dependencies:
|
|
58
|
+
// `@fougere/adapter-sql` declares `better-sqlite3`, so a CLI depending on it installs
|
|
59
|
+
// 26 MB of native module into every `npm create fougere`. A project that migrates
|
|
60
|
+
// declares the adapter itself, which is where this resolves from.
|
|
61
|
+
const { actualState, desiredTables, planStep, collapseChain, applyStep } = await import('@fougere/adapter-sql');
|
|
62
|
+
|
|
57
63
|
const tables = desiredTables(scan as never);
|
|
58
64
|
// Each frond's chain is composed on its own — its versions are its own line — and the
|
|
59
65
|
// results are gathered by SOURCE, because an engine is what a statement runs against.
|
|
@@ -98,6 +104,7 @@ function onSource(step: SetDiff, source: string, sourceOf: (entity: string) => s
|
|
|
98
104
|
/** Every recorded step, oldest first — the chain composes, so it is replayed whole. */
|
|
99
105
|
async function stepsOf(frondPath: string): Promise<{ version: string; step: SetDiff }[]> {
|
|
100
106
|
const chain = await chainOf(frondPath);
|
|
107
|
+
|
|
101
108
|
// The first version has a shape and no step — there was nothing before it to move from.
|
|
102
109
|
return chain.flatMap(({ name, step }) => (step ? [{ version: name, step }] : []));
|
|
103
110
|
}
|
|
@@ -49,6 +49,7 @@ export function entityClassName(name: string): string {
|
|
|
49
49
|
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(identifier)) {
|
|
50
50
|
throw new Error(`Entity name '${name}' cannot be represented as a TypeScript identifier`);
|
|
51
51
|
}
|
|
52
|
+
|
|
52
53
|
return identifier;
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -103,6 +104,7 @@ function identityCardOf(value: unknown): IdentityCard {
|
|
|
103
104
|
for (const facade of frond.facades) assertEntry('facade', frond.name, facade);
|
|
104
105
|
for (const fact of frond.facts ?? []) assertEntry('fact', frond.name, fact);
|
|
105
106
|
}
|
|
107
|
+
|
|
106
108
|
return card;
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -170,6 +172,7 @@ export default class SyncHandler {
|
|
|
170
172
|
const className = entityClassName(name);
|
|
171
173
|
if (generated.has(className)) throw new Error(`Remote declares duplicate entity '${className}'`);
|
|
172
174
|
generated.set(className, { row: false, facade: false });
|
|
175
|
+
|
|
173
176
|
return className;
|
|
174
177
|
};
|
|
175
178
|
|
|
@@ -324,6 +327,7 @@ export default class SyncHandler {
|
|
|
324
327
|
rmSync(path);
|
|
325
328
|
dropped.push(name);
|
|
326
329
|
}
|
|
330
|
+
|
|
327
331
|
return dropped;
|
|
328
332
|
}
|
|
329
333
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, renameSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
2
4
|
import { dirname, join } from 'node:path';
|
|
3
5
|
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { type Conventions, DEFAULT_CONVENTIONS, frondPackage } from '@fougere/core';
|
|
@@ -17,6 +19,7 @@ function monorepoPackages(): string | undefined {
|
|
|
17
19
|
if (existsSync(join(d, 'pnpm-workspace.yaml'))) return join(d, 'packages');
|
|
18
20
|
d = dirname(d);
|
|
19
21
|
}
|
|
22
|
+
|
|
20
23
|
return undefined;
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -37,6 +40,14 @@ const TEMPLATES = fileURLToPath(new URL('../../../templates/', import.meta.url))
|
|
|
37
40
|
* `nuxt.config.ts` must say, and a copy of it here would be that knowledge written twice —
|
|
38
41
|
* which is how `templates/apps/` came to hold one host while six were published.
|
|
39
42
|
*
|
|
43
|
+
* Two ways to reach them, and the first is the monorepo's: a host is on disk there, and in
|
|
44
|
+
* every process that installed one for its own reasons.
|
|
45
|
+
*/
|
|
46
|
+
function starterOf(pkg: string): string | undefined {
|
|
47
|
+
return carried(pkg) ?? fetched(pkg);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
40
51
|
* Resolved from the main entry and walked up to the manifest, because a host does not export
|
|
41
52
|
* its own `package.json` and has no reason to.
|
|
42
53
|
*
|
|
@@ -44,7 +55,7 @@ const TEMPLATES = fileURLToPath(new URL('../../../templates/', import.meta.url))
|
|
|
44
55
|
* `import` condition, so the CJS resolver answers `ERR_PACKAGE_PATH_NOT_EXPORTED` for every
|
|
45
56
|
* one of them.
|
|
46
57
|
*/
|
|
47
|
-
function
|
|
58
|
+
function carried(pkg: string): string | undefined {
|
|
48
59
|
let dir: string;
|
|
49
60
|
try {
|
|
50
61
|
dir = dirname(fileURLToPath(import.meta.resolve(pkg)));
|
|
@@ -57,23 +68,50 @@ function starterOf(pkg: string): string | undefined {
|
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
/**
|
|
60
|
-
* The
|
|
71
|
+
* The starter of a host this process does not carry, read out of its published tarball.
|
|
72
|
+
*
|
|
73
|
+
* A host is no longer a `dependencies` entry: what is wanted of it is a directory of files, and
|
|
74
|
+
* npm answers a dependency by installing the whole tree behind it — `next` brought 300 MB and
|
|
75
|
+
* `nuxt` its own, so that 28 files weighing 112 KB could be copied. A tarball is 27 to 388 KB,
|
|
76
|
+
* and the peers it names are the scaffolded app's to install, never this CLI's.
|
|
77
|
+
*
|
|
78
|
+
* Pinned to `scaffoldVersion()` for the reason `pinVersions` states, and extracted under that
|
|
79
|
+
* version, so a second call reuses what the first unpacked and a released CLI never reads the
|
|
80
|
+
* starter of another one.
|
|
81
|
+
*/
|
|
82
|
+
function fetched(pkg: string): string | undefined {
|
|
83
|
+
const dir = join(tmpdir(), 'fougere-starter', `${pkg.replace('/', '-')}@${scaffoldVersion()}`);
|
|
84
|
+
const template = join(dir, 'package', 'template');
|
|
85
|
+
if (existsSync(template)) return template;
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
mkdirSync(dir, { recursive: true });
|
|
89
|
+
const tarball = execFileSync('npm', ['pack', `${pkg}@${scaffoldVersion()}`, '--pack-destination', dir, '--silent'],
|
|
90
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
91
|
+
execFileSync('tar', ['-xzf', join(dir, tarball), '-C', dir, 'package/template'], { stdio: 'ignore' });
|
|
92
|
+
} catch { return undefined; }
|
|
93
|
+
|
|
94
|
+
return existsSync(template) ? template : undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The hosts this CLI can scaffold: the `@fougere/*` packages it is developed against.
|
|
61
99
|
*
|
|
62
100
|
* The dependency list IS the registry — nothing to declare, and a host added to the family
|
|
63
|
-
* appears here the day the CLI
|
|
101
|
+
* appears here the day the CLI names it. It names them under `devDependencies`, because what
|
|
102
|
+
* it wants of a host is a directory of files rather than a module to load, and `dependencies`
|
|
103
|
+
* is what had `npm create fougere` install Next.js and Nuxt to copy 28 files.
|
|
104
|
+
*
|
|
105
|
+
* The NAMES are read here and the FILES only where an app is written, so offering the list
|
|
106
|
+
* costs nothing: resolving all six would fetch six tarballs to print six words.
|
|
64
107
|
*/
|
|
65
|
-
function hosts():
|
|
108
|
+
function hosts(): string[] {
|
|
66
109
|
const manifest = JSON.parse(readFileSync(fileURLToPath(new URL('../../../package.json', import.meta.url)), 'utf8')) as
|
|
67
|
-
{
|
|
68
|
-
const found = new Map<string, string>();
|
|
110
|
+
{ devDependencies?: Record<string, string> };
|
|
69
111
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (starter) found.set(pkg.slice('@fougere/'.length), starter);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return found;
|
|
112
|
+
return Object.keys(manifest.devDependencies ?? {})
|
|
113
|
+
.filter((pkg) => pkg.startsWith('@fougere/'))
|
|
114
|
+
.map((pkg) => pkg.slice('@fougere/'.length));
|
|
77
115
|
}
|
|
78
116
|
|
|
79
117
|
/** The version that scaffolds is the version the templates were written for. */
|
|
@@ -102,6 +140,7 @@ export default class ProjectWriter {
|
|
|
102
140
|
cpSync(join(TEMPLATES, 'workspace'), dir, { recursive: true });
|
|
103
141
|
restoreGitignore(dir);
|
|
104
142
|
setPackageName(dir, name);
|
|
143
|
+
|
|
105
144
|
return { path: dir };
|
|
106
145
|
}
|
|
107
146
|
|
|
@@ -114,6 +153,7 @@ export default class ProjectWriter {
|
|
|
114
153
|
cpSync(join(TEMPLATES, 'flat'), dir, { recursive: true });
|
|
115
154
|
restoreGitignore(dir);
|
|
116
155
|
setPackageName(dir, name);
|
|
156
|
+
|
|
117
157
|
return { path: dir };
|
|
118
158
|
}
|
|
119
159
|
|
|
@@ -129,6 +169,7 @@ export default class ProjectWriter {
|
|
|
129
169
|
if (!entry.isDirectory()) continue;
|
|
130
170
|
cpSync(join(src, entry.name), join(dir, entry.name), { recursive: true });
|
|
131
171
|
}
|
|
172
|
+
|
|
132
173
|
return { path: dir };
|
|
133
174
|
}
|
|
134
175
|
|
|
@@ -145,18 +186,20 @@ export default class ProjectWriter {
|
|
|
145
186
|
pkg.name = frondPackage(name, conventions);
|
|
146
187
|
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
147
188
|
}
|
|
189
|
+
|
|
148
190
|
return { path: dest };
|
|
149
191
|
}
|
|
150
192
|
|
|
151
193
|
/** Add an app (consumer) under apps/<name>, from the host package that owns its wiring. */
|
|
152
194
|
addApp(wsDir: string, template: string, name: string): { path: string } {
|
|
153
195
|
const dest = join(wsDir, 'apps', name);
|
|
154
|
-
const starter = hosts().
|
|
155
|
-
if (!starter) throw new Error(`No host ships a starter for '${template}'. Served: ${
|
|
196
|
+
const starter = hosts().includes(template) ? starterOf(`@fougere/${template}`) : undefined;
|
|
197
|
+
if (!starter) throw new Error(`No host ships a starter for '${template}'. Served: ${hosts().join(', ')}.`);
|
|
156
198
|
|
|
157
199
|
cpSync(starter, dest, { recursive: true });
|
|
158
200
|
restoreGitignore(dest);
|
|
159
201
|
setPackageName(dest, name);
|
|
202
|
+
|
|
160
203
|
return { path: dest };
|
|
161
204
|
}
|
|
162
205
|
|
|
@@ -168,7 +211,7 @@ export default class ProjectWriter {
|
|
|
168
211
|
* CLI depends on, so `fougere new` offers what is published rather than what was copied here.
|
|
169
212
|
*/
|
|
170
213
|
listTemplates(kind: 'fronds' | 'apps'): string[] {
|
|
171
|
-
if (kind === 'apps') return
|
|
214
|
+
if (kind === 'apps') return hosts().sort();
|
|
172
215
|
|
|
173
216
|
const dir = join(TEMPLATES, kind);
|
|
174
217
|
if (!existsSync(dir)) return [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4-alpha.0",
|
|
4
4
|
"description": "The Fougere CLI — compose a workspace, serve a frond, call an operation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -42,27 +42,34 @@
|
|
|
42
42
|
"jiti": "^2.4.2",
|
|
43
43
|
"picocolors": "^1.1.1",
|
|
44
44
|
"safe-regex": "^2.1.1",
|
|
45
|
-
"@fougere/compiler": "0.12.
|
|
46
|
-
"@fougere/
|
|
47
|
-
"@fougere/
|
|
48
|
-
"@fougere/
|
|
49
|
-
"@fougere/
|
|
50
|
-
"@fougere/
|
|
51
|
-
"@fougere/
|
|
52
|
-
"@fougere/container": "0.12.1-alpha.0",
|
|
53
|
-
"@fougere/testing": "0.12.1-alpha.0",
|
|
54
|
-
"@fougere/nuxt": "0.12.1-alpha.0",
|
|
55
|
-
"@fougere/svelte": "0.12.1-alpha.0",
|
|
56
|
-
"@fougere/transport-http": "0.12.1-alpha.0",
|
|
57
|
-
"@fougere/admin": "0.12.1-alpha.0",
|
|
58
|
-
"@fougere/oclif": "0.12.1-alpha.0"
|
|
45
|
+
"@fougere/compiler": "0.12.4-alpha.0",
|
|
46
|
+
"@fougere/container": "0.12.4-alpha.0",
|
|
47
|
+
"@fougere/core": "0.12.4-alpha.0",
|
|
48
|
+
"@fougere/schema": "0.12.4-alpha.0",
|
|
49
|
+
"@fougere/testing": "0.12.4-alpha.0",
|
|
50
|
+
"@fougere/transport-http": "0.12.4-alpha.0",
|
|
51
|
+
"@fougere/defaults": "0.12.4-alpha.0"
|
|
59
52
|
},
|
|
60
53
|
"devDependencies": {
|
|
61
|
-
"vitest": "^4.1.0"
|
|
54
|
+
"vitest": "^4.1.0",
|
|
55
|
+
"@fougere/admin": "0.12.4-alpha.0",
|
|
56
|
+
"@fougere/next": "0.12.4-alpha.0",
|
|
57
|
+
"@fougere/nuxt": "0.12.4-alpha.0",
|
|
58
|
+
"@fougere/oclif": "0.12.4-alpha.0",
|
|
59
|
+
"@fougere/svelte": "0.12.4-alpha.0",
|
|
60
|
+
"@fougere/react": "0.12.4-alpha.0"
|
|
62
61
|
},
|
|
63
62
|
"publishConfig": {
|
|
64
63
|
"access": "public"
|
|
65
64
|
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@fougere/adapter-sql": "^0.12.4-alpha.0"
|
|
67
|
+
},
|
|
68
|
+
"peerDependenciesMeta": {
|
|
69
|
+
"@fougere/adapter-sql": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
66
73
|
"scripts": {
|
|
67
74
|
"build": "rm -rf dist && tsc && chmod +x dist/bin.js && node dist/bin.js build",
|
|
68
75
|
"test": "vitest run",
|
package/src/bin.ts
CHANGED
|
@@ -40,8 +40,10 @@ async function newestDeclaration(root: string): Promise<number> {
|
|
|
40
40
|
const stats = await Promise.all(entries
|
|
41
41
|
.filter((entry) => entry.isFile() && entry.name.endsWith('.ts'))
|
|
42
42
|
.map((entry) => stat(join(dir, entry.name)).then((s) => s.mtimeMs).catch(() => 0)));
|
|
43
|
+
|
|
43
44
|
return Math.max(0, ...stats);
|
|
44
45
|
}));
|
|
46
|
+
|
|
45
47
|
return Math.max(0, ...times);
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -62,6 +64,7 @@ async function scanOf(root: string): Promise<ScanResult> {
|
|
|
62
64
|
const spin = process.stdout.isTTY ? terminal.spinner('reading fronds') : undefined;
|
|
63
65
|
const scan = await scanProject(root);
|
|
64
66
|
spin?.stop(`${scan.fronds.length} frond(s)`);
|
|
67
|
+
|
|
65
68
|
return scan;
|
|
66
69
|
}
|
|
67
70
|
|
package/src/bridge.ts
CHANGED
|
@@ -24,7 +24,7 @@ function suppliedIn(fields: Fields): Fields {
|
|
|
24
24
|
if (Object.keys(written).length > 0) return written;
|
|
25
25
|
|
|
26
26
|
return Object.fromEntries(
|
|
27
|
-
Object.entries(fields).filter(([, field]) => Role.of(field).isPrimary),
|
|
27
|
+
Object.entries(fields).filter(([, field]) => Role.of(field).isPrimary()),
|
|
28
28
|
) as Fields;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -36,7 +36,7 @@ export function entityToArgs(fields: Fields): ArgsDef {
|
|
|
36
36
|
// The CLI additionally skips ALL relations: a ref is not a flag — supplying related rows is
|
|
37
37
|
// not a CLI gesture.
|
|
38
38
|
for (const [key, field] of Object.entries(suppliedIn(fields))) {
|
|
39
|
-
if (Role.of(field).isRelation) continue;
|
|
39
|
+
if (Role.of(field).isRelation()) continue;
|
|
40
40
|
|
|
41
41
|
// A `default(v)` travels as the create rule `{ value }` — citty shows it.
|
|
42
42
|
const defaultValue = Lifecycle.of(field).literal?.value;
|
|
@@ -44,17 +44,17 @@ export function entityToArgs(fields: Fields): ArgsDef {
|
|
|
44
44
|
const type = Shapes.typeOf(field.shape);
|
|
45
45
|
// Naming a row is required by definition: a generator fills a primary the server writes,
|
|
46
46
|
// never one a caller hands in to designate.
|
|
47
|
-
const designates = Role.of(field).isPrimary;
|
|
47
|
+
const designates = Role.of(field).isPrimary();
|
|
48
48
|
const common = {
|
|
49
|
-
description: field.
|
|
50
|
-
required: designates || (!nullable && Lifecycle.of(field).requiredAtCreate),
|
|
49
|
+
description: field.shape?.description,
|
|
50
|
+
required: designates || (!nullable && Lifecycle.of(field).requiredAtCreate()),
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
// A closed set is citty's `enum`: the shape already names the legal values, so the
|
|
54
54
|
// refusal and the `--help` listing come from the declaration rather than a check
|
|
55
55
|
// written beside it.
|
|
56
|
-
const options = shape
|
|
57
|
-
? shape.enum.filter((value)
|
|
56
|
+
const options = shape && 'enum' in shape && shape.enum?.length
|
|
57
|
+
? shape.enum.filter((value) => value !== null).map(String)
|
|
58
58
|
: undefined;
|
|
59
59
|
// First required field becomes positional — but never a boolean, a closed set, or a
|
|
60
60
|
// date-time, which stay named flags.
|
package/src/runner.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { lowerFirst } from '@fougere/core/contract';
|
|
|
8
8
|
import { defineCommand, runMain } from 'citty';
|
|
9
9
|
import { ui } from './ui.js';
|
|
10
10
|
import { machineWanted } from './machine.js';
|
|
11
|
+
import { Shapes } from '@fougere/schema';
|
|
11
12
|
import { entityToArgs } from './bridge.js';
|
|
12
13
|
import { readdir } from 'node:fs/promises';
|
|
13
14
|
import { join } from 'node:path';
|
|
@@ -110,10 +111,13 @@ export async function run(app: App, root = new URL('..', import.meta.url).pathna
|
|
|
110
111
|
if (cmdName !== 'completion' && !machineOutput) terminal.intro();
|
|
111
112
|
|
|
112
113
|
// citty adds `_` (raw positionals) and `--` (passthrough); strip them
|
|
113
|
-
// so only the entity's own fields reach the handler
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
// so only the entity's own fields reach the handler — read as their shape says,
|
|
115
|
+
// since a flag is text.
|
|
116
|
+
const input = Object.fromEntries(
|
|
117
|
+
Object.entries(parsed as Record<string, unknown>)
|
|
118
|
+
.filter(([key]) => key !== '_' && key !== '--')
|
|
119
|
+
.map(([key, value]) => [key, Shapes.fromText(fields[key]?.shape, value)]),
|
|
120
|
+
);
|
|
117
121
|
|
|
118
122
|
try {
|
|
119
123
|
if (AppCommand) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { upperFirst, type FieldDescriptor, type SchemaDescriptor } from '@fougere/schema';
|
|
1
|
+
import { Shapes, upperFirst, type FieldDescriptor, type SchemaDescriptor } from '@fougere/schema';
|
|
2
2
|
import { docCommentOf, propertyKey } from './syntax.js';
|
|
3
3
|
|
|
4
4
|
export interface EntityTypesOptions {
|
|
@@ -8,10 +8,11 @@ export interface EntityTypesOptions {
|
|
|
8
8
|
|
|
9
9
|
/** So a nullable field lands as a union. */
|
|
10
10
|
function typeOf(field: FieldDescriptor): string {
|
|
11
|
-
const types =
|
|
11
|
+
const types = Shapes.typesOf(field);
|
|
12
12
|
const nullable = types.includes('null');
|
|
13
13
|
const base = types.find((t) => t !== 'null');
|
|
14
14
|
const inner = baseTypeOf(base, field);
|
|
15
|
+
|
|
15
16
|
return nullable ? `${inner} | null` : inner;
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -41,8 +42,10 @@ function baseTypeOf(base: string | undefined, field: FieldDescriptor): string {
|
|
|
41
42
|
function objectTypeOf(properties: Record<string, FieldDescriptor>, required: readonly string[]): string {
|
|
42
43
|
const members = Object.entries(properties).map(([name, field]) => {
|
|
43
44
|
const optional = required.includes(name) ? '' : '?';
|
|
45
|
+
|
|
44
46
|
return `${propertyKey(name)}${optional}: ${typeOf(field)}`;
|
|
45
47
|
});
|
|
48
|
+
|
|
46
49
|
return `{ ${members.join('; ')} }`;
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -53,8 +56,10 @@ function shapeTypeOf(descriptor: SchemaDescriptor, indent = ''): string {
|
|
|
53
56
|
|
|
54
57
|
const lines = entries.map(([key, field]) => {
|
|
55
58
|
const doc = docCommentOf(field.description, `${indent} `);
|
|
59
|
+
|
|
56
60
|
return `${doc}${indent} ${propertyKey(key)}: ${typeOf(field)};`;
|
|
57
61
|
});
|
|
62
|
+
|
|
58
63
|
return `{\n${lines.join('\n')}\n${indent}}`;
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -82,5 +87,6 @@ function identifierOf(name: string): string {
|
|
|
82
87
|
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) {
|
|
83
88
|
throw new Error(`'${name}' is not a TypeScript identifier — it cannot name a generated declaration`);
|
|
84
89
|
}
|
|
90
|
+
|
|
85
91
|
return name;
|
|
86
92
|
}
|
|
@@ -39,10 +39,12 @@ export class FacadeTypes {
|
|
|
39
39
|
const rowType = options.rowType ?? 'unknown';
|
|
40
40
|
const members = this.operations.map((operation) => {
|
|
41
41
|
const doc = docCommentOf(operation.description, ' ');
|
|
42
|
+
|
|
42
43
|
return `${doc} ${propertyKey(operation.name)}(invocation?: Invocation): Promise<${returnTypeOf(operation, rowType)}>;`;
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
if (members.length === 0) return `${exported}interface ${name} {}`;
|
|
47
|
+
|
|
46
48
|
return `${exported}interface ${name} {\n${members.join('\n')}\n}`;
|
|
47
49
|
}
|
|
48
50
|
}
|
package/src/ui.ts
CHANGED
|
@@ -35,14 +35,24 @@ export function ui(options?: UiTheme) {
|
|
|
35
35
|
/** Text input. */
|
|
36
36
|
async text(opts: { message: string; placeholder?: string; defaultValue?: string; validate?: (value: string) => string | undefined }) {
|
|
37
37
|
const result = await clack.text(opts);
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
38
42
|
if (clack.isCancel(result)) { this.cancel(); return ''; }
|
|
43
|
+
|
|
39
44
|
return result as string;
|
|
40
45
|
},
|
|
41
46
|
|
|
42
47
|
/** Yes/no confirmation. */
|
|
43
48
|
async confirm(opts: { message: string; initialValue?: boolean }) {
|
|
44
49
|
const result = await clack.confirm(opts);
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
45
54
|
if (clack.isCancel(result)) { this.cancel(); return false; }
|
|
55
|
+
|
|
46
56
|
return result as boolean;
|
|
47
57
|
},
|
|
48
58
|
|
|
@@ -53,7 +63,12 @@ export function ui(options?: UiTheme) {
|
|
|
53
63
|
initialValue?: string;
|
|
54
64
|
}) {
|
|
55
65
|
const result = await clack.select(opts as Parameters<typeof clack.select>[0]);
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
56
70
|
if (clack.isCancel(result)) { this.cancel(); return ''; }
|
|
71
|
+
|
|
57
72
|
return result as string;
|
|
58
73
|
},
|
|
59
74
|
|
|
@@ -64,7 +79,12 @@ export function ui(options?: UiTheme) {
|
|
|
64
79
|
required?: boolean;
|
|
65
80
|
}) {
|
|
66
81
|
const result = await clack.multiselect(opts as Parameters<typeof clack.multiselect>[0]);
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
67
86
|
if (clack.isCancel(result)) { this.cancel(); return [] as string[]; }
|
|
87
|
+
|
|
68
88
|
return result as string[];
|
|
69
89
|
},
|
|
70
90
|
|
|
@@ -74,6 +94,7 @@ export function ui(options?: UiTheme) {
|
|
|
74
94
|
spinner(message?: string) {
|
|
75
95
|
const s = clack.spinner();
|
|
76
96
|
s.start(message);
|
|
97
|
+
|
|
77
98
|
return {
|
|
78
99
|
update: (msg: string) => s.message(msg),
|
|
79
100
|
stop: (msg?: string) => s.stop(msg),
|
|
@@ -16,12 +16,14 @@ export default class UserHandler extends Crud(User) {
|
|
|
16
16
|
if (user.status === 'inactive') {
|
|
17
17
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already inactive', entity: 'user', operation: 'deactivate' });
|
|
18
18
|
}
|
|
19
|
+
|
|
19
20
|
return this.storage.update(id, { status: 'inactive' });
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/** Active users, projected to the card contract. */
|
|
23
24
|
async active(): Promise<UserCard[]> {
|
|
24
25
|
const users = await this.storage.list({ where: { status: 'active' } });
|
|
26
|
+
|
|
25
27
|
return users.map(({ id, name, status }) => ({ id, name, status }));
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -16,12 +16,14 @@ export default class TaskHandler extends Crud(Task) {
|
|
|
16
16
|
if (task.status === 'done') {
|
|
17
17
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already done', entity: 'task', operation: 'complete' });
|
|
18
18
|
}
|
|
19
|
+
|
|
19
20
|
return this.storage.update(id, { status: 'done' });
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/** Still-open tasks, projected to the card contract. */
|
|
23
24
|
async open(): Promise<TaskCard[]> {
|
|
24
25
|
const tasks = await this.storage.list({ where: { status: 'open' } });
|
|
26
|
+
|
|
25
27
|
return tasks.map(({ id, title, status }) => ({ id, title, status }));
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -22,12 +22,14 @@ export default class PostHandler extends Crud(Post) {
|
|
|
22
22
|
if (post.status === 'published') {
|
|
23
23
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already published', entity: 'post', operation: 'publish' });
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
return this.storage.update(id, { status: 'published' });
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
/** Only published posts exist for the outside world, projected to the card. */
|
|
29
30
|
async listPublished(): Promise<PostCard[]> {
|
|
30
31
|
const posts = await this.storage.list({ where: { status: 'published' } });
|
|
32
|
+
|
|
31
33
|
return posts.map(({ id, title, status }) => ({ id, title, status }));
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -13,12 +13,14 @@ export default class PostHandler extends Crud(Post) {
|
|
|
13
13
|
if (post.status === 'published') {
|
|
14
14
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already published', entity: 'post', operation: 'publish' });
|
|
15
15
|
}
|
|
16
|
+
|
|
16
17
|
return this.storage.update(id, { status: 'published' });
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/** Only published posts, projected to the card. */
|
|
20
21
|
async listPublished(): Promise<PostCard[]> {
|
|
21
22
|
const posts = await this.storage.list({ where: { status: 'published' } });
|
|
23
|
+
|
|
22
24
|
return posts.map(({ id, title, status }) => ({ id, title, status }));
|
|
23
25
|
}
|
|
24
26
|
}
|
|
@@ -25,12 +25,14 @@ export default class PostHandler extends Crud(Post) {
|
|
|
25
25
|
if (post.status === 'published') {
|
|
26
26
|
throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already published', entity: 'post', operation: 'publish' });
|
|
27
27
|
}
|
|
28
|
+
|
|
28
29
|
return this.storage.update(id, { status: 'published' });
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
/** Only published posts, projected to the card. */
|
|
32
33
|
async listPublished(): Promise<PostCard[]> {
|
|
33
34
|
const posts = await this.storage.list({ where: { status: 'published' } });
|
|
35
|
+
|
|
34
36
|
return posts.map(({ id, title, status }) => ({ id, title, status }));
|
|
35
37
|
}
|
|
36
38
|
}
|