@beignet/cli 0.0.24 → 0.0.25
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/CHANGELOG.md +13 -0
- package/README.md +45 -4
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +51 -0
- package/dist/config.js.map +1 -1
- package/dist/db.d.ts +30 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +201 -1
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +157 -235
- package/dist/inspect.js.map +1 -1
- package/dist/provider-audit.d.ts +131 -0
- package/dist/provider-audit.d.ts.map +1 -0
- package/dist/provider-audit.js +1013 -0
- package/dist/provider-audit.js.map +1 -0
- package/package.json +2 -2
- package/skills/app-structure/SKILL.md +22 -4
- package/src/config.ts +99 -0
- package/src/db.ts +316 -1
- package/src/index.ts +180 -1
- package/src/inspect.ts +298 -369
- package/src/provider-audit.ts +1681 -0
package/src/index.ts
CHANGED
|
@@ -107,6 +107,27 @@ type DbFlags = {
|
|
|
107
107
|
dryRun?: boolean;
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
type DatabaseSchemaDialect = "sqlite" | "postgres" | "mysql";
|
|
111
|
+
type DatabaseSchemaTable = "audit" | "idempotency" | "outbox";
|
|
112
|
+
|
|
113
|
+
const databaseSchemaDialectChoices = [
|
|
114
|
+
"sqlite",
|
|
115
|
+
"postgres",
|
|
116
|
+
"mysql",
|
|
117
|
+
] as const satisfies readonly DatabaseSchemaDialect[];
|
|
118
|
+
|
|
119
|
+
const databaseSchemaTableChoices = [
|
|
120
|
+
"audit",
|
|
121
|
+
"idempotency",
|
|
122
|
+
"outbox",
|
|
123
|
+
] as const satisfies readonly DatabaseSchemaTable[];
|
|
124
|
+
|
|
125
|
+
type DbSchemaGenerateFlags = DbFlags & {
|
|
126
|
+
dialect?: DatabaseSchemaDialect;
|
|
127
|
+
tables?: readonly DatabaseSchemaTable[];
|
|
128
|
+
output?: string;
|
|
129
|
+
};
|
|
130
|
+
|
|
110
131
|
type TaskRunFlags = {
|
|
111
132
|
json?: boolean;
|
|
112
133
|
input?: string;
|
|
@@ -142,6 +163,11 @@ type DoctorFlags = {
|
|
|
142
163
|
format?: OutputFormat;
|
|
143
164
|
};
|
|
144
165
|
|
|
166
|
+
type ProviderAuditFlags = {
|
|
167
|
+
json?: boolean;
|
|
168
|
+
cwd?: string;
|
|
169
|
+
};
|
|
170
|
+
|
|
145
171
|
const parseString = (input: string): string => input;
|
|
146
172
|
const parsePositiveInteger = (input: string): number => {
|
|
147
173
|
const value = Number(input);
|
|
@@ -209,11 +235,38 @@ const lintFlagParameters = {
|
|
|
209
235
|
format: formatFlag,
|
|
210
236
|
} satisfies FlagParametersForType<LintFlags, CliContext>;
|
|
211
237
|
|
|
238
|
+
const providerAuditFlagParameters = {
|
|
239
|
+
json: jsonFlag,
|
|
240
|
+
cwd: cwdFlag,
|
|
241
|
+
} satisfies FlagParametersForType<ProviderAuditFlags, CliContext>;
|
|
242
|
+
|
|
212
243
|
const dbFlagParameters = {
|
|
213
244
|
json: jsonFlag,
|
|
214
245
|
dryRun: dryRunFlag,
|
|
215
246
|
} satisfies FlagParametersForType<DbFlags, CliContext>;
|
|
216
247
|
|
|
248
|
+
const dbSchemaGenerateFlagParameters = {
|
|
249
|
+
...dbFlagParameters,
|
|
250
|
+
dialect: {
|
|
251
|
+
kind: "enum",
|
|
252
|
+
values: databaseSchemaDialectChoices,
|
|
253
|
+
optional: true,
|
|
254
|
+
brief:
|
|
255
|
+
"Drizzle dialect to generate for. Inferred from server/providers.ts when omitted.",
|
|
256
|
+
},
|
|
257
|
+
tables: {
|
|
258
|
+
kind: "enum",
|
|
259
|
+
values: databaseSchemaTableChoices,
|
|
260
|
+
optional: true,
|
|
261
|
+
variadic: ",",
|
|
262
|
+
brief:
|
|
263
|
+
"Provider tables to generate as a comma-separated list. Defaults to audit,idempotency,outbox.",
|
|
264
|
+
},
|
|
265
|
+
output: parsedStringFlag(
|
|
266
|
+
"Generated schema file. Defaults to infra/db/schema/beignet.ts.",
|
|
267
|
+
),
|
|
268
|
+
} satisfies FlagParametersForType<DbSchemaGenerateFlags, CliContext>;
|
|
269
|
+
|
|
217
270
|
const taskRunFlagParameters = {
|
|
218
271
|
json: jsonFlag,
|
|
219
272
|
input: parsedStringFlag("JSON input passed to the task schema."),
|
|
@@ -557,6 +610,44 @@ const mcpCommand = buildCommand<McpFlags, [], CliContext>({
|
|
|
557
610
|
},
|
|
558
611
|
});
|
|
559
612
|
|
|
613
|
+
const providerAuditCommand = buildCommand<ProviderAuditFlags, [], CliContext>({
|
|
614
|
+
docs: {
|
|
615
|
+
brief: "Audit installed Beignet provider setup.",
|
|
616
|
+
fullDescription:
|
|
617
|
+
"Reports installed provider packages, metadata validity, registration, provider env, required tables, app ports, and variants. This command is report-only; doctor remains the enforcement surface.",
|
|
618
|
+
},
|
|
619
|
+
parameters: {
|
|
620
|
+
flags: providerAuditFlagParameters,
|
|
621
|
+
},
|
|
622
|
+
loader: async () => {
|
|
623
|
+
const { auditProviders, formatProviderAudit } = await import(
|
|
624
|
+
"./provider-audit.js"
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
return async function runProviderAudit(
|
|
628
|
+
this: CliContext,
|
|
629
|
+
flags: ProviderAuditFlags,
|
|
630
|
+
) {
|
|
631
|
+
const result = await auditProviders({ cwd: flags.cwd });
|
|
632
|
+
writeOutput(
|
|
633
|
+
this,
|
|
634
|
+
flags.json
|
|
635
|
+
? JSON.stringify(result, null, 2)
|
|
636
|
+
: formatProviderAudit(result),
|
|
637
|
+
);
|
|
638
|
+
};
|
|
639
|
+
},
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
const providerRoutes = buildRouteMap({
|
|
643
|
+
docs: {
|
|
644
|
+
brief: "Inspect Beignet provider setup.",
|
|
645
|
+
},
|
|
646
|
+
routes: {
|
|
647
|
+
audit: providerAuditCommand,
|
|
648
|
+
},
|
|
649
|
+
});
|
|
650
|
+
|
|
560
651
|
type DatabaseCommandName = "generate" | "migrate" | "reset" | "seed";
|
|
561
652
|
|
|
562
653
|
function databaseCommand(command: DatabaseCommandName) {
|
|
@@ -591,6 +682,52 @@ function databaseCommand(command: DatabaseCommandName) {
|
|
|
591
682
|
});
|
|
592
683
|
}
|
|
593
684
|
|
|
685
|
+
const dbSchemaGenerateCommand = buildCommand<
|
|
686
|
+
DbSchemaGenerateFlags,
|
|
687
|
+
[],
|
|
688
|
+
CliContext
|
|
689
|
+
>({
|
|
690
|
+
docs: {
|
|
691
|
+
brief: "Generate provider-owned Drizzle schema exports.",
|
|
692
|
+
fullDescription:
|
|
693
|
+
"Writes an app-owned schema file that re-exports Beignet provider tables, then updates the schema index. Run beignet db generate afterward to let the app's Drizzle Kit script create migrations.",
|
|
694
|
+
},
|
|
695
|
+
parameters: {
|
|
696
|
+
flags: dbSchemaGenerateFlagParameters,
|
|
697
|
+
},
|
|
698
|
+
loader: async () => {
|
|
699
|
+
const { generateDatabaseSchema } = await import("./db.js");
|
|
700
|
+
|
|
701
|
+
return async function runDbSchemaGenerate(
|
|
702
|
+
this: CliContext,
|
|
703
|
+
flags: DbSchemaGenerateFlags,
|
|
704
|
+
) {
|
|
705
|
+
const result = await generateDatabaseSchema({
|
|
706
|
+
dialect: flags.dialect,
|
|
707
|
+
tables: flags.tables,
|
|
708
|
+
output: flags.output,
|
|
709
|
+
dryRun: Boolean(flags.dryRun),
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
writeOutput(
|
|
713
|
+
this,
|
|
714
|
+
flags.json
|
|
715
|
+
? JSON.stringify(result, null, 2)
|
|
716
|
+
: databaseSchemaGenerateNextSteps(result),
|
|
717
|
+
);
|
|
718
|
+
};
|
|
719
|
+
},
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
const dbSchemaRoutes = buildRouteMap({
|
|
723
|
+
docs: {
|
|
724
|
+
brief: "Generate Beignet database schema helpers.",
|
|
725
|
+
},
|
|
726
|
+
routes: {
|
|
727
|
+
generate: dbSchemaGenerateCommand,
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
|
|
594
731
|
const dbRoutes = buildRouteMap({
|
|
595
732
|
docs: {
|
|
596
733
|
brief: "Run Beignet database lifecycle commands.",
|
|
@@ -599,6 +736,7 @@ const dbRoutes = buildRouteMap({
|
|
|
599
736
|
generate: databaseCommand("generate"),
|
|
600
737
|
migrate: databaseCommand("migrate"),
|
|
601
738
|
reset: databaseCommand("reset"),
|
|
739
|
+
schema: dbSchemaRoutes,
|
|
602
740
|
seed: databaseCommand("seed"),
|
|
603
741
|
},
|
|
604
742
|
});
|
|
@@ -1214,6 +1352,7 @@ Run npm create beignet@latest (or bun create beignet) to scaffold a new app.`,
|
|
|
1214
1352
|
make: makeRoutes,
|
|
1215
1353
|
mcp: mcpCommand,
|
|
1216
1354
|
outbox: outboxRoutes,
|
|
1355
|
+
providers: providerRoutes,
|
|
1217
1356
|
routes: routesCommand,
|
|
1218
1357
|
schedule: scheduleRoutes,
|
|
1219
1358
|
task: taskRoutes,
|
|
@@ -1278,6 +1417,18 @@ type DatabaseCommandNextStepsResult = {
|
|
|
1278
1417
|
dryRun: boolean;
|
|
1279
1418
|
};
|
|
1280
1419
|
|
|
1420
|
+
type DatabaseSchemaGenerateNextStepsResult = {
|
|
1421
|
+
cwd: string;
|
|
1422
|
+
dialect: DatabaseSchemaDialect;
|
|
1423
|
+
tables: DatabaseSchemaTable[];
|
|
1424
|
+
output: string;
|
|
1425
|
+
indexFile: string;
|
|
1426
|
+
createdFiles: string[];
|
|
1427
|
+
updatedFiles: string[];
|
|
1428
|
+
skippedFiles: string[];
|
|
1429
|
+
dryRun: boolean;
|
|
1430
|
+
};
|
|
1431
|
+
|
|
1281
1432
|
type AppTaskRunNextStepsResult = {
|
|
1282
1433
|
name: string;
|
|
1283
1434
|
durationMs: number;
|
|
@@ -1432,7 +1583,12 @@ function isEnvRequiredProviderIntegration(
|
|
|
1432
1583
|
);
|
|
1433
1584
|
}
|
|
1434
1585
|
|
|
1435
|
-
function changedFileLines(
|
|
1586
|
+
function changedFileLines(
|
|
1587
|
+
result: Pick<
|
|
1588
|
+
MakeNextStepsResult,
|
|
1589
|
+
"createdFiles" | "updatedFiles" | "skippedFiles"
|
|
1590
|
+
>,
|
|
1591
|
+
): {
|
|
1436
1592
|
changedFiles: string;
|
|
1437
1593
|
skippedFiles: string;
|
|
1438
1594
|
} {
|
|
@@ -1482,6 +1638,29 @@ Command:
|
|
|
1482
1638
|
${command}`;
|
|
1483
1639
|
}
|
|
1484
1640
|
|
|
1641
|
+
function databaseSchemaGenerateNextSteps(
|
|
1642
|
+
result: DatabaseSchemaGenerateNextStepsResult,
|
|
1643
|
+
): string {
|
|
1644
|
+
const { changedFiles, skippedFiles } = changedFileLines({
|
|
1645
|
+
createdFiles: result.createdFiles,
|
|
1646
|
+
updatedFiles: result.updatedFiles,
|
|
1647
|
+
skippedFiles: result.skippedFiles,
|
|
1648
|
+
});
|
|
1649
|
+
const prefix = result.dryRun ? "Would generate" : "Generated";
|
|
1650
|
+
const tables = result.tables.join(", ");
|
|
1651
|
+
|
|
1652
|
+
return `${prefix} Beignet ${result.dialect} database schema (${tables}) in ${result.cwd}
|
|
1653
|
+
|
|
1654
|
+
Changed files:
|
|
1655
|
+
${changedFiles || " none"}
|
|
1656
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
1657
|
+
|
|
1658
|
+
Next steps:
|
|
1659
|
+
Run beignet db generate to produce app-owned Drizzle migrations.
|
|
1660
|
+
Run beignet db migrate to apply the migration.
|
|
1661
|
+
Run beignet doctor --strict to check provider setup.`;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1485
1664
|
function makeFeatureNextSteps(result: MakeNextStepsResult): string {
|
|
1486
1665
|
return makeNextSteps(result, "feature slice", [
|
|
1487
1666
|
"Use make feature for product capabilities and workflows. Use make resource when the concept is mostly CRUD-shaped.",
|