@fougere/cli 0.13.1-alpha.0 → 0.14.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.
Files changed (38) hide show
  1. package/dist/.fougere/scan.generated.js +1 -1
  2. package/dist/.fougere/scan.generated.js.map +1 -1
  3. package/dist/app/commands/MigrateCommand.d.ts +2 -2
  4. package/dist/app/commands/MigrateCommand.d.ts.map +1 -1
  5. package/dist/app/commands/MigrateCommand.js +15 -13
  6. package/dist/app/commands/MigrateCommand.js.map +1 -1
  7. package/dist/app/commands/NewCommand.d.ts +4 -12
  8. package/dist/app/commands/NewCommand.d.ts.map +1 -1
  9. package/dist/app/commands/NewCommand.js +51 -85
  10. package/dist/app/commands/NewCommand.js.map +1 -1
  11. package/dist/fronds/analysis/entities/Migrate.d.ts +1 -1
  12. package/dist/fronds/analysis/entities/Migrate.d.ts.map +1 -1
  13. package/dist/fronds/analysis/entities/Migrate.js +1 -1
  14. package/dist/fronds/analysis/entities/Migrate.js.map +1 -1
  15. package/dist/fronds/analysis/handlers/MigrateHandler.d.ts +14 -9
  16. package/dist/fronds/analysis/handlers/MigrateHandler.d.ts.map +1 -1
  17. package/dist/fronds/analysis/handlers/MigrateHandler.js +83 -39
  18. package/dist/fronds/analysis/handlers/MigrateHandler.js.map +1 -1
  19. package/dist/fronds/analysis/services/ProjectScan.d.ts +2 -2
  20. package/dist/fronds/analysis/services/ProjectScan.js +2 -2
  21. package/dist/fronds/scaffold/entities/New.d.ts +2 -5
  22. package/dist/fronds/scaffold/entities/New.d.ts.map +1 -1
  23. package/dist/fronds/scaffold/entities/New.js +5 -8
  24. package/dist/fronds/scaffold/entities/New.js.map +1 -1
  25. package/dist/fronds/scaffold/services/ProjectWriter.d.ts +16 -0
  26. package/dist/fronds/scaffold/services/ProjectWriter.d.ts.map +1 -1
  27. package/dist/fronds/scaffold/services/ProjectWriter.js +84 -12
  28. package/dist/fronds/scaffold/services/ProjectWriter.js.map +1 -1
  29. package/dist/src/composer/Composer.d.ts +61 -0
  30. package/dist/src/composer/Composer.d.ts.map +1 -0
  31. package/dist/src/composer/Composer.js +246 -0
  32. package/dist/src/composer/Composer.js.map +1 -0
  33. package/dist/src/composer/Plan.d.ts +36 -0
  34. package/dist/src/composer/Plan.d.ts.map +1 -0
  35. package/dist/src/composer/Plan.js +70 -0
  36. package/dist/src/composer/Plan.js.map +1 -0
  37. package/package.json +16 -15
  38. package/templates/workspace/package.json +5 -3
@@ -0,0 +1,246 @@
1
+ import { stripVTControlCharacters } from 'node:util';
2
+ import { Prompt, isCancel } from '@clack/core';
3
+ import pc from 'picocolors';
4
+ import { commandOf, treeOf } from './Plan.js';
5
+ const STEPS = ['project', 'fronds', 'apps'];
6
+ const TITLE = { project: 'Project', fronds: 'Fronds', apps: 'Apps' };
7
+ const QUESTION = {
8
+ project: 'Name',
9
+ fronds: 'Which domains does it hold?',
10
+ apps: 'What consumes them?',
11
+ };
12
+ const MEANING = {
13
+ fronds: 'A frond is a domain — its entities and the operations on them. It runs inside an app, or in a process of its own.',
14
+ apps: 'An app is what people use — pages that call the fronds’ operations.',
15
+ };
16
+ const TYPED = /^[a-z0-9._-]$/;
17
+ const ERASE = new Set(['\x7f', '\b']);
18
+ const visible = (line) => stripVTControlCharacters(line).length;
19
+ const padded = (line, width) => line + ' '.repeat(Math.max(0, width - visible(line)));
20
+ /**
21
+ * `fougere new` in three steps — the project, its fronds, its apps — with the tree the plan
22
+ * writes and the command that writes it with no prompt drawn beside every step.
23
+ *
24
+ * ⏎ moves on and ← goes back. In a list, `r` renames the row under the cursor and `+` adds another
25
+ * piece of the same template. Nothing is written here: the answer is a `Plan`, and whether the
26
+ * directory it names may be replaced.
27
+ *
28
+ * Documented: [the CLI](https://fougere.dev/docs/cli).
29
+ */
30
+ export class Composer {
31
+ options;
32
+ static WIDTH = 36;
33
+ step;
34
+ rows;
35
+ name;
36
+ cursor = 0;
37
+ editing;
38
+ asking = false;
39
+ overwrite = false;
40
+ held = false;
41
+ prompt;
42
+ output;
43
+ constructor(options) {
44
+ this.options = options;
45
+ this.name = options.name;
46
+ this.rows = ['fronds', 'apps'].flatMap((kind) => options.catalog[kind].map((template) => ({ kind, template, name: template, on: false })));
47
+ this.step = 'project';
48
+ this.editing = options.name;
49
+ this.output = options.output ?? process.stdout;
50
+ this.prompt = new Prompt({
51
+ render: () => this.frame(),
52
+ validate: () => this.refusal(),
53
+ input: options.input,
54
+ output: options.output,
55
+ }, false);
56
+ this.prompt.value = '';
57
+ this.prompt.on('cursor', (action) => this.act(action));
58
+ this.prompt.on('key', (char) => this.type(char ?? ''));
59
+ this.prompt.on('finalize', () => { this.prompt.value = { plan: this.plan(), overwrite: this.overwrite }; });
60
+ }
61
+ /** What the screen was left on, or `undefined` when it was cancelled. */
62
+ async ask() {
63
+ const answer = await this.prompt.prompt();
64
+ return isCancel(answer) ? undefined : answer;
65
+ }
66
+ plan() {
67
+ const pieces = (kind) => this.rows.filter((row) => row.kind === kind && row.on).map(({ template, name }) => ({ template, name }));
68
+ return { name: this.name, fronds: pieces('fronds'), apps: pieces('apps') };
69
+ }
70
+ frame(columns = this.output.columns || 80) {
71
+ const plan = this.plan();
72
+ const bar = pc.gray('│');
73
+ if (this.prompt.state === 'submit') {
74
+ return `${pc.green('◇')} ${plan.name} ${pc.dim('— ' + summaryOf(plan) + (this.overwrite ? ', replacing what was there' : ''))}`;
75
+ }
76
+ if (this.prompt.state === 'cancel')
77
+ return `${pc.red('■')} ${pc.dim('Cancelled — nothing was written.')}`;
78
+ const left = this.body();
79
+ const right = treeOf(plan).map((line) => pc.dim(line));
80
+ const side = columns >= Composer.WIDTH + Math.max(...right.map(visible)) + 6;
81
+ const body = side
82
+ ? Array.from({ length: Math.max(left.length, right.length) }, (_, at) => (padded(left[at] ?? '', Composer.WIDTH) + (right[at] ?? '')).trimEnd())
83
+ : [...left, '', ...right];
84
+ const refusal = this.prompt.state === 'error' ? this.prompt.error.trim() : '';
85
+ return [
86
+ `${pc.cyan('◆')} ${pc.bold('New Fougere project')}`,
87
+ bar,
88
+ `${bar} ${this.breadcrumb()}`,
89
+ bar,
90
+ `${bar} ${pc.bold(QUESTION[this.step])}`,
91
+ ...(this.step === 'project' ? [] : [`${bar} ${pc.dim(MEANING[this.step])}`, bar]),
92
+ ...body.map((line) => `${bar} ${line}`),
93
+ bar,
94
+ `${bar} ${pc.dim('Same, with no prompt:')} ${commandOf(plan)}`,
95
+ ...(refusal ? [`${bar} ${pc.yellow(refusal)}`] : []),
96
+ `${pc.gray('└')} ${pc.dim(this.hint())}`,
97
+ ].join('\n');
98
+ }
99
+ breadcrumb() {
100
+ const reached = STEPS.indexOf(this.step);
101
+ return STEPS.map((step, at) => {
102
+ if (at === reached)
103
+ return pc.cyan(pc.bold(`● ${TITLE[step]}`));
104
+ return at < reached ? pc.green(`✓ ${TITLE[step]}`) : pc.dim(`○ ${TITLE[step]}`);
105
+ }).join(pc.dim(' › '));
106
+ }
107
+ body() {
108
+ if (this.step === 'project') {
109
+ const name = this.editing === undefined ? this.name : pc.underline(this.editing) + pc.cyan('▌');
110
+ const lines = [`${pc.cyan('▸')} ${name || pc.dim('<name>')}`];
111
+ return this.asking ? [...lines, '', pc.yellow(`${this.name}/ already exists.`), `Replace it? ${pc.dim('y / n')}`] : lines;
112
+ }
113
+ return this.listed().map(({ row, at }) => {
114
+ const pointer = at === this.cursor ? pc.cyan('▸') : ' ';
115
+ const box = row.on ? pc.green('◼') : pc.dim('◻');
116
+ const name = at === this.cursor && this.editing !== undefined ? pc.underline(this.editing) + pc.cyan('▌') : row.name;
117
+ const renamed = row.name === row.template ? '' : pc.dim(` (${row.template})`);
118
+ return `${pointer} ${box} ${name}${renamed}`;
119
+ });
120
+ }
121
+ hint() {
122
+ if (this.asking)
123
+ return 'y replace · n pick another name · esc quit';
124
+ if (this.editing !== undefined)
125
+ return this.step === 'project' ? 'type the name · ⏎ next · esc quit' : 'type the name · ⏎ keep it · esc quit';
126
+ const next = this.step === 'apps' ? '⏎ write' : '⏎ next';
127
+ return `↑↓ move · space check · + another · r rename · ← back · ${next} · esc quit`;
128
+ }
129
+ /** The rows of the current step, each with its index among them. */
130
+ listed() {
131
+ return this.rows.filter((row) => row.kind === this.step).map((row, at) => ({ row, at }));
132
+ }
133
+ current() {
134
+ return this.listed()[this.cursor]?.row;
135
+ }
136
+ go(step) {
137
+ this.step = step;
138
+ this.cursor = 0;
139
+ this.editing = step === 'project' ? this.name : undefined;
140
+ }
141
+ act(action) {
142
+ if (this.editing !== undefined || this.asking)
143
+ return;
144
+ const last = this.listed().length - 1;
145
+ if (action === 'up')
146
+ this.cursor = this.cursor === 0 ? last : this.cursor - 1;
147
+ if (action === 'down')
148
+ this.cursor = this.cursor === last ? 0 : this.cursor + 1;
149
+ if (action === 'left')
150
+ this.go(STEPS[STEPS.indexOf(this.step) - 1] ?? 'project');
151
+ if (action === 'space') {
152
+ const row = this.current();
153
+ if (row)
154
+ row.on = !row.on;
155
+ }
156
+ }
157
+ type(char) {
158
+ if (this.asking)
159
+ return this.answer(char);
160
+ if (this.editing !== undefined)
161
+ return this.edit(char);
162
+ if (char === '\r' && this.step !== 'apps')
163
+ return this.hold(() => this.go(STEPS[STEPS.indexOf(this.step) + 1]));
164
+ if (char === 'r')
165
+ this.editing = this.current()?.name;
166
+ if (char === '+')
167
+ this.another();
168
+ }
169
+ edit(char) {
170
+ const editing = this.editing ?? '';
171
+ if (ERASE.has(char))
172
+ this.editing = editing.slice(0, -1);
173
+ else if (TYPED.test(char))
174
+ this.editing = editing + char;
175
+ if (char !== '\r')
176
+ return;
177
+ if (this.step === 'project')
178
+ return this.hold(() => this.named(editing));
179
+ this.editing = undefined;
180
+ const row = this.current();
181
+ this.hold(() => { if (editing && row)
182
+ row.name = editing; });
183
+ }
184
+ /** The name is kept, and the step left, only once it can be written. */
185
+ named(name) {
186
+ this.name = name;
187
+ this.overwrite = false;
188
+ if (this.options.refusals({ name, fronds: [], apps: [] }, true).length)
189
+ return;
190
+ this.editing = undefined;
191
+ if (this.options.exists(name))
192
+ this.asking = true;
193
+ else
194
+ this.go('fronds');
195
+ }
196
+ answer(char) {
197
+ if (char === 'y') {
198
+ this.overwrite = true;
199
+ this.asking = false;
200
+ this.go('fronds');
201
+ }
202
+ if (char === 'n') {
203
+ this.asking = false;
204
+ this.editing = this.name;
205
+ }
206
+ if (char === '\r')
207
+ this.held = true;
208
+ }
209
+ another() {
210
+ const row = this.current();
211
+ if (!row)
212
+ return;
213
+ const taken = new Set(this.rows.filter((other) => other.kind === row.kind).map((other) => other.name));
214
+ let count = 2;
215
+ while (taken.has(`${row.template}-${count}`))
216
+ count++;
217
+ this.rows.splice(this.rows.indexOf(row) + 1, 0, { ...row, name: `${row.template}-${count}`, on: true });
218
+ this.cursor++;
219
+ this.editing = this.current()?.name;
220
+ }
221
+ /** ⏎ that moves the screen on is not the ⏎ that writes: the next one is. */
222
+ hold(move) {
223
+ this.held = true;
224
+ move();
225
+ }
226
+ refusal() {
227
+ if (this.step === 'project' && !this.asking) {
228
+ const refused = this.options.refusals({ name: this.name, fronds: [], apps: [] }, true)[0];
229
+ if (refused) {
230
+ this.held = false;
231
+ return refused;
232
+ }
233
+ }
234
+ if (this.held) {
235
+ this.held = false;
236
+ return ' ';
237
+ }
238
+ return this.options.refusals(this.plan(), this.overwrite)[0];
239
+ }
240
+ }
241
+ function summaryOf(plan) {
242
+ const names = (kind) => plan[kind].map((piece) => piece.name).join(', ');
243
+ const parts = ['fronds', 'apps'].filter((kind) => plan[kind].length).map((kind) => `${kind}: ${names(kind)}`);
244
+ return parts.join(' · ') || 'an empty workspace';
245
+ }
246
+ //# sourceMappingURL=Composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Composer.js","sourceRoot":"","sources":["../../../src/composer/Composer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export type Kind = 'fronds' | 'apps';
2
+ export interface Piece {
3
+ template: string;
4
+ name: string;
5
+ }
6
+ /**
7
+ * What `fougere new` writes, whoever composed it: the flags state it, the composer builds it,
8
+ * and one writer carries it out once nothing is left to ask.
9
+ */
10
+ export interface Plan {
11
+ name: string;
12
+ fronds: Piece[];
13
+ apps: Piece[];
14
+ }
15
+ export interface Catalog {
16
+ fronds: string[];
17
+ apps: string[];
18
+ }
19
+ export interface Stated {
20
+ name?: string;
21
+ frond?: string;
22
+ app?: string;
23
+ bare?: boolean;
24
+ }
25
+ /** The flags, read as a plan — or `undefined` when they state no composition and the composer should ask. */
26
+ export declare function planOf(stated: Stated): Plan | undefined;
27
+ /** The dual of `planOf`: the line that writes this plan again, with no prompt. */
28
+ export declare function commandOf(plan: Plan, entry?: string): string;
29
+ /** The directories the plan writes, drawn as a tree. */
30
+ export declare function treeOf(plan: Plan): string[];
31
+ /** Everything that stops the plan from being written, in the order a reader fixes it. */
32
+ export declare function refusalsOf(plan: Plan, catalog: Catalog, where: {
33
+ cwd: string;
34
+ replace?: boolean;
35
+ }): string[];
36
+ //# sourceMappingURL=Plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Plan.d.ts","sourceRoot":"","sources":["../../../src/composer/Plan.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,KAAK;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEzD;;;GAGG;AACH,MAAM,WAAW,IAAI;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,IAAI,EAAE,KAAK,EAAE,CAAA;CAAE;AAEtE,MAAM,WAAW,OAAO;IAAG,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE;AAE7D,MAAM,WAAW,MAAM;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE;AAQvF,6GAA6G;AAC7G,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAQvD;AAWD,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,SAAwB,GAAG,MAAM,CAQ3E;AAED,wDAAwD;AACxD,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAe3C;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,EAAE,CAiB5G"}
@@ -0,0 +1,70 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const FLAG = { fronds: '--frond', apps: '--app' };
4
+ const PROJECT = /^[a-z0-9][a-z0-9._-]*$/;
5
+ const PIECE = /^[a-z][a-z0-9-]*$/;
6
+ /** The flags, read as a plan — or `undefined` when they state no composition and the composer should ask. */
7
+ export function planOf(stated) {
8
+ if (!stated.bare && !stated.frond && !stated.app)
9
+ return undefined;
10
+ return {
11
+ name: stated.name ?? '',
12
+ fronds: piecesOf(stated.frond ?? ''),
13
+ apps: piecesOf(stated.app ?? ''),
14
+ };
15
+ }
16
+ function piecesOf(spec) {
17
+ return spec.split(',').map((piece) => piece.trim()).filter(Boolean).map((piece) => {
18
+ const [template, name = template, ...rest] = piece.split(':');
19
+ if (rest.length)
20
+ throw new Error(`'${piece}' is a template and a name, 'blog:news' — one colon at most.`);
21
+ return { template, name };
22
+ });
23
+ }
24
+ /** The dual of `planOf`: the line that writes this plan again, with no prompt. */
25
+ export function commandOf(plan, entry = 'pnpm create fougere') {
26
+ const spec = (pieces) => pieces.map(({ template, name }) => (name === template ? template : `${template}:${name}`)).join(',');
27
+ const flags = ['fronds', 'apps']
28
+ .filter((kind) => plan[kind].length)
29
+ .map((kind) => `${FLAG[kind]} ${spec(plan[kind])}`);
30
+ return [entry, plan.name || '<name>', ...(flags.length ? flags : ['--bare'])].join(' ');
31
+ }
32
+ /** The directories the plan writes, drawn as a tree. */
33
+ export function treeOf(plan) {
34
+ const kinds = ['fronds', 'apps'].filter((kind) => plan[kind].length);
35
+ const top = ['fougere.config.ts', 'package.json', ...kinds.map((kind) => `${kind}/`)];
36
+ const lines = [`${plan.name || '<name>'}/`];
37
+ top.forEach((entry, index) => {
38
+ const last = index === top.length - 1;
39
+ lines.push(`${last ? '└─' : '├─'} ${entry}`);
40
+ const kind = kinds.find((candidate) => `${candidate}/` === entry);
41
+ if (!kind)
42
+ return;
43
+ plan[kind].forEach((piece, at) => lines.push(`${last ? ' ' : '│ '}${at === plan[kind].length - 1 ? '└─' : '├─'} ${piece.name}/`));
44
+ });
45
+ return lines;
46
+ }
47
+ /** Everything that stops the plan from being written, in the order a reader fixes it. */
48
+ export function refusalsOf(plan, catalog, where) {
49
+ const refusals = [];
50
+ if (!plan.name)
51
+ refusals.push('The project has no name — fougere new <name>.');
52
+ else if (!PROJECT.test(plan.name))
53
+ refusals.push(`'${plan.name}' is not a package name: lowercase letters, digits, '.', '_' and '-'.`);
54
+ else if (existsSync(join(where.cwd, plan.name)) && !where.replace)
55
+ refusals.push(`${plan.name}/ already exists — pick another name, or pass --force to replace it.`);
56
+ for (const kind of ['fronds', 'apps']) {
57
+ const seen = new Set();
58
+ for (const { template, name } of plan[kind]) {
59
+ if (!catalog[kind].includes(template))
60
+ refusals.push(`No ${kind} template '${template}' — available: ${catalog[kind].join(', ') || '(none)'}.`);
61
+ if (!PIECE.test(name))
62
+ refusals.push(`'${name}' is not a ${kind === 'fronds' ? 'frond' : 'app'} name: a lowercase letter, then letters, digits and '-'.`);
63
+ if (seen.has(name))
64
+ refusals.push(`Two ${kind} are called '${name}' — rename one.`);
65
+ seen.add(name);
66
+ }
67
+ }
68
+ return refusals;
69
+ }
70
+ //# sourceMappingURL=Plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Plan.js","sourceRoot":"","sources":["../../../src/composer/Plan.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/cli",
3
- "version": "0.13.1-alpha.0",
3
+ "version": "0.14.0-alpha.0",
4
4
  "description": "The Fougere CLI — compose a workspace, serve a frond, call an operation.",
5
5
  "keywords": [
6
6
  "fougere",
@@ -33,33 +33,34 @@
33
33
  "templates"
34
34
  ],
35
35
  "dependencies": {
36
+ "@clack/core": "0.4.2",
36
37
  "@clack/prompts": "^0.10.0",
37
- "@fougere/compiler": "0.13.1-alpha.0",
38
- "@fougere/container": "0.13.1-alpha.0",
39
- "@fougere/core": "0.13.1-alpha.0",
40
- "@fougere/defaults": "0.13.1-alpha.0",
41
- "@fougere/schema": "0.13.1-alpha.0",
42
- "@fougere/testing": "0.13.1-alpha.0",
43
- "@fougere/transport-http": "0.13.1-alpha.0",
38
+ "@fougere/compiler": "0.14.0-alpha.0",
39
+ "@fougere/container": "0.14.0-alpha.0",
40
+ "@fougere/core": "0.14.0-alpha.0",
41
+ "@fougere/defaults": "0.14.0-alpha.0",
42
+ "@fougere/schema": "0.14.0-alpha.0",
43
+ "@fougere/testing": "0.14.0-alpha.0",
44
+ "@fougere/transport-http": "0.14.0-alpha.0",
44
45
  "citty": "^0.2.1",
45
46
  "jiti": "^2.4.2",
46
47
  "picocolors": "^1.1.1",
47
48
  "safe-regex": "^2.1.1"
48
49
  },
49
50
  "devDependencies": {
50
- "@fougere/admin": "0.13.1-alpha.0",
51
- "@fougere/next": "0.13.1-alpha.0",
52
- "@fougere/nuxt": "0.13.1-alpha.0",
53
- "@fougere/oclif": "0.13.1-alpha.0",
54
- "@fougere/react": "0.13.1-alpha.0",
55
- "@fougere/svelte": "0.13.1-alpha.0",
51
+ "@fougere/admin": "0.14.0-alpha.0",
52
+ "@fougere/next": "0.14.0-alpha.0",
53
+ "@fougere/nuxt": "0.14.0-alpha.0",
54
+ "@fougere/oclif": "0.14.0-alpha.0",
55
+ "@fougere/react": "0.14.0-alpha.0",
56
+ "@fougere/svelte": "0.14.0-alpha.0",
56
57
  "vitest": "^4.1.0"
57
58
  },
58
59
  "publishConfig": {
59
60
  "access": "public"
60
61
  },
61
62
  "peerDependencies": {
62
- "@fougere/adapter-sql": "^0.13.1-alpha.0"
63
+ "@fougere/adapter-sql": "^0.14.0-alpha.0"
63
64
  },
64
65
  "peerDependenciesMeta": {
65
66
  "@fougere/adapter-sql": {
@@ -4,15 +4,17 @@
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@12.6.0",
6
6
  "scripts": {
7
- "dev": "pnpm --filter './apps/*' --parallel dev",
8
7
  "build": "pnpm --filter './apps/*' -r build",
9
- "typecheck": "tsc -p fronds"
8
+ "typecheck": "tsc -p fronds",
9
+ "migrate": "fougere migrate --apply"
10
10
  },
11
11
  "dependencies": {
12
12
  "@fougere/core": "latest",
13
- "@fougere/schema": "latest"
13
+ "@fougere/schema": "latest",
14
+ "better-sqlite3": "^13.0.3"
14
15
  },
15
16
  "devDependencies": {
17
+ "@fougere/cli": "latest",
16
18
  "@types/node": "^22.19.15",
17
19
  "typescript": "^5.9.3"
18
20
  }