-
Notifications
You must be signed in to change notification settings - Fork 779
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement a basic
wrangler delete
This PR adds a simple (but useful!) implementation for `wrangler delete`. Of note, it'll delete a given service, including all it's bindings. It uses the same api as the dashboard.
- Loading branch information
1 parent
ccfdd0b
commit eedf371
Showing
6 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"wrangler": patch | ||
--- | ||
|
||
feat: implement a basic `wrangler delete` | ||
|
||
This PR adds a simple (but useful!) implementation for `wrangler delete`. Of note, it'll delete a given service, including all it's bindings. It uses the same api as the dashboard. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id"; | ||
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch"; | ||
import { mockConsoleMethods } from "./helpers/mock-console"; | ||
import { mockConfirm } from "./helpers/mock-dialogs"; | ||
import { runInTempDir } from "./helpers/run-in-tmp"; | ||
import { runWrangler } from "./helpers/run-wrangler"; | ||
import writeWranglerToml from "./helpers/write-wrangler-toml"; | ||
|
||
describe("delete", () => { | ||
mockAccountId(); | ||
mockApiToken(); | ||
runInTempDir(); | ||
|
||
afterEach(() => { | ||
unsetAllMocks(); | ||
}); | ||
|
||
const std = mockConsoleMethods(); | ||
|
||
it("should delete an entire service by name", async () => { | ||
mockConfirm({ | ||
text: `Are you sure you want to delete my-script? This action cannot be undone.`, | ||
result: true, | ||
}); | ||
mockDeleteWorkerRequest({ name: "my-script" }); | ||
await runWrangler("delete --name my-script"); | ||
|
||
expect(std).toMatchInlineSnapshot(` | ||
Object { | ||
"debug": "", | ||
"err": "", | ||
"out": "Successfully deleted my-script", | ||
"warn": "", | ||
} | ||
`); | ||
}); | ||
|
||
it("should delete a script by configuration", async () => { | ||
mockConfirm({ | ||
text: `Are you sure you want to delete test-name? This action cannot be undone.`, | ||
result: true, | ||
}); | ||
writeWranglerToml(); | ||
mockDeleteWorkerRequest(); | ||
await runWrangler("delete"); | ||
|
||
expect(std).toMatchInlineSnapshot(` | ||
Object { | ||
"debug": "", | ||
"err": "", | ||
"out": "Successfully deleted test-name", | ||
"warn": "", | ||
} | ||
`); | ||
}); | ||
|
||
it("shouldn't delete a service when doing a --dry-run", async () => { | ||
await runWrangler("delete --name xyz --dry-run"); | ||
|
||
expect(std).toMatchInlineSnapshot(` | ||
Object { | ||
"debug": "", | ||
"err": "", | ||
"out": "--dry-run: exiting now.", | ||
"warn": "", | ||
} | ||
`); | ||
}); | ||
|
||
it('shouldn\'t delete when the user says "no"', async () => { | ||
mockConfirm({ | ||
text: `Are you sure you want to delete xyz? This action cannot be undone.`, | ||
result: false, | ||
}); | ||
|
||
await runWrangler("delete --name xyz"); | ||
|
||
expect(std).toMatchInlineSnapshot(` | ||
Object { | ||
"debug": "", | ||
"err": "", | ||
"out": "", | ||
"warn": "", | ||
} | ||
`); | ||
}); | ||
}); | ||
|
||
/** Create a mock handler for the request to upload a worker script. */ | ||
function mockDeleteWorkerRequest( | ||
options: { | ||
name?: string; | ||
env?: string; | ||
legacyEnv?: boolean; | ||
} = {} | ||
) { | ||
const { env, legacyEnv, name } = options; | ||
setMockResponse( | ||
// there's no special handling for environments yet | ||
"/accounts/:accountId/workers/services/:scriptName", | ||
"DELETE", | ||
async ([_url, accountId, scriptName], { method }, queryParams) => { | ||
expect(accountId).toEqual("some-account-id"); | ||
expect(method).toEqual("DELETE"); | ||
expect(scriptName).toEqual( | ||
legacyEnv && env | ||
? `${name || "test-name"}-${env}` | ||
: `${name || "test-name"}` | ||
); | ||
|
||
expect(queryParams.get("force")).toEqual("true"); | ||
|
||
return null; | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import path from "path"; | ||
import { fetchResult } from "./cfetch"; | ||
import { findWranglerToml, readConfig } from "./config"; | ||
import { confirm } from "./dialogs"; | ||
import { CI } from "./is-ci"; | ||
import isInteractive from "./is-interactive"; | ||
import { logger } from "./logger"; | ||
import * as metrics from "./metrics"; | ||
import { requireAuth } from "./user"; | ||
import { getScriptName, printWranglerBanner } from "./index"; | ||
import type { ConfigPath } from "./index"; | ||
import type { YargsOptionsToInterface } from "./yargs-types"; | ||
import type { Argv, ArgumentsCamelCase } from "yargs"; | ||
|
||
export function deleteOptions(yargs: Argv) { | ||
return yargs | ||
.option("env", { | ||
type: "string", | ||
requiresArg: true, | ||
describe: "Perform on a specific environment", | ||
alias: "e", | ||
}) | ||
.positional("script", { | ||
describe: "The path to an entry point for your worker", | ||
type: "string", | ||
requiresArg: true, | ||
}) | ||
.option("name", { | ||
describe: "Name of the worker", | ||
type: "string", | ||
requiresArg: true, | ||
}) | ||
.option("dry-run", { | ||
describe: "Don't actually delete", | ||
type: "boolean", | ||
}) | ||
.option("legacy-env", { | ||
type: "boolean", | ||
describe: "Use legacy environments", | ||
hidden: true, | ||
}); | ||
} | ||
|
||
type DeleteArgs = YargsOptionsToInterface<typeof deleteOptions>; | ||
|
||
export async function deleteHandler(args: ArgumentsCamelCase<DeleteArgs>) { | ||
await printWranglerBanner(); | ||
|
||
const configPath = | ||
(args.config as ConfigPath) || | ||
(args.script && findWranglerToml(path.dirname(args.script))); | ||
const config = readConfig(configPath, args); | ||
await metrics.sendMetricsEvent( | ||
"delete worker script", | ||
{}, | ||
{ sendMetrics: config.send_metrics } | ||
); | ||
|
||
const accountId = args.dryRun ? undefined : await requireAuth(config); | ||
|
||
const scriptName = getScriptName(args, config); | ||
|
||
if (args.dryRun) { | ||
logger.log(`--dry-run: exiting now.`); | ||
return; | ||
} | ||
|
||
let confirmed = true; | ||
if (isInteractive() || !CI.isCI()) { | ||
confirmed = await confirm( | ||
`Are you sure you want to delete ${scriptName}? This action cannot be undone.` | ||
); | ||
} | ||
|
||
if (confirmed) { | ||
await fetchResult( | ||
`/accounts/${accountId}/workers/services/${scriptName}`, | ||
{ method: "DELETE" }, | ||
new URLSearchParams({ force: "true" }) | ||
); | ||
|
||
logger.log("Successfully deleted", scriptName); | ||
} | ||
|
||
// TODO: maybe delete sites/assets kv namespace as well? | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters