diff --git a/.changeset/cool-wombats-marry.md b/.changeset/cool-wombats-marry.md new file mode 100644 index 000000000000..8683a2b0dc58 --- /dev/null +++ b/.changeset/cool-wombats-marry.md @@ -0,0 +1,7 @@ +--- +"wrangler": patch +--- + +fix: the docs command should not crash if given search terms + +Fixes a regression accidentally introduced by #3735. diff --git a/packages/wrangler/src/__tests__/docs.test.ts b/packages/wrangler/src/__tests__/docs.test.ts new file mode 100644 index 000000000000..c508875189e7 --- /dev/null +++ b/packages/wrangler/src/__tests__/docs.test.ts @@ -0,0 +1,124 @@ +import { http, HttpResponse } from "msw"; +import { afterEach, beforeEach, describe, test } from "vitest"; +import openInBrowser from "../open-in-browser"; +import { mockConsoleMethods } from "./helpers/mock-console"; +import { msw } from "./helpers/msw"; +import { runWrangler } from "./helpers/run-wrangler"; + +// NOTE: in production builds we "esbuild define" Algolia constants as globals +// but in tests we have to attach mocks values to the globalThis object. + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare module globalThis { + let ALGOLIA_APP_ID: string | undefined; + let ALGOLIA_PUBLIC_KEY: string | undefined; +} + +describe("wrangler docs", () => { + const std = mockConsoleMethods(); + + beforeEach(() => { + globalThis.ALGOLIA_APP_ID = "FAKE-ID"; + globalThis.ALGOLIA_PUBLIC_KEY = "FAKE-KEY"; + + msw.use( + http.post, { params: string | undefined }>( + `*/1/indexes/developers-cloudflare2/query`, + async ({ request }) => { + return HttpResponse.json({ + hits: [ + { + url: `FAKE_DOCS_URL:${await request.text()}`, + }, + ], + }); + }, + { once: true } + ) + ); + }); + + afterEach(() => { + delete globalThis.ALGOLIA_APP_ID; + delete globalThis.ALGOLIA_PUBLIC_KEY; + }); + + test("--help", async ({ expect }) => { + const result = runWrangler("docs --help"); + + await expect(result).resolves.toBeUndefined(); + expect(std.out).toMatchInlineSnapshot(` + "wrangler docs [search..] + + 📚 Open Wrangler's command documentation in your browser + + + POSITIONALS + search Enter search terms (e.g. the wrangler command) you want to know more about [array] [default: []] + + GLOBAL FLAGS + -j, --experimental-json-config Experimental: support wrangler.json [boolean] + -c, --config Path to .toml configuration file [string] + -e, --env Environment to use for operations and .env files [string] + -h, --help Show help [boolean] + -v, --version Show version number [boolean] + + OPTIONS + -y, --yes Takes you to the docs, even if search fails [boolean]" + `); + }); + + test("opens a browser to Cloudflare docs when given no search term", async ({ + expect, + }) => { + await runWrangler("docs"); + expect(std).toMatchInlineSnapshot(` + Object { + "debug": "", + "err": "", + "info": "", + "out": "Opening a link in your default browser: https://developers.cloudflare.com/workers/wrangler/commands/", + "warn": "", + } + `); + expect(openInBrowser).toHaveBeenCalledWith( + "https://developers.cloudflare.com/workers/wrangler/commands/" + ); + }); + + test("opens a browser to Cloudflare docs when given a single search term", async ({ + expect, + }) => { + await runWrangler("docs dev"); + expect(std).toMatchInlineSnapshot(` + Object { + "debug": "", + "err": "", + "info": "", + "out": "Opening a link in your default browser: FAKE_DOCS_URL:{\\"params\\":\\"query=dev&hitsPerPage=1&getRankingInfo=0\\"}", + "warn": "", + } + `); + expect(openInBrowser).toHaveBeenCalledWith( + 'FAKE_DOCS_URL:{"params":"query=dev&hitsPerPage=1&getRankingInfo=0"}' + ); + }); + + test("opens a browser to Cloudflare docs when given multiple search terms", async ({ + expect, + }) => { + await runWrangler("docs foo bar"); + expect(std).toMatchInlineSnapshot(` + Object { + "debug": "", + "err": "", + "info": "", + "out": "Opening a link in your default browser: FAKE_DOCS_URL:{\\"params\\":\\"query=foo+bar&hitsPerPage=1&getRankingInfo=0\\"}", + "warn": "", + } + `); + expect(openInBrowser).toHaveBeenCalledWith( + 'FAKE_DOCS_URL:{"params":"query=foo+bar&hitsPerPage=1&getRankingInfo=0"}' + ); + }); +}); diff --git a/packages/wrangler/src/__tests__/index.test.ts b/packages/wrangler/src/__tests__/index.test.ts index fd59cdc0d79f..49c9b2aaed2d 100644 --- a/packages/wrangler/src/__tests__/index.test.ts +++ b/packages/wrangler/src/__tests__/index.test.ts @@ -36,7 +36,7 @@ describe("wrangler", () => { "wrangler COMMANDS - wrangler docs [command] 📚 Open Wrangler's command documentation in your browser + wrangler docs [search..] 📚 Open Wrangler's command documentation in your browser wrangler init [name] 📥 Initialize a basic Worker wrangler dev [script] 👂 Start a local server for developing your Worker @@ -92,7 +92,7 @@ describe("wrangler", () => { wrangler COMMANDS - wrangler docs [command] 📚 Open Wrangler's command documentation in your browser + wrangler docs [search..] 📚 Open Wrangler's command documentation in your browser wrangler init [name] 📥 Initialize a basic Worker wrangler dev [script] 👂 Start a local server for developing your Worker diff --git a/packages/wrangler/src/__tests__/versions/versions.help.test.ts b/packages/wrangler/src/__tests__/versions/versions.help.test.ts index 989a0a6004b1..859c2c5886f7 100644 --- a/packages/wrangler/src/__tests__/versions/versions.help.test.ts +++ b/packages/wrangler/src/__tests__/versions/versions.help.test.ts @@ -14,7 +14,7 @@ describe("versions --help", () => { "wrangler COMMANDS - wrangler docs [command] 📚 Open Wrangler's command documentation in your browser + wrangler docs [search..] 📚 Open Wrangler's command documentation in your browser wrangler init [name] 📥 Initialize a basic Worker wrangler dev [script] 👂 Start a local server for developing your Worker diff --git a/packages/wrangler/src/docs/index.ts b/packages/wrangler/src/docs/index.ts index b853de6ba139..bedb329afd85 100644 --- a/packages/wrangler/src/docs/index.ts +++ b/packages/wrangler/src/docs/index.ts @@ -11,8 +11,9 @@ import type { export function docsOptions(yargs: CommonYargsArgv) { return yargs - .positional("command", { - describe: "Enter the wrangler command you want to know more about", + .positional("search", { + describe: + "Enter search terms (e.g. the wrangler command) you want to know more about", type: "string", array: true, }) @@ -29,12 +30,12 @@ export async function docsHandler( //if no command is provided, open the docs homepage //or, if a command IS provided, but we can't find anything, open the docs homepage let urlToOpen = - args.yes || !args.command || args.command.length === 0 + args.yes || !args.search || args.search.length === 0 ? "https://developers.cloudflare.com/workers/wrangler/commands/" : ""; - if (args.command && args.command.length > 0) { - const searchTerm = args.command.join(" "); + if (args.search && args.search.length > 0) { + const searchTerm = args.search.join(" "); const searchResult = await runSearch(searchTerm); urlToOpen = searchResult ?? urlToOpen; diff --git a/packages/wrangler/src/index.ts b/packages/wrangler/src/index.ts index e3fc2b4c4af2..e4466f007bb5 100644 --- a/packages/wrangler/src/index.ts +++ b/packages/wrangler/src/index.ts @@ -340,7 +340,7 @@ export function createCLIParser(argv: string[]) { /******************************************************/ // docs wrangler.command( - "docs [command]", + "docs [search..]", "📚 Open Wrangler's command documentation in your browser\n", docsOptions, docsHandler