create-svc 0.1.49 → 0.1.51
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/package.json
CHANGED
|
@@ -42,6 +42,7 @@ describe("buildLocalPreparationCommands", () => {
|
|
|
42
42
|
test("starts local Postgres before migrating Workers dev", () => {
|
|
43
43
|
expect(buildLocalPreparationCommands({ target: "workers" })).toEqual([
|
|
44
44
|
{ command: "bun", args: ["run", "./scripts/ensure-local-db.ts"] },
|
|
45
|
+
{ command: "bun", args: ["run", "./scripts/wait-for-db.ts"] },
|
|
45
46
|
{ command: "bun", args: ["run", "migrate"] },
|
|
46
47
|
]);
|
|
47
48
|
});
|
package/src/post-scaffold.ts
CHANGED
|
@@ -78,6 +78,7 @@ export function buildLocalPreparationCommands(config: Pick<ScaffoldConfig, "targ
|
|
|
78
78
|
if (config.target === "workers") {
|
|
79
79
|
return [
|
|
80
80
|
{ command: "bun", args: ["run", "./scripts/ensure-local-db.ts"] },
|
|
81
|
+
{ command: "bun", args: ["run", "./scripts/wait-for-db.ts"] },
|
|
81
82
|
{ command: "bun", args: ["run", "migrate"] },
|
|
82
83
|
];
|
|
83
84
|
}
|
package/src/scaffold.test.ts
CHANGED
|
@@ -320,6 +320,8 @@ test("scaffolds the workers target with wrangler lifecycle commands", async () =
|
|
|
320
320
|
expect(wranglerConfig).toContain('binding = "HYPERDRIVE"');
|
|
321
321
|
expect(wranglerConfig).toContain('AUTH_ENABLED = "true"');
|
|
322
322
|
expect(wranglerConfig).toContain('AUTH_AUDIENCE = "api://dns-api"');
|
|
323
|
+
expect(wranglerConfig).not.toContain("[triggers]");
|
|
324
|
+
expect(wranglerConfig).not.toContain("crons");
|
|
323
325
|
const authSource = await Bun.file(join(generatedRoot, "src", "auth.ts")).text();
|
|
324
326
|
expect(authSource).toContain('alg === "EdDSA"');
|
|
325
327
|
expect(authSource).toContain('name: "Ed25519"');
|
|
@@ -4,8 +4,9 @@ import { confirm, intro, isCancel, log, outro } from "@clack/prompts";
|
|
|
4
4
|
import { createApiClient } from "@neondatabase/api-client";
|
|
5
5
|
import { Client } from "pg";
|
|
6
6
|
import { manualGitHubDeleteCommand } from "../../git-bootstrap";
|
|
7
|
-
import { ensureAuthClient, ensureAuthResourceServer, runAuthCommand, runAuthDoctor } from "../authctl";
|
|
7
|
+
import { deleteAuthResourceServer, ensureAuthClient, ensureAuthResourceServer, runAuthCommand, runAuthDoctor } from "../authctl";
|
|
8
8
|
import { stopLocalDev } from "../local-dev";
|
|
9
|
+
import { runParallelTasks, type ParallelTask } from "../parallel-tasks";
|
|
9
10
|
import { serviceConfig } from "../runtime";
|
|
10
11
|
import { isLocalDatabaseUrl, isMissingDatabaseError, resolveCommandPath } from "./lib";
|
|
11
12
|
|
|
@@ -78,7 +79,7 @@ export async function main(argv = Bun.argv.slice(2)) {
|
|
|
78
79
|
if (rest[0] !== "down") {
|
|
79
80
|
throw new Error(`Unknown dev command: ${rest[0] || ""}\n\n${formatHelp()}`);
|
|
80
81
|
}
|
|
81
|
-
return runMain("Dev", () => stopLocalDev({ dockerCompose: false }));
|
|
82
|
+
return runMain("Dev", () => stopLocalDev({ dockerCompose: true, removeVolumes: false }));
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
if (command === "doctor") {
|
|
@@ -97,14 +98,45 @@ export async function main(argv = Bun.argv.slice(2)) {
|
|
|
97
98
|
return runMain("Destroy", async () => {
|
|
98
99
|
await requireDestroyConfirmation(rest.includes("--force"));
|
|
99
100
|
const wranglerArgs = rest.filter((arg) => arg !== "--force");
|
|
100
|
-
|
|
101
|
+
const tasks: ParallelTask[] = [
|
|
102
|
+
{
|
|
103
|
+
label: "Stopping local dev resources",
|
|
104
|
+
task: () => stopLocalDev({ dockerCompose: true, removeVolumes: true }),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
label: `Deleting auth resource server ${config.serviceName}`,
|
|
108
|
+
task: () => deleteAuthResourceServer(),
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
label: "Deleting Hyperdrive",
|
|
112
|
+
task: () => deleteHyperdrive(),
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
label: `Deleting Worker ${config.serviceName}`,
|
|
116
|
+
task: () => run("wrangler", ["delete", "--name", config.serviceName, "--force", ...wranglerArgs]),
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
label: "Deleting Neon database",
|
|
120
|
+
task: () => deleteNeonDatabase(),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
label: "Deleting Grafana resources",
|
|
124
|
+
task: () => deleteGrafanaResources(),
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
|
|
101
128
|
if (await confirmGitHubRepositoryDeletion(rest.includes("--force"))) {
|
|
102
|
-
|
|
129
|
+
tasks.push({
|
|
130
|
+
label: `Deleting GitHub repository ${config.git.owner}/${config.git.repository}`,
|
|
131
|
+
task: () => deleteGitHubRepositoryIfOwned(),
|
|
132
|
+
});
|
|
103
133
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
await
|
|
107
|
-
|
|
134
|
+
|
|
135
|
+
log.step(`Deleting ${tasks.length} resource groups in parallel`);
|
|
136
|
+
await runParallelTasks(tasks, {
|
|
137
|
+
onSuccess: (label) => log.step(`${label}: done`),
|
|
138
|
+
onFailure: (label, error) => log.error(`${label} failed\n${error instanceof Error ? error.message : String(error)}`),
|
|
139
|
+
});
|
|
108
140
|
return `Destroyed ${config.serviceName}`;
|
|
109
141
|
});
|
|
110
142
|
}
|
|
@@ -129,7 +161,7 @@ function formatHelp() {
|
|
|
129
161
|
" doctor Check local tools and cloud access",
|
|
130
162
|
" auth Manage auth resource server and clients",
|
|
131
163
|
" auth token Mint a bearer token for protected API checks",
|
|
132
|
-
" dev down Stop local dev",
|
|
164
|
+
" dev down Stop local dev and Docker Compose containers",
|
|
133
165
|
" dns Show Workers custom-domain configuration",
|
|
134
166
|
" dashboards Publish Grafana resources",
|
|
135
167
|
" destroy Remove service-managed Worker resources",
|
|
@@ -457,13 +489,6 @@ async function runDoctor() {
|
|
|
457
489
|
}
|
|
458
490
|
return "name and custom domain route configured";
|
|
459
491
|
});
|
|
460
|
-
await record(results, "Cron Trigger", "fail", async () => {
|
|
461
|
-
const text = await Bun.file("./wrangler.toml").text();
|
|
462
|
-
if (!text.includes("[triggers]") || !text.includes("crons")) {
|
|
463
|
-
throw new Error("wrangler.toml is missing a cron trigger");
|
|
464
|
-
}
|
|
465
|
-
return "cron trigger configured";
|
|
466
|
-
});
|
|
467
492
|
await record(results, "Hyperdrive binding", "warn", async () => {
|
|
468
493
|
const text = await Bun.file("./wrangler.toml").text();
|
|
469
494
|
if (!text.includes('binding = "HYPERDRIVE"')) {
|
|
@@ -7,7 +7,6 @@ This `{{PROFILE}}` profile targets `{{RUNTIME}} + {{FRAMEWORK}}` on Cloudflare W
|
|
|
7
7
|
- one `wrangler.toml`
|
|
8
8
|
- a lightweight waitlist/launch API
|
|
9
9
|
- the `service` CLI for create, deploy, doctor, dashboards, DNS, and destroy
|
|
10
|
-
- Cron Trigger wiring for scheduled follow-up work
|
|
11
10
|
- a Hyperdrive binding for Neon-backed Postgres persistence
|
|
12
11
|
- a production API origin at `https://{{API_HOSTNAME}}`
|
|
13
12
|
|
|
@@ -62,7 +61,7 @@ configured in `wrangler.toml`:
|
|
|
62
61
|
https://{{API_HOSTNAME}}
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
Use `service doctor` after create to verify Wrangler auth, route config,
|
|
64
|
+
Use `service doctor` after create to verify Wrangler auth, route config,
|
|
66
65
|
Hyperdrive, dashboard tooling, auth tooling, and deployed health.
|
|
67
66
|
|
|
68
67
|
{{PRODUCTION_PROTECTED_CHECKS}}
|