@ogygie/generate 0.20.0 → 0.22.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/dist/{chunk-WVFHAPGC.js → chunk-ASXSTGY5.js} +471 -112
- package/dist/cli/fill-command.d.ts +14 -2
- package/dist/cli/generate-screen-command.d.ts +11 -2
- package/dist/cli/run.js +55 -159
- package/dist/emit/screen/views.d.ts +2 -0
- package/dist/fill/body.d.ts +2 -2
- package/dist/fill/fill.d.ts +27 -6
- package/dist/fill/model-draw.d.ts +14 -2
- package/dist/fill/view.d.ts +55 -0
- package/dist/hole-shape.d.ts +2 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +43 -1
- package/holes-library/README.md +7 -1
- package/package.json +4 -4
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent The body of a CUSTOM VIEW as a hole (DECISIONS.md D41, D53 — spec
|
|
3
|
+
* ogygie-hosted-mode B10): the text mechanics `fill` needs to treat
|
|
4
|
+
* `views/<Vue>.tsx` like `logic.ts`. A candidate answered by a model is TWO
|
|
5
|
+
* written parts — the import lines it needs, then the body of the component —
|
|
6
|
+
* because a view composes patterns the generator cannot foresee; they go
|
|
7
|
+
* between the `// @hole-imports` and the `// @hole` markers of the file. The
|
|
8
|
+
* imports are judged against a CLOSED catalogue (react, the i18n macro,
|
|
9
|
+
* `@ogygie/ui` and its entries, the product's patterns folder, the sibling
|
|
10
|
+
* views, the feature's own reads), the body against the bans of a logic hole
|
|
11
|
+
* plus what a view may not do: a data hook, a raw table or form, an inline
|
|
12
|
+
* style, an arbitrary Tailwind value or a hex colour (the tokens), an
|
|
13
|
+
* innerHTML. The rules of D24 then apply unchanged: the first candidate green
|
|
14
|
+
* at the view's example test — and at the static render of the nominal
|
|
15
|
+
* state — wins, and enters the library under the view's signature. Pure
|
|
16
|
+
* functions, proven in memory; the command wires the files and the runner.
|
|
17
|
+
*/
|
|
18
|
+
import type { CustomViewPlan, ScreenPlan } from "../emit/screen-plan.js";
|
|
19
|
+
import { type HoleLibraryEntry, type HoleShape } from "../hole-shape.js";
|
|
20
|
+
import { type BodyBan } from "./body.js";
|
|
21
|
+
import type { HoleFillRules } from "./fill.js";
|
|
22
|
+
/** The mark the generator leaves in a view whose body nobody wrote yet. */
|
|
23
|
+
export declare const VIEW_PLACEHOLDER = "data-pattern=\"HoleUnfilled\"";
|
|
24
|
+
/** Whether a view's body is still the generator's placeholder. */
|
|
25
|
+
export declare function isUnfilledViewBody(body: string): boolean;
|
|
26
|
+
export interface ViewCandidateParts {
|
|
27
|
+
/** The import statements, one per entry, as written. */
|
|
28
|
+
imports: string[];
|
|
29
|
+
/** The body lines of the component, two-space indented. */
|
|
30
|
+
body: string;
|
|
31
|
+
}
|
|
32
|
+
/** A candidate text split into its leading import statements (multi-line ones included) and the body that follows. */
|
|
33
|
+
export declare function splitViewCandidate(text: string): ViewCandidateParts;
|
|
34
|
+
/** The canonical text of a view candidate: its import lines, then its body — what the library stores and `writeBody` splits. */
|
|
35
|
+
export declare function viewCandidateTextOf(parts: ViewCandidateParts): string;
|
|
36
|
+
/** A model's answer reduced to a canonical candidate: the fenced block when there is one, the imports first, the body extracted as a logic body is. */
|
|
37
|
+
export declare function extractViewCandidate(answer: string): string;
|
|
38
|
+
/** The sources a model-written view may import from — the closed catalogue of D53 — besides a type-only import, which is harmless anywhere. */
|
|
39
|
+
export declare function isAllowedViewImportSource(source: string): boolean;
|
|
40
|
+
/** The import statements that leave the catalogue — each named by its source. */
|
|
41
|
+
export declare function forbiddenInViewImports(imports: readonly string[]): string[];
|
|
42
|
+
/** What the body of a view may not carry: a logic body's bans, and what a view in particular never does. */
|
|
43
|
+
export declare const VIEW_BODY_BANS: readonly BodyBan[];
|
|
44
|
+
/** The rules a view candidate breaks — its imports against the catalogue, its body against the bans; empty when it may be tested. */
|
|
45
|
+
export declare function forbiddenInViewCandidate(text: string): string[];
|
|
46
|
+
/** The body currently written for a view, read between its markers — empty when the markers are absent. */
|
|
47
|
+
export declare function currentViewBody(file: string, holeId: string): string;
|
|
48
|
+
/** `views/<Vue>.tsx` with its two written parts replaced — the candidate's imports and body, or the placeholder and no import when the candidate is null — everything else byte for byte. */
|
|
49
|
+
export declare function replaceViewSections(file: string, holeId: string, candidate: string | null): string;
|
|
50
|
+
/** The literal signature of a custom view: its props and its function line, as the file carries them. */
|
|
51
|
+
export declare function customViewSignatureText(view: CustomViewPlan): string;
|
|
52
|
+
/** The shape of a custom view: the normalized types it receives, by position, and the kinds of the writes it may trigger. */
|
|
53
|
+
export declare function customViewShapeOf(view: CustomViewPlan): HoleShape;
|
|
54
|
+
/** The rules `fillHole` applies to the body of a custom view (D53): placeholder, catalogue and bans, library by signature then by shape, entry under the view's signature. */
|
|
55
|
+
export declare function customViewRules(view: CustomViewPlan, plan: ScreenPlan, library: readonly HoleLibraryEntry[]): HoleFillRules;
|
package/dist/hole-shape.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare const HoleShapeSchema: z.ZodObject<{
|
|
|
10
10
|
derive: "derive";
|
|
11
11
|
project: "project";
|
|
12
12
|
view: "view";
|
|
13
|
+
"custom-view": "custom-view";
|
|
13
14
|
}>;
|
|
14
15
|
reads: z.ZodArray<z.ZodString>;
|
|
15
16
|
columns: z.ZodArray<z.ZodString>;
|
|
@@ -47,6 +48,7 @@ export declare const HoleLibraryEntrySchema: z.ZodObject<{
|
|
|
47
48
|
derive: "derive";
|
|
48
49
|
project: "project";
|
|
49
50
|
view: "view";
|
|
51
|
+
"custom-view": "custom-view";
|
|
50
52
|
}>;
|
|
51
53
|
reads: z.ZodArray<z.ZodString>;
|
|
52
54
|
columns: z.ZodArray<z.ZodString>;
|
package/dist/index.d.ts
CHANGED
|
@@ -38,8 +38,10 @@ export { applyGeneratedContracts } from "./emit/spec-contracts.js";
|
|
|
38
38
|
export { boundScreenBehaviorsOf, type LoadedConsumedForVerify } from "./verify-generation.js";
|
|
39
39
|
export { FrontTargetSchema, type FrontTarget } from "./manifest-generation.schema.js";
|
|
40
40
|
export { DERIVED_READ_GUARD, consumableOperationsOf, derivedReadsOf, readIdOfInputSchema } from "./consumed-feature.js";
|
|
41
|
-
export { fillHole, fillFeature, DEFAULT_FILL_OPTIONS, type Candidate, type FillDeps, type FillOptions, type HoleFillInput, type HoleFillResult, type FeatureFillSummary } from "./fill/fill.js";
|
|
42
|
-
export { replaceHoleBody, extractCandidateBody, forbiddenInBody, isTodoBody, BODY_BANS } from "./fill/body.js";
|
|
43
|
-
export { createModelDrawer, DEFAULT_FILL_MODELS, HOLE_SYSTEM_PROMPT, type FillModels, type ModelDrawer } from "./fill/model-draw.js";
|
|
44
|
-
export {
|
|
41
|
+
export { fillHole, fillFeature, logicHoleRules, DEFAULT_FILL_OPTIONS, type Candidate, type FillDeps, type FillOptions, type HoleFillInput, type HoleFillResult, type HoleFillRules, type FeatureFillSummary } from "./fill/fill.js";
|
|
42
|
+
export { replaceHoleBody, extractCandidateBody, forbiddenInBody, isTodoBody, BODY_BANS, type BodyBan } from "./fill/body.js";
|
|
43
|
+
export { createModelDrawer, DEFAULT_FILL_MODELS, HOLE_SYSTEM_PROMPT, VIEW_SYSTEM_PROMPT, VIEW_DRAWER_OPTIONS, type FillModels, type ModelDrawer, type ModelDrawerOptions } from "./fill/model-draw.js";
|
|
44
|
+
export { VIEW_PLACEHOLDER, VIEW_BODY_BANS, isUnfilledViewBody, splitViewCandidate, viewCandidateTextOf, extractViewCandidate, isAllowedViewImportSource, forbiddenInViewImports, forbiddenInViewCandidate, currentViewBody, replaceViewSections, customViewSignatureText, customViewShapeOf, customViewRules, type ViewCandidateParts, } from "./fill/view.js";
|
|
45
|
+
export { recordLibraryEntry, scrubbedEnvironment, parseFillFlags, viewExampleTestName, NOMINAL_PREVIEW_TEST_NAME, FILL_NEEDS_OPERATOR_EXIT } from "./cli/fill-command.js";
|
|
46
|
+
export { screenPlanOf, type ScreenPlanLookup } from "./cli/generate-screen-command.js";
|
|
45
47
|
export { generationGrammarCard } from "./prompt-card.js";
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
DEFAULT_FILL_OPTIONS,
|
|
12
12
|
DERIVED_READ_GUARD,
|
|
13
13
|
EMPTY_GUARD_REGISTRY,
|
|
14
|
+
FILL_NEEDS_OPERATOR_EXIT,
|
|
14
15
|
FORM_RENDERS,
|
|
15
16
|
FORM_STATES,
|
|
16
17
|
FormViewSchema,
|
|
@@ -44,6 +45,7 @@ import {
|
|
|
44
45
|
ModuleExportSchema,
|
|
45
46
|
ModuleTypeSchema,
|
|
46
47
|
MotifsSchema,
|
|
48
|
+
NOMINAL_PREVIEW_TEST_NAME,
|
|
47
49
|
OPENING_KEYWORD,
|
|
48
50
|
OperationSchema,
|
|
49
51
|
READ_RENDERS,
|
|
@@ -56,6 +58,10 @@ import {
|
|
|
56
58
|
ScreenHoleSchema,
|
|
57
59
|
TableDeclarationSchema,
|
|
58
60
|
TableRefSchema,
|
|
61
|
+
VIEW_BODY_BANS,
|
|
62
|
+
VIEW_DRAWER_OPTIONS,
|
|
63
|
+
VIEW_PLACEHOLDER,
|
|
64
|
+
VIEW_SYSTEM_PROMPT,
|
|
59
65
|
ViewSchema,
|
|
60
66
|
WRITE_OPERATION_KINDS,
|
|
61
67
|
acceptExamplesOf,
|
|
@@ -80,6 +86,10 @@ import {
|
|
|
80
86
|
consumerOf,
|
|
81
87
|
contractViolationCodeOf,
|
|
82
88
|
createModelDrawer,
|
|
89
|
+
currentViewBody,
|
|
90
|
+
customViewRules,
|
|
91
|
+
customViewShapeOf,
|
|
92
|
+
customViewSignatureText,
|
|
83
93
|
deepOverlay,
|
|
84
94
|
deniedCodeOf,
|
|
85
95
|
derivedReadsOf,
|
|
@@ -92,10 +102,13 @@ import {
|
|
|
92
102
|
extractCandidateBody,
|
|
93
103
|
extractGenerationSection,
|
|
94
104
|
extractSpecContracts,
|
|
105
|
+
extractViewCandidate,
|
|
95
106
|
fieldNamesOf,
|
|
96
107
|
fillFeature,
|
|
97
108
|
fillHole,
|
|
98
109
|
forbiddenInBody,
|
|
110
|
+
forbiddenInViewCandidate,
|
|
111
|
+
forbiddenInViewImports,
|
|
99
112
|
generateFeature,
|
|
100
113
|
generateScreen,
|
|
101
114
|
hasSameFieldsAs,
|
|
@@ -104,16 +117,19 @@ import {
|
|
|
104
117
|
intentForManifest,
|
|
105
118
|
intentOfSpec,
|
|
106
119
|
invalidSampleOf,
|
|
120
|
+
isAllowedViewImportSource,
|
|
107
121
|
isAsyncHole,
|
|
108
122
|
isHttpOperation,
|
|
109
123
|
isKeyedOperation,
|
|
110
124
|
isLiteralValue,
|
|
111
125
|
isTodoBody,
|
|
126
|
+
isUnfilledViewBody,
|
|
112
127
|
isWriteOperation,
|
|
113
128
|
labelOf,
|
|
114
129
|
libraryEntryOf,
|
|
115
130
|
libraryFileNameOf,
|
|
116
131
|
loadHolesLibrary,
|
|
132
|
+
logicHoleRules,
|
|
117
133
|
manifestEntryDrift,
|
|
118
134
|
manifestEntryOf,
|
|
119
135
|
migrationFileNameFor,
|
|
@@ -143,11 +159,13 @@ import {
|
|
|
143
159
|
recordLibraryEntry,
|
|
144
160
|
refusalsOf,
|
|
145
161
|
replaceHoleBody,
|
|
162
|
+
replaceViewSections,
|
|
146
163
|
routeDescriptionOf,
|
|
147
164
|
sampleOf,
|
|
148
165
|
screenBodyDefault,
|
|
149
166
|
screenBodyPath,
|
|
150
167
|
screenCaseKey,
|
|
168
|
+
screenPlanOf,
|
|
151
169
|
screenVocabularyOf,
|
|
152
170
|
scrubbedEnvironment,
|
|
153
171
|
serializeManifest,
|
|
@@ -157,6 +175,7 @@ import {
|
|
|
157
175
|
signatureTextOf,
|
|
158
176
|
specGeneratedStart,
|
|
159
177
|
splitTopLevelSections,
|
|
178
|
+
splitViewCandidate,
|
|
160
179
|
tableNameOf,
|
|
161
180
|
tableRefOf,
|
|
162
181
|
tablesOf,
|
|
@@ -165,8 +184,10 @@ import {
|
|
|
165
184
|
validationOf,
|
|
166
185
|
verifyGeneration,
|
|
167
186
|
viewBodiesOf,
|
|
187
|
+
viewCandidateTextOf,
|
|
188
|
+
viewExampleTestName,
|
|
168
189
|
vocabularyOf
|
|
169
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-ASXSTGY5.js";
|
|
170
191
|
|
|
171
192
|
// src/prompt-card.ts
|
|
172
193
|
var phrase = (caseKey) => caseKey.replace(/^with:/u, "avec ").replace(/^without:/u, "sans ");
|
|
@@ -243,6 +264,7 @@ export {
|
|
|
243
264
|
DEFAULT_FILL_OPTIONS,
|
|
244
265
|
DERIVED_READ_GUARD,
|
|
245
266
|
EMPTY_GUARD_REGISTRY,
|
|
267
|
+
FILL_NEEDS_OPERATOR_EXIT,
|
|
246
268
|
FORM_RENDERS,
|
|
247
269
|
FORM_STATES,
|
|
248
270
|
FormViewSchema,
|
|
@@ -275,6 +297,7 @@ export {
|
|
|
275
297
|
ModuleExportSchema,
|
|
276
298
|
ModuleTypeSchema,
|
|
277
299
|
MotifsSchema,
|
|
300
|
+
NOMINAL_PREVIEW_TEST_NAME,
|
|
278
301
|
OPENING_KEYWORD,
|
|
279
302
|
OperationSchema,
|
|
280
303
|
READ_RENDERS,
|
|
@@ -287,6 +310,10 @@ export {
|
|
|
287
310
|
ScreenHoleSchema,
|
|
288
311
|
TableDeclarationSchema,
|
|
289
312
|
TableRefSchema,
|
|
313
|
+
VIEW_BODY_BANS,
|
|
314
|
+
VIEW_DRAWER_OPTIONS,
|
|
315
|
+
VIEW_PLACEHOLDER,
|
|
316
|
+
VIEW_SYSTEM_PROMPT,
|
|
290
317
|
ViewSchema,
|
|
291
318
|
WRITE_OPERATION_KINDS,
|
|
292
319
|
acceptExamplesOf,
|
|
@@ -311,6 +338,10 @@ export {
|
|
|
311
338
|
consumerOf,
|
|
312
339
|
contractViolationCodeOf,
|
|
313
340
|
createModelDrawer,
|
|
341
|
+
currentViewBody,
|
|
342
|
+
customViewRules,
|
|
343
|
+
customViewShapeOf,
|
|
344
|
+
customViewSignatureText,
|
|
314
345
|
deepOverlay,
|
|
315
346
|
deniedCodeOf,
|
|
316
347
|
derivedReadsOf,
|
|
@@ -323,10 +354,13 @@ export {
|
|
|
323
354
|
extractCandidateBody,
|
|
324
355
|
extractGenerationSection,
|
|
325
356
|
extractSpecContracts,
|
|
357
|
+
extractViewCandidate,
|
|
326
358
|
fieldNamesOf,
|
|
327
359
|
fillFeature,
|
|
328
360
|
fillHole,
|
|
329
361
|
forbiddenInBody,
|
|
362
|
+
forbiddenInViewCandidate,
|
|
363
|
+
forbiddenInViewImports,
|
|
330
364
|
generateFeature,
|
|
331
365
|
generateScreen,
|
|
332
366
|
generationGrammarCard,
|
|
@@ -336,16 +370,19 @@ export {
|
|
|
336
370
|
intentForManifest,
|
|
337
371
|
intentOfSpec,
|
|
338
372
|
invalidSampleOf,
|
|
373
|
+
isAllowedViewImportSource,
|
|
339
374
|
isAsyncHole,
|
|
340
375
|
isHttpOperation,
|
|
341
376
|
isKeyedOperation,
|
|
342
377
|
isLiteralValue,
|
|
343
378
|
isTodoBody,
|
|
379
|
+
isUnfilledViewBody,
|
|
344
380
|
isWriteOperation,
|
|
345
381
|
labelOf,
|
|
346
382
|
libraryEntryOf,
|
|
347
383
|
libraryFileNameOf,
|
|
348
384
|
loadHolesLibrary,
|
|
385
|
+
logicHoleRules,
|
|
349
386
|
manifestEntryDrift,
|
|
350
387
|
manifestEntryOf,
|
|
351
388
|
migrationFileNameFor,
|
|
@@ -375,11 +412,13 @@ export {
|
|
|
375
412
|
recordLibraryEntry,
|
|
376
413
|
refusalsOf,
|
|
377
414
|
replaceHoleBody,
|
|
415
|
+
replaceViewSections,
|
|
378
416
|
routeDescriptionOf,
|
|
379
417
|
sampleOf,
|
|
380
418
|
screenBodyDefault,
|
|
381
419
|
screenBodyPath,
|
|
382
420
|
screenCaseKey,
|
|
421
|
+
screenPlanOf,
|
|
383
422
|
screenVocabularyOf,
|
|
384
423
|
scrubbedEnvironment,
|
|
385
424
|
serializeManifest,
|
|
@@ -389,6 +428,7 @@ export {
|
|
|
389
428
|
signatureTextOf,
|
|
390
429
|
specGeneratedStart,
|
|
391
430
|
splitTopLevelSections,
|
|
431
|
+
splitViewCandidate,
|
|
392
432
|
tableNameOf,
|
|
393
433
|
tableRefOf,
|
|
394
434
|
tablesOf,
|
|
@@ -397,5 +437,7 @@ export {
|
|
|
397
437
|
validationOf,
|
|
398
438
|
verifyGeneration,
|
|
399
439
|
viewBodiesOf,
|
|
440
|
+
viewCandidateTextOf,
|
|
441
|
+
viewExampleTestName,
|
|
400
442
|
vocabularyOf
|
|
401
443
|
};
|
package/holes-library/README.md
CHANGED
|
@@ -10,7 +10,7 @@ porte sous `// @hole <id>`.
|
|
|
10
10
|
"hole": "<id du trou>",
|
|
11
11
|
"signature": "<signature générée>",
|
|
12
12
|
"signatureHash": "<16 hex — sha256 du texte de la signature>",
|
|
13
|
-
"shape": { "kind": "validate | transform", "reads": ["<type normalisé par position>"], "columns": ["…"], "codeRole": "operation-refusal | motif-rejection", "returns": "void | rows:<n>" },
|
|
13
|
+
"shape": { "kind": "validate | transform | derive | project | view | custom-view", "reads": ["<type normalisé par position>"], "columns": ["…"], "codeRole": "operation-refusal | motif-rejection | none", "returns": "void | rows:<n> | <type dérivé> | output | view:<forme> | jsx" },
|
|
14
14
|
"shapeHash": "<16 hex — sha256 du JSON de la forme>",
|
|
15
15
|
"errorCode": "<code que le trou rend>",
|
|
16
16
|
"bodyTemplate": "<corps en gabarit : {{read:n}}, {{column:n}}, {{code}}, {{rowType}} à la place des noms de la feature>",
|
|
@@ -31,3 +31,9 @@ Lot 2 : les entrées sont écrites par `pnpm ogygie:holes-library <feature>`,
|
|
|
31
31
|
qui enregistre les corps qu'un humain a remplis (chemin `human`, `model: null`).
|
|
32
32
|
La recherche par forme au remplissage, le tirage-vérification et l'escalade
|
|
33
33
|
sont le lot 2 bis.
|
|
34
|
+
|
|
35
|
+
Depuis la 0.21.0 (D53), le corps d'une vue `custom` d'un écran entre ici
|
|
36
|
+
aussi : `kind: "custom-view"`, `reads` les types normalisés des champs reçus,
|
|
37
|
+
`columns` les genres des écritures que la vue peut déclencher, `returns: "jsx"`,
|
|
38
|
+
la signature étant les props et la ligne de fonction de `views/<Vue>.tsx` ; le
|
|
39
|
+
`bodyTemplate` porte les lignes d'import puis le corps, sans gabarit.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogygie/generate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Ogygie generator: reads the `# Génération` block of a spec and its schemas.ts, derives everything deterministic without a model (routes, pipeline, database, factories, tests, screens, previews), fills the typed holes of logic.ts by library, draw and escalation, and draws the first schemas.ts of a new feature — judged by the gates. Sixth package of the lockstep (D55).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ogygie/core": "0.
|
|
32
|
+
"@ogygie/core": "0.22.0",
|
|
33
33
|
"tsx": "^4.20.0",
|
|
34
34
|
"yaml": "^2.9.0",
|
|
35
35
|
"zod": "^4.0.0"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@lingui/babel-plugin-lingui-macro": "^5.9.5",
|
|
39
39
|
"@lingui/core": "^5.9.5",
|
|
40
40
|
"@lingui/react": "^5.9.5",
|
|
41
|
-
"@ogygie/ui": "0.
|
|
41
|
+
"@ogygie/ui": "0.22.0",
|
|
42
42
|
"@starter/api": "0.1.0",
|
|
43
43
|
"@tanstack/react-query": "^5.102.2",
|
|
44
44
|
"@tanstack/react-router": "^1.170.32",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"react-dom": "^19.2.8",
|
|
54
54
|
"typescript": "^5.8.0",
|
|
55
55
|
"vite": "^7.3.6",
|
|
56
|
-
"vitest": "^
|
|
56
|
+
"vitest": "^4.1.12"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsx scripts/build.ts",
|