@beignet/cli 0.0.31 → 0.0.33
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 +107 -0
- package/README.md +70 -17
- package/dist/check.d.ts +2 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +16 -0
- package/dist/check.js.map +1 -1
- package/dist/choices.d.ts +22 -2
- package/dist/choices.d.ts.map +1 -1
- package/dist/choices.js +62 -0
- package/dist/choices.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/create-prompts.d.ts +6 -2
- package/dist/create-prompts.d.ts.map +1 -1
- package/dist/create-prompts.js +1 -1
- package/dist/create-prompts.js.map +1 -1
- package/dist/db.d.ts +5 -5
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +5 -5
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -27
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +5 -0
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +805 -62
- package/dist/inspect.js.map +1 -1
- package/dist/make/inbox.d.ts.map +1 -1
- package/dist/make/inbox.js +5 -3
- package/dist/make/inbox.js.map +1 -1
- package/dist/make/payments.d.ts.map +1 -1
- package/dist/make/payments.js +58 -29
- package/dist/make/payments.js.map +1 -1
- package/dist/make/shared.d.ts +12 -3
- package/dist/make/shared.d.ts.map +1 -1
- package/dist/make/shared.js +52 -11
- package/dist/make/shared.js.map +1 -1
- package/dist/make/tenancy.d.ts.map +1 -1
- package/dist/make/tenancy.js +6 -4
- package/dist/make/tenancy.js.map +1 -1
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +136 -65
- package/dist/make.js.map +1 -1
- package/dist/outbox.d.ts +114 -1
- package/dist/outbox.d.ts.map +1 -1
- package/dist/outbox.js +190 -0
- package/dist/outbox.js.map +1 -1
- package/dist/preflight.d.ts +90 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +423 -0
- package/dist/preflight.js.map +1 -0
- package/dist/provider-add.d.ts +10 -1
- package/dist/provider-add.d.ts.map +1 -1
- package/dist/provider-add.js +255 -16
- package/dist/provider-add.js.map +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +2 -3
- package/dist/task.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +6 -3
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.d.ts.map +1 -1
- package/dist/templates/base.js +5 -11
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +2 -0
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +10 -5
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shared.d.ts +5 -1
- package/dist/templates/shared.d.ts.map +1 -1
- package/dist/templates/shared.js +13 -1
- package/dist/templates/shared.js.map +1 -1
- package/dist/templates/testing.d.ts +5 -0
- package/dist/templates/testing.d.ts.map +1 -0
- package/dist/templates/testing.js +542 -0
- package/dist/templates/testing.js.map +1 -0
- package/dist/templates/todos.js +2 -2
- package/package.json +3 -2
- package/skills/app-structure/SKILL.md +12 -4
- package/src/check.ts +23 -0
- package/src/choices.ts +84 -0
- package/src/config.ts +4 -0
- package/src/create-prompts.ts +8 -2
- package/src/db.ts +12 -12
- package/src/index.ts +592 -37
- package/src/inspect.ts +1253 -156
- package/src/make/inbox.ts +5 -3
- package/src/make/payments.ts +58 -29
- package/src/make/shared.ts +87 -13
- package/src/make/tenancy.ts +6 -4
- package/src/make.ts +179 -65
- package/src/outbox.ts +363 -0
- package/src/preflight.ts +596 -0
- package/src/provider-add.ts +270 -16
- package/src/task.ts +2 -3
- package/src/templates/agents.ts +6 -3
- package/src/templates/base.ts +5 -13
- package/src/templates/index.ts +2 -0
- package/src/templates/server.ts +10 -5
- package/src/templates/shared.ts +15 -1
- package/src/templates/testing.ts +545 -0
- package/src/templates/todos.ts +2 -2
- package/src/test-helpers/generated-app.ts +10 -6
package/src/choices.ts
CHANGED
|
@@ -29,12 +29,16 @@ export type DatabaseName = "sqlite" | "postgres" | "mysql";
|
|
|
29
29
|
*/
|
|
30
30
|
export type ProviderPresetName =
|
|
31
31
|
| "flags-openfeature"
|
|
32
|
+
| "jobs-bullmq"
|
|
33
|
+
| "jobs-inngest"
|
|
32
34
|
| "mail-resend"
|
|
33
35
|
| "mail-smtp"
|
|
36
|
+
| "payments-stripe"
|
|
34
37
|
| "search-meilisearch"
|
|
35
38
|
| "sentry"
|
|
36
39
|
| "upstash-rate-limit"
|
|
37
40
|
| "redis-cache"
|
|
41
|
+
| "event-bus-redis"
|
|
38
42
|
| "redis-locks"
|
|
39
43
|
| "s3-storage"
|
|
40
44
|
| "vercel-blob-storage";
|
|
@@ -79,17 +83,97 @@ export const databaseChoices = [
|
|
|
79
83
|
*/
|
|
80
84
|
export const providerPresetChoices = [
|
|
81
85
|
"flags-openfeature",
|
|
86
|
+
"jobs-bullmq",
|
|
87
|
+
"jobs-inngest",
|
|
82
88
|
"mail-resend",
|
|
83
89
|
"mail-smtp",
|
|
90
|
+
"payments-stripe",
|
|
84
91
|
"search-meilisearch",
|
|
85
92
|
"sentry",
|
|
86
93
|
"upstash-rate-limit",
|
|
87
94
|
"redis-cache",
|
|
95
|
+
"event-bus-redis",
|
|
88
96
|
"redis-locks",
|
|
89
97
|
"s3-storage",
|
|
90
98
|
"vercel-blob-storage",
|
|
91
99
|
] as const satisfies readonly ProviderPresetName[];
|
|
92
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Values accepted by `beignet create --integrations`: the starter template
|
|
103
|
+
* integrations plus the full `beignet providers add` preset catalog.
|
|
104
|
+
*/
|
|
105
|
+
export type CreateIntegrationName = IntegrationName | ProviderPresetName;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Supported `beignet create --integrations` choices. Template integrations
|
|
109
|
+
* come first; the rest of the provider preset catalog follows.
|
|
110
|
+
*/
|
|
111
|
+
export const createIntegrationChoices = [
|
|
112
|
+
"inngest",
|
|
113
|
+
"resend",
|
|
114
|
+
"upstash-rate-limit",
|
|
115
|
+
"flags-openfeature",
|
|
116
|
+
"jobs-bullmq",
|
|
117
|
+
"jobs-inngest",
|
|
118
|
+
"mail-resend",
|
|
119
|
+
"mail-smtp",
|
|
120
|
+
"payments-stripe",
|
|
121
|
+
"redis-cache",
|
|
122
|
+
"event-bus-redis",
|
|
123
|
+
"redis-locks",
|
|
124
|
+
"s3-storage",
|
|
125
|
+
"search-meilisearch",
|
|
126
|
+
"sentry",
|
|
127
|
+
"vercel-blob-storage",
|
|
128
|
+
] as const satisfies readonly CreateIntegrationName[];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Provider presets whose create-time wiring already ships as a starter
|
|
132
|
+
* template integration. Selecting the preset name at create time scaffolds
|
|
133
|
+
* the equivalent template integration, so preset and integration stay
|
|
134
|
+
* consistent and `beignet providers add` remains a no-op afterwards.
|
|
135
|
+
*/
|
|
136
|
+
const presetTemplateIntegrationAliases: Partial<
|
|
137
|
+
Record<ProviderPresetName, IntegrationName>
|
|
138
|
+
> = {
|
|
139
|
+
"jobs-inngest": "inngest",
|
|
140
|
+
"mail-resend": "resend",
|
|
141
|
+
"upstash-rate-limit": "upstash-rate-limit",
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Split `--integrations` selections into starter template integrations and
|
|
146
|
+
* provider presets applied with the `beignet providers add` machinery after
|
|
147
|
+
* the scaffold is written. Preset names with a template equivalent are
|
|
148
|
+
* normalized to the template integration; duplicates collapse.
|
|
149
|
+
*/
|
|
150
|
+
export function splitCreateIntegrations(
|
|
151
|
+
values: readonly CreateIntegrationName[],
|
|
152
|
+
): {
|
|
153
|
+
integrations: IntegrationName[];
|
|
154
|
+
presets: ProviderPresetName[];
|
|
155
|
+
} {
|
|
156
|
+
const integrations = new Set<IntegrationName>();
|
|
157
|
+
const presets = new Set<ProviderPresetName>();
|
|
158
|
+
|
|
159
|
+
for (const value of values) {
|
|
160
|
+
if ((integrationChoices as readonly string[]).includes(value)) {
|
|
161
|
+
integrations.add(value as IntegrationName);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const preset = value as ProviderPresetName;
|
|
166
|
+
const alias = presetTemplateIntegrationAliases[preset];
|
|
167
|
+
if (alias) {
|
|
168
|
+
integrations.add(alias);
|
|
169
|
+
} else {
|
|
170
|
+
presets.add(preset);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return { integrations: [...integrations], presets: [...presets] };
|
|
175
|
+
}
|
|
176
|
+
|
|
93
177
|
/**
|
|
94
178
|
* Local database name derived from the app name.
|
|
95
179
|
*
|
package/src/config.ts
CHANGED
|
@@ -16,6 +16,7 @@ export type BeignetPaths = {
|
|
|
16
16
|
contracts: string;
|
|
17
17
|
routes: string;
|
|
18
18
|
server: string;
|
|
19
|
+
listeners: string;
|
|
19
20
|
openapiRoute: string;
|
|
20
21
|
tasks: string;
|
|
21
22
|
outbox: string;
|
|
@@ -32,6 +33,7 @@ export type BeignetPaths = {
|
|
|
32
33
|
schedulesBuilder: string;
|
|
33
34
|
notificationsBuilder: string;
|
|
34
35
|
tasksBuilder: string;
|
|
36
|
+
uploadsBuilder: string;
|
|
35
37
|
tests: string;
|
|
36
38
|
};
|
|
37
39
|
|
|
@@ -84,6 +86,7 @@ export const defaultBeignetConfig: ResolvedBeignetConfig = {
|
|
|
84
86
|
contracts: "features",
|
|
85
87
|
routes: "app/api",
|
|
86
88
|
server: "server/index.ts",
|
|
89
|
+
listeners: "server/listeners.ts",
|
|
87
90
|
openapiRoute: "app/api/openapi/route.ts",
|
|
88
91
|
tasks: "server/tasks.ts",
|
|
89
92
|
outbox: "server/outbox.ts",
|
|
@@ -100,6 +103,7 @@ export const defaultBeignetConfig: ResolvedBeignetConfig = {
|
|
|
100
103
|
schedulesBuilder: "lib/schedules.ts",
|
|
101
104
|
notificationsBuilder: "lib/notifications.ts",
|
|
102
105
|
tasksBuilder: "lib/tasks.ts",
|
|
106
|
+
uploadsBuilder: "lib/uploads.ts",
|
|
103
107
|
tests: "tests",
|
|
104
108
|
},
|
|
105
109
|
database: {
|
package/src/create-prompts.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
+
type CreateIntegrationName,
|
|
10
11
|
type DatabaseName,
|
|
11
12
|
databaseChoices,
|
|
12
13
|
type IntegrationName,
|
|
@@ -16,12 +17,16 @@ import {
|
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Selections shared by create flags and interactive prompt answers.
|
|
20
|
+
*
|
|
21
|
+
* `integrations` accepts the starter template integrations plus the full
|
|
22
|
+
* `beignet providers add` preset catalog; the interactive prompt shows the
|
|
23
|
+
* curated template list and points at the wider catalog.
|
|
19
24
|
*/
|
|
20
25
|
export type CreateSelections = {
|
|
21
26
|
directory?: string;
|
|
22
27
|
api?: boolean;
|
|
23
28
|
db?: DatabaseName;
|
|
24
|
-
integrations?: readonly
|
|
29
|
+
integrations?: readonly CreateIntegrationName[];
|
|
25
30
|
packageManager?: PackageManager;
|
|
26
31
|
};
|
|
27
32
|
|
|
@@ -114,7 +119,8 @@ export async function promptCreateSelections(
|
|
|
114
119
|
if (prompts.isCancel(db)) return undefined;
|
|
115
120
|
|
|
116
121
|
const integrations = await prompts.multiselect<IntegrationName>({
|
|
117
|
-
message:
|
|
122
|
+
message:
|
|
123
|
+
"Add provider integrations? (press enter to skip; the full preset catalog is available via --integrations or beignet providers add)",
|
|
118
124
|
options: integrationChoices.map((integration) => ({
|
|
119
125
|
value: integration,
|
|
120
126
|
label: integration,
|
package/src/db.ts
CHANGED
|
@@ -36,7 +36,7 @@ export type RunDatabaseCommandResult = {
|
|
|
36
36
|
export type DatabaseSchemaDialect = "sqlite" | "postgres" | "mysql";
|
|
37
37
|
export type DatabaseSchemaTable = "audit" | "idempotency" | "outbox";
|
|
38
38
|
|
|
39
|
-
export type
|
|
39
|
+
export type SyncDatabaseSchemaOptions = {
|
|
40
40
|
cwd?: string;
|
|
41
41
|
dialect?: DatabaseSchemaDialect;
|
|
42
42
|
tables?: readonly DatabaseSchemaTable[];
|
|
@@ -44,9 +44,9 @@ export type GenerateDatabaseSchemaOptions = {
|
|
|
44
44
|
dryRun?: boolean;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
export type
|
|
47
|
+
export type SyncDatabaseSchemaResult = {
|
|
48
48
|
schemaVersion: 1;
|
|
49
|
-
command: "schema:
|
|
49
|
+
command: "schema:sync";
|
|
50
50
|
cwd: string;
|
|
51
51
|
dialect: DatabaseSchemaDialect;
|
|
52
52
|
tables: DatabaseSchemaTable[];
|
|
@@ -132,15 +132,15 @@ export async function runDatabaseCommand(
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
|
-
*
|
|
135
|
+
* Sync the app-owned Drizzle schema entrypoint for Beignet provider tables.
|
|
136
136
|
*
|
|
137
137
|
* This only writes schema source. The app still owns SQL migration generation
|
|
138
138
|
* through `beignet db generate` and migration application through
|
|
139
139
|
* `beignet db migrate`.
|
|
140
140
|
*/
|
|
141
|
-
export async function
|
|
142
|
-
options:
|
|
143
|
-
): Promise<
|
|
141
|
+
export async function syncDatabaseSchema(
|
|
142
|
+
options: SyncDatabaseSchemaOptions = {},
|
|
143
|
+
): Promise<SyncDatabaseSchemaResult> {
|
|
144
144
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
145
145
|
const dialect = await resolveDatabaseSchemaDialect(cwd, options.dialect);
|
|
146
146
|
const tables = uniqueSchemaTables(options.tables ?? allDatabaseSchemaTables);
|
|
@@ -159,9 +159,9 @@ export async function generateDatabaseSchema(
|
|
|
159
159
|
throw new Error("Schema output must not be the schema index file.");
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
const result:
|
|
162
|
+
const result: SyncDatabaseSchemaResult = {
|
|
163
163
|
schemaVersion: 1,
|
|
164
|
-
command: "schema:
|
|
164
|
+
command: "schema:sync",
|
|
165
165
|
cwd,
|
|
166
166
|
dialect,
|
|
167
167
|
tables,
|
|
@@ -345,7 +345,7 @@ function renderDatabaseSchema(
|
|
|
345
345
|
const tableNames = selectedTables.map((table) => table.tableName);
|
|
346
346
|
const exportNames = selectedTables.map((table) => table.exportName).sort();
|
|
347
347
|
|
|
348
|
-
return `//
|
|
348
|
+
return `// Managed by beignet db schema sync.
|
|
349
349
|
// Required tables: ${tableNames.join(", ")}.
|
|
350
350
|
// Re-run this command after upgrading @beignet/provider-db-drizzle.
|
|
351
351
|
|
|
@@ -437,7 +437,7 @@ async function readTextIfExists(file: string): Promise<string | undefined> {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
function recordFileStatus(
|
|
440
|
-
result:
|
|
440
|
+
result: SyncDatabaseSchemaResult,
|
|
441
441
|
file: string,
|
|
442
442
|
status: FileWriteStatus,
|
|
443
443
|
): void {
|
|
@@ -464,7 +464,7 @@ function missingDatabaseScriptMessage(
|
|
|
464
464
|
|
|
465
465
|
const entrypoint =
|
|
466
466
|
command === "seed" ? "server/seed.ts" : "infra/db/reset.ts";
|
|
467
|
-
return `Missing package.json script "${script}". Standard Drizzle apps use "${script}": "
|
|
467
|
+
return `Missing package.json script "${script}". Standard Drizzle apps use "${script}": "tsx ${entrypoint}" so beignet db ${command} can run the app-owned ${command} entrypoint.`;
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
async function readPackageJson(cwd: string): Promise<PackageJson> {
|