@beignet/cli 0.0.37 → 0.0.39
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 +26 -0
- package/README.md +138 -101
- package/dist/choices.d.ts +17 -21
- package/dist/choices.d.ts.map +1 -1
- package/dist/choices.js +21 -67
- package/dist/choices.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/create-prompts.d.ts +5 -6
- package/dist/create-prompts.d.ts.map +1 -1
- package/dist/create-prompts.js +15 -15
- package/dist/create-prompts.js.map +1 -1
- package/dist/create.d.ts +11 -2
- package/dist/create.d.ts.map +1 -1
- package/dist/create.js +38 -28
- package/dist/create.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +149 -47
- package/dist/index.js.map +1 -1
- package/dist/inspect.js +69 -16
- package/dist/inspect.js.map +1 -1
- package/dist/lib.d.ts +1 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +27 -6
- package/dist/lint.js.map +1 -1
- package/dist/make/inbox.js +10 -10
- package/dist/make/inbox.js.map +1 -1
- package/dist/make/payments.d.ts +2 -1
- package/dist/make/payments.d.ts.map +1 -1
- package/dist/make/payments.js +18 -14
- package/dist/make/payments.js.map +1 -1
- package/dist/make/shared.d.ts +11 -4
- package/dist/make/shared.d.ts.map +1 -1
- package/dist/make/shared.js +56 -45
- package/dist/make/shared.js.map +1 -1
- package/dist/make/tenancy.js +8 -8
- package/dist/make/tenancy.js.map +1 -1
- package/dist/make.d.ts +3 -2
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +481 -200
- package/dist/make.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +15 -11
- package/dist/mcp.js.map +1 -1
- package/dist/operational-error-reporting.d.ts +15 -0
- package/dist/operational-error-reporting.d.ts.map +1 -0
- package/dist/operational-error-reporting.js +42 -0
- package/dist/operational-error-reporting.js.map +1 -0
- package/dist/outbox.d.ts.map +1 -1
- package/dist/outbox.js +73 -0
- package/dist/outbox.js.map +1 -1
- package/dist/provider-add.d.ts +21 -3
- package/dist/provider-add.d.ts.map +1 -1
- package/dist/provider-add.js +117 -81
- package/dist/provider-add.js.map +1 -1
- package/dist/provider-audit.js +3 -3
- package/dist/provider-audit.js.map +1 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +28 -1
- package/dist/schedule.js.map +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +38 -5
- package/dist/task.js.map +1 -1
- package/dist/templates/base.d.ts +1 -1
- package/dist/templates/base.d.ts.map +1 -1
- package/dist/templates/base.js +15 -15
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/index.d.ts +2 -2
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +7 -7
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/server.d.ts +1 -1
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +22 -18
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shared.d.ts +4 -4
- package/dist/templates/shared.d.ts.map +1 -1
- package/dist/templates/shared.js +6 -6
- package/dist/templates/shared.js.map +1 -1
- package/dist/templates/testing.js +1 -1
- package/dist/templates/todos.js +6 -6
- package/package.json +4 -4
- package/skills/app-structure/SKILL.md +13 -8
- package/src/choices.ts +38 -88
- package/src/config.ts +2 -2
- package/src/create-prompts.ts +20 -21
- package/src/create.ts +54 -36
- package/src/index.ts +193 -65
- package/src/inspect.ts +116 -18
- package/src/lib.ts +1 -1
- package/src/lint.ts +35 -4
- package/src/make/inbox.ts +10 -10
- package/src/make/payments.ts +26 -18
- package/src/make/shared.ts +72 -50
- package/src/make/tenancy.ts +8 -8
- package/src/make.ts +607 -191
- package/src/mcp.ts +20 -13
- package/src/operational-error-reporting.ts +60 -0
- package/src/outbox.ts +77 -0
- package/src/provider-add.ts +179 -95
- package/src/provider-audit.ts +3 -3
- package/src/schedule.ts +32 -1
- package/src/task.ts +42 -5
- package/src/templates/base.ts +16 -16
- package/src/templates/index.ts +8 -8
- package/src/templates/server.ts +22 -18
- package/src/templates/shared.ts +10 -10
- package/src/templates/testing.ts +1 -1
- package/src/templates/todos.ts +6 -6
- package/src/test-helpers/generated-app.ts +1 -0
package/src/create-prompts.ts
CHANGED
|
@@ -7,26 +7,25 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
-
type
|
|
10
|
+
type CreateProviderName,
|
|
11
11
|
type DatabaseName,
|
|
12
12
|
databaseChoices,
|
|
13
|
-
type IntegrationName,
|
|
14
|
-
integrationChoices,
|
|
15
13
|
type PackageManager,
|
|
14
|
+
type StarterProviderName,
|
|
15
|
+
starterProviderChoices,
|
|
16
16
|
} from "./choices.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Selections shared by create flags and interactive prompt answers.
|
|
20
20
|
*
|
|
21
|
-
* `
|
|
22
|
-
*
|
|
23
|
-
* curated template list and points at the wider catalog.
|
|
21
|
+
* `providers` accepts the full `beignet provider add` preset catalog; the
|
|
22
|
+
* interactive prompt shows the providers rendered directly by the starter.
|
|
24
23
|
*/
|
|
25
24
|
export type CreateSelections = {
|
|
26
25
|
directory?: string;
|
|
27
26
|
api?: boolean;
|
|
28
27
|
db?: DatabaseName;
|
|
29
|
-
|
|
28
|
+
providers?: readonly CreateProviderName[];
|
|
30
29
|
packageManager?: PackageManager;
|
|
31
30
|
};
|
|
32
31
|
|
|
@@ -43,7 +42,7 @@ type CreatePromptTty = {
|
|
|
43
42
|
* Decide whether `beignet create` should run the interactive prompt flow.
|
|
44
43
|
*
|
|
45
44
|
* Prompts run only on a full TTY, only when `--yes` is absent, and only when
|
|
46
|
-
* no selection flag was passed. Any explicit api, database,
|
|
45
|
+
* no selection flag was passed. Any explicit api, database, provider, or
|
|
47
46
|
* package manager selection means the invocation is scripted, so the
|
|
48
47
|
* non-interactive path stays byte-identical for agents and CI.
|
|
49
48
|
*/
|
|
@@ -57,16 +56,16 @@ export function shouldPromptInteractively(
|
|
|
57
56
|
const selectionFlagPassed =
|
|
58
57
|
flags.api !== undefined ||
|
|
59
58
|
flags.db !== undefined ||
|
|
60
|
-
(flags.
|
|
59
|
+
(flags.providers?.length ?? 0) > 0 ||
|
|
61
60
|
flags.packageManager !== undefined;
|
|
62
61
|
|
|
63
62
|
return !selectionFlagPassed;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
const
|
|
67
|
-
inngest: "Inngest-backed background jobs",
|
|
68
|
-
resend: "Resend-backed mail provider",
|
|
69
|
-
"
|
|
65
|
+
const providerHints: Record<StarterProviderName, string> = {
|
|
66
|
+
"jobs-inngest": "Inngest-backed background jobs",
|
|
67
|
+
"mail-resend": "Resend-backed mail provider",
|
|
68
|
+
"rate-limit-upstash": "Upstash-backed rate limiting",
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
const databaseHints: Record<DatabaseName, string> = {
|
|
@@ -118,17 +117,17 @@ export async function promptCreateSelections(
|
|
|
118
117
|
});
|
|
119
118
|
if (prompts.isCancel(db)) return undefined;
|
|
120
119
|
|
|
121
|
-
const
|
|
120
|
+
const providers = await prompts.multiselect<StarterProviderName>({
|
|
122
121
|
message:
|
|
123
|
-
"Add
|
|
124
|
-
options:
|
|
125
|
-
value:
|
|
126
|
-
label:
|
|
127
|
-
hint:
|
|
122
|
+
"Add providers? (press enter to skip; the full catalog is available via --providers or beignet provider add)",
|
|
123
|
+
options: starterProviderChoices.map((provider) => ({
|
|
124
|
+
value: provider,
|
|
125
|
+
label: provider,
|
|
126
|
+
hint: providerHints[provider],
|
|
128
127
|
})),
|
|
129
128
|
required: false,
|
|
130
129
|
});
|
|
131
|
-
if (prompts.isCancel(
|
|
130
|
+
if (prompts.isCancel(providers)) return undefined;
|
|
132
131
|
|
|
133
132
|
prompts.outro(`Creating ${directory}`);
|
|
134
133
|
|
|
@@ -136,7 +135,7 @@ export async function promptCreateSelections(
|
|
|
136
135
|
directory,
|
|
137
136
|
api,
|
|
138
137
|
db,
|
|
139
|
-
|
|
138
|
+
providers,
|
|
140
139
|
packageManager: initial.packageManager,
|
|
141
140
|
};
|
|
142
141
|
}
|
package/src/create.ts
CHANGED
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
type DatabaseName,
|
|
5
5
|
databaseChoices,
|
|
6
6
|
getTemplateFiles,
|
|
7
|
-
type IntegrationName,
|
|
8
|
-
integrationChoices,
|
|
9
7
|
type PackageManager,
|
|
8
|
+
type StarterProviderName,
|
|
9
|
+
starterProviderChoices,
|
|
10
|
+
type TemplateFile,
|
|
10
11
|
type TemplateName,
|
|
11
12
|
} from "./templates/index.js";
|
|
12
13
|
import { getCliVersion } from "./version.js";
|
|
@@ -23,7 +24,7 @@ export type CreateOptions = {
|
|
|
23
24
|
*/
|
|
24
25
|
api?: boolean;
|
|
25
26
|
packageManager?: PackageManager;
|
|
26
|
-
|
|
27
|
+
providers?: StarterProviderName[];
|
|
27
28
|
/**
|
|
28
29
|
* Database backing the starter's Drizzle persistence layer.
|
|
29
30
|
* Defaults to "sqlite".
|
|
@@ -47,19 +48,46 @@ export type CreateResult = {
|
|
|
47
48
|
database: DatabaseName;
|
|
48
49
|
};
|
|
49
50
|
|
|
51
|
+
export type CreateProjectPlan = {
|
|
52
|
+
result: CreateResult;
|
|
53
|
+
files: TemplateFile[];
|
|
54
|
+
};
|
|
55
|
+
|
|
50
56
|
/**
|
|
51
57
|
* Create a Beignet app from the starter template.
|
|
52
58
|
*/
|
|
53
59
|
export async function createProject(
|
|
54
60
|
options: CreateOptions,
|
|
55
61
|
): Promise<CreateResult> {
|
|
62
|
+
const plan = await planCreateProject(options);
|
|
63
|
+
|
|
64
|
+
if (!plan.result.dryRun) {
|
|
65
|
+
await mkdir(plan.result.targetDir, { recursive: true });
|
|
66
|
+
|
|
67
|
+
for (const file of plan.files) {
|
|
68
|
+
const destination = path.join(plan.result.targetDir, file.path);
|
|
69
|
+
await mkdir(path.dirname(destination), { recursive: true });
|
|
70
|
+
await writeFile(destination, file.content);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return plan.result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render a scaffold without writing it so create-time provider presets can
|
|
79
|
+
* compose against the exact same file contents as a real create.
|
|
80
|
+
*/
|
|
81
|
+
export async function planCreateProject(
|
|
82
|
+
options: CreateOptions,
|
|
83
|
+
): Promise<CreateProjectPlan> {
|
|
56
84
|
const cwd = options.cwd ?? process.cwd();
|
|
57
85
|
const name = normalizeProjectName(options.name);
|
|
58
86
|
const targetDir = path.resolve(cwd, options.name);
|
|
59
87
|
const packageManager = options.packageManager ?? "bun";
|
|
60
88
|
const template = options.template ?? "next";
|
|
61
89
|
const api = Boolean(options.api);
|
|
62
|
-
const
|
|
90
|
+
const providers = resolveStarterProviders(options.providers ?? []);
|
|
63
91
|
const database = options.db ?? "sqlite";
|
|
64
92
|
|
|
65
93
|
if (template !== "next") {
|
|
@@ -83,58 +111,48 @@ export async function createProject(
|
|
|
83
111
|
packageManager,
|
|
84
112
|
beignetVersion: options.beignetVersion ?? getDefaultBeignetVersion(),
|
|
85
113
|
api,
|
|
86
|
-
|
|
114
|
+
providers,
|
|
87
115
|
database,
|
|
88
116
|
});
|
|
89
117
|
|
|
90
|
-
if (!dryRun) {
|
|
91
|
-
await mkdir(targetDir, { recursive: true });
|
|
92
|
-
|
|
93
|
-
for (const file of files) {
|
|
94
|
-
const destination = path.join(targetDir, file.path);
|
|
95
|
-
await mkdir(path.dirname(destination), { recursive: true });
|
|
96
|
-
await writeFile(destination, file.content);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
118
|
return {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
result: {
|
|
120
|
+
schemaVersion: 1,
|
|
121
|
+
name,
|
|
122
|
+
targetDir,
|
|
123
|
+
dryRun,
|
|
124
|
+
files: files.map((file) => file.path),
|
|
125
|
+
packageManager,
|
|
126
|
+
database,
|
|
127
|
+
},
|
|
128
|
+
files,
|
|
108
129
|
};
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
/**
|
|
112
|
-
* Providers that ship in every starter
|
|
113
|
-
* choices, so passing them gets a pointed error instead of a generic one.
|
|
133
|
+
* Providers that ship in every starter are not selectable additions.
|
|
114
134
|
*/
|
|
115
135
|
const baseProviderNames = new Set(["better-auth", "drizzle-sqlite", "pino"]);
|
|
116
136
|
|
|
117
|
-
function
|
|
118
|
-
|
|
119
|
-
):
|
|
120
|
-
for (const
|
|
121
|
-
const
|
|
122
|
-
if (baseProviderNames.has(
|
|
137
|
+
function resolveStarterProviders(
|
|
138
|
+
explicitProviders: StarterProviderName[],
|
|
139
|
+
): StarterProviderName[] {
|
|
140
|
+
for (const provider of explicitProviders) {
|
|
141
|
+
const providerName: string = provider;
|
|
142
|
+
if (baseProviderNames.has(providerName)) {
|
|
123
143
|
const databaseHint =
|
|
124
|
-
|
|
144
|
+
providerName === "drizzle-sqlite"
|
|
125
145
|
? " Choose the starter database with --db sqlite|postgres|mysql instead."
|
|
126
146
|
: "";
|
|
127
147
|
throw new Error(
|
|
128
|
-
`${
|
|
148
|
+
`${provider} is part of every Beignet starter and is not a --providers choice.${databaseHint}`,
|
|
129
149
|
);
|
|
130
150
|
}
|
|
131
151
|
}
|
|
132
152
|
|
|
133
|
-
const
|
|
153
|
+
const providers = new Set<StarterProviderName>(explicitProviders);
|
|
134
154
|
|
|
135
|
-
return
|
|
136
|
-
integrations.has(integration),
|
|
137
|
-
);
|
|
155
|
+
return starterProviderChoices.filter((provider) => providers.has(provider));
|
|
138
156
|
}
|
|
139
157
|
|
|
140
158
|
function getDefaultBeignetVersion(): string {
|