From 7e46ae489e64b2137256f68bd73203147584fb74 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sat, 6 Jan 2024 23:36:49 +0000 Subject: [PATCH 01/12] fix(server): make CLI entrypoints consistent --- packages/api-server/src/cliHandlers.ts | 2 +- packages/api-server/src/index.ts | 52 +- packages/cli/src/index.js | 14 +- packages/web-server/src/server.ts | 44 +- .../__snapshots__/server.test.mjs.snap | 38 ++ tasks/server-tests/jest.config.js | 2 + .../{server.test.ts => server.test.mjs} | 537 ++++++++++-------- 7 files changed, 417 insertions(+), 272 deletions(-) create mode 100644 tasks/server-tests/__snapshots__/server.test.mjs.snap rename tasks/server-tests/{server.test.ts => server.test.mjs} (52%) diff --git a/packages/api-server/src/cliHandlers.ts b/packages/api-server/src/cliHandlers.ts index ad04725e46ee..e7fcb0271ac1 100644 --- a/packages/api-server/src/cliHandlers.ts +++ b/packages/api-server/src/cliHandlers.ts @@ -29,7 +29,7 @@ export const apiCliOptions = { port: { default: getConfig().api?.port || 8911, type: 'number', alias: 'p' }, socket: { type: 'string' }, apiRootPath: { - alias: ['rootPath', 'root-path'], + alias: ['api-root-path', 'rootPath', 'root-path'], default: '/', type: 'string', desc: 'Root path where your api functions are served', diff --git a/packages/api-server/src/index.ts b/packages/api-server/src/index.ts index dedf60785c19..df9ab77f35b3 100644 --- a/packages/api-server/src/index.ts +++ b/packages/api-server/src/index.ts @@ -1,4 +1,5 @@ #!/usr/bin/env node + import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' @@ -13,29 +14,38 @@ import { export * from './types' -const positionalArgs = yargs(hideBin(process.argv)).parseSync()._ - -// "bin": { -// "rw-api-server-watch": "./dist/watch.js", -// "rw-log-formatter": "./dist/logFormatter/bin.js", -// "rw-server": "./dist/index.js" -// }, - if (require.main === module) { - if (positionalArgs.includes('api') && !positionalArgs.includes('web')) { - apiServerHandler( - yargs(hideBin(process.argv)).options(apiCliOptions).parseSync() + yargs(hideBin(process.argv)) + .scriptName('rw-server') + .usage('usage: $0 ') + .strict() + + .command( + '$0', + 'Run both api and web servers', + // @ts-expect-error just passing yargs though + (yargs) => { + yargs.options(commonOptions) + }, + bothServerHandler ) - } else if ( - positionalArgs.includes('web') && - !positionalArgs.includes('api') - ) { - webServerHandler( - yargs(hideBin(process.argv)).options(webCliOptions).parseSync() + .command( + 'api', + 'Start server for serving only the api', + // @ts-expect-error just passing yargs though + (yargs) => { + yargs.options(apiCliOptions) + }, + apiServerHandler ) - } else { - bothServerHandler( - yargs(hideBin(process.argv)).options(commonOptions).parseSync() + .command( + 'web', + 'Start server for serving only the web side', + // @ts-expect-error just passing yargs though + (yargs) => { + yargs.options(webCliOptions) + }, + webServerHandler ) - } + .parse() } diff --git a/packages/cli/src/index.js b/packages/cli/src/index.js index c0130ea2feac..614c5d30d79e 100644 --- a/packages/cli/src/index.js +++ b/packages/cli/src/index.js @@ -215,10 +215,20 @@ async function runYargs() { await loadPlugins(yarg) // Run - await yarg.parse(process.argv.slice(2), {}, (_err, _argv, output) => { + await yarg.parse(process.argv.slice(2), {}, (err, _argv, output) => { + // Configuring yargs with `strict` makes it error on unknown args; + // here we're propagating the exit code. + if (err) { + process.exitCode = 1 + } + // Show the output that yargs was going to if there was no callback provided if (output) { - console.log(output) + if (err) { + console.error(output) + } else { + console.log(output) + } } }) } diff --git a/packages/web-server/src/server.ts b/packages/web-server/src/server.ts index dcc5ea955405..de699fb2d99f 100644 --- a/packages/web-server/src/server.ts +++ b/packages/web-server/src/server.ts @@ -5,19 +5,14 @@ import path from 'path' import chalk from 'chalk' import { config } from 'dotenv-defaults' import Fastify from 'fastify' -import yargsParser from 'yargs-parser' +import { hideBin } from 'yargs/helpers' +import yargs from 'yargs/yargs' import { getPaths, getConfig } from '@redwoodjs/project-config' import { redwoodFastifyWeb } from './web' import { withApiProxy } from './withApiProxy' -interface Opts { - socket?: string - port?: string - apiHost?: string -} - function isFullyQualifiedUrl(url: string) { try { // eslint-disable-next-line no-new @@ -29,22 +24,29 @@ function isFullyQualifiedUrl(url: string) { } async function serve() { - // Parse server file args - const args = yargsParser(process.argv.slice(2), { - string: ['port', 'socket', 'apiHost'], - alias: { apiHost: ['api-host'], port: ['p'] }, - }) - - const options: Opts = { - socket: args.socket, - port: args.port, - apiHost: args.apiHost, - } + const options = yargs(hideBin(process.argv)) + .scriptName('rw-web-server') + .usage('$0', 'Start server for serving only the web side') + .strict() + + .options({ + port: { + default: getConfig().web?.port || 8910, + type: 'number', + alias: 'p', + }, + socket: { type: 'string' }, + apiHost: { + alias: 'api-host', + type: 'string', + desc: 'Forward requests from the apiUrl, defined in redwood.toml to this host', + }, + }) + .parseSync() const redwoodProjectPaths = getPaths() const redwoodConfig = getConfig() - const port = options.port ? parseInt(options.port) : redwoodConfig.web.port const apiUrl = redwoodConfig.web.apiUrl if (!options.apiHost && !isFullyQualifiedUrl(apiUrl)) { @@ -110,7 +112,7 @@ async function serve() { listenOptions = { path: options.socket } } else { listenOptions = { - port, + port: options.port, host: process.env.NODE_ENV === 'production' ? '0.0.0.0' : '::', } } @@ -121,7 +123,7 @@ async function serve() { if (options.socket) { console.log(`Web server started on ${options.socket}`) } else { - console.log(`Web server started on http://localhost:${port}`) + console.log(`Web server started on http://localhost:${options.port}`) } }) diff --git a/tasks/server-tests/__snapshots__/server.test.mjs.snap b/tasks/server-tests/__snapshots__/server.test.mjs.snap new file mode 100644 index 000000000000..cdb3303211fd --- /dev/null +++ b/tasks/server-tests/__snapshots__/server.test.mjs.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`serve web (/Users/dom/projects/redwood/redwood/packages/web-server/dist/server.js) errors out on unknown args 1`] = ` +"rw-web-server + +Start server for serving only the web side + +Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + +Unknown arguments: foo, bar, baz +" +`; + +exports[`serve web ([ + '/Users/dom/projects/redwood/redwood/packages/api-server/dist/index.js', + 'web' +]) errors out on unknown args 1`] = ` +"rw-server web + +Start server for serving only the web side + +Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + +Unknown arguments: foo, bar, baz +" +`; diff --git a/tasks/server-tests/jest.config.js b/tasks/server-tests/jest.config.js index 6d446413e90f..609bf5d104c9 100644 --- a/tasks/server-tests/jest.config.js +++ b/tasks/server-tests/jest.config.js @@ -1,7 +1,9 @@ /** @type {import('jest').Config} */ const config = { rootDir: '.', + testMatch: ['/*.test.mjs'], testTimeout: 5_000 * 2, + transform: {}, } module.exports = config diff --git a/tasks/server-tests/server.test.ts b/tasks/server-tests/server.test.mjs similarity index 52% rename from tasks/server-tests/server.test.ts rename to tasks/server-tests/server.test.mjs index a7e34f9af9e5..2dc2301bc374 100644 --- a/tasks/server-tests/server.test.ts +++ b/tasks/server-tests/server.test.mjs @@ -1,34 +1,43 @@ -const fs = require('fs') -const http = require('http') -const path = require('path') +/* eslint-disable camelcase */ -const execa = require('execa') +import http from 'node:http' +import { fileURLToPath } from 'node:url' +import { fs, path, $ } from 'zx' + +const __dirname = fileURLToPath(new URL('./', import.meta.url)) + +const FIXTURE_PATH = fileURLToPath( + new URL('./fixtures/redwood-app', import.meta.url) +) + +//////////////////////////////////////////////////////////////// // Set up RWJS_CWD. let original_RWJS_CWD beforeAll(() => { original_RWJS_CWD = process.env.RWJS_CWD - process.env.RWJS_CWD = path.join(__dirname, './fixtures/redwood-app') + process.env.RWJS_CWD = FIXTURE_PATH }) afterAll(() => { process.env.RWJS_CWD = original_RWJS_CWD }) +//////////////////////////////////////////////////////////////// // Clean up the child process after each test. -let child +let p afterEach(async () => { - if (!child) { + if (!p) { return } - child.cancel() + p.kill() // Wait for child process to terminate. try { - await child + await p } catch (e) { // Ignore the error. } @@ -37,18 +46,15 @@ afterEach(async () => { const TIMEOUT = 1_000 * 2 const commandStrings = { - '@redwoodjs/cli': `node ${path.resolve( - __dirname, - '../../packages/cli/dist/index.js' - )} serve`, - '@redwoodjs/api-server': `node ${path.resolve( + '@redwoodjs/cli': path.resolve(__dirname, '../../packages/cli/dist/index.js'), + '@redwoodjs/api-server': path.resolve( __dirname, '../../packages/api-server/dist/index.js' - )}`, - '@redwoodjs/web-server': `node ${path.resolve( + ), + '@redwoodjs/web-server': path.resolve( __dirname, '../../packages/web-server/dist/server.js' - )}`, + ), } const redwoodToml = fs.readFileSync( @@ -61,11 +67,11 @@ const { } = redwoodToml.match(/apiUrl = "(?[^"]*)/) describe.each([ - [`${commandStrings['@redwoodjs/cli']}`], - [`${commandStrings['@redwoodjs/api-server']}`], + [[commandStrings['@redwoodjs/cli'], 'serve']], + [commandStrings['@redwoodjs/api-server']], ])('serve both (%s)', (commandString) => { it('serves both sides, using the apiRootPath in redwood.toml', async () => { - child = execa.command(commandString) + p = $`yarn node ${commandString}` await new Promise((r) => setTimeout(r, TIMEOUT)) const webRes = await fetch('http://localhost:8910/about') @@ -89,7 +95,7 @@ describe.each([ it('--port changes the port', async () => { const port = 8920 - child = execa.command(`${commandString} --port ${port}`) + p = $`yarn node ${commandString} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const webRes = await fetch(`http://localhost:${port}/about`) @@ -109,14 +115,17 @@ describe.each([ expect(apiRes.status).toEqual(200) expect(apiBody).toEqual({ data: 'hello function' }) }) + + it.todo('changing redwood.toml api.port does nothing') + it.todo('changing redwood.toml web.port works') }) describe.each([ - [`${commandStrings['@redwoodjs/cli']} api`], - [`${commandStrings['@redwoodjs/api-server']} api`], + [[commandStrings['@redwoodjs/cli'], 'serve', 'api']], + [[commandStrings['@redwoodjs/api-server'], 'api']], ])('serve api (%s)', (commandString) => { it('serves the api side', async () => { - child = execa.command(commandString) + p = $`yarn node ${commandString}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch('http://localhost:8911/hello') @@ -129,7 +138,7 @@ describe.each([ it('--port changes the port', async () => { const port = 3000 - child = execa.command(`${commandString} --port ${port}`) + p = $`yarn node ${commandString} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${port}/hello`) @@ -142,7 +151,7 @@ describe.each([ it('--apiRootPath changes the prefix', async () => { const apiRootPath = '/api' - child = execa.command(`${commandString} --apiRootPath ${apiRootPath}`) + p = $`yarn node ${commandString} --apiRootPath ${apiRootPath}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:8911${apiRootPath}/hello`) @@ -151,15 +160,18 @@ describe.each([ expect(res.status).toEqual(200) expect(body).toEqual({ data: 'hello function' }) }) + + it.todo('changing redwood.toml api.port works') + it.todo('changing redwood.toml web.apiUrl does nothing?') }) // We can't test @redwoodjs/cli here because it depends on node_modules. describe.each([ - [`${commandStrings['@redwoodjs/api-server']} web`], + [[`${commandStrings['@redwoodjs/api-server']}`, 'web']], [commandStrings['@redwoodjs/web-server']], ])('serve web (%s)', (commandString) => { it('serves the web side', async () => { - child = execa.command(commandString) + p = $`yarn node ${commandString}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch('http://localhost:8910/about') @@ -167,7 +179,7 @@ describe.each([ expect(res.status).toEqual(200) expect(body).toEqual( - fs.readFileSync( + await fs.readFile( path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), 'utf-8' ) @@ -177,7 +189,7 @@ describe.each([ it('--port changes the port', async () => { const port = 8912 - child = execa.command(`${commandString} --port ${port}`) + p = $`yarn node ${commandString} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${port}/about`) @@ -185,7 +197,7 @@ describe.each([ expect(res.status).toEqual(200) expect(body).toEqual( - fs.readFileSync( + await fs.readFile( path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), 'utf-8' ) @@ -206,9 +218,7 @@ describe.each([ server.listen(apiPort, apiHost) - child = execa.command( - `${commandString} --apiHost http://${apiHost}:${apiPort}` - ) + p = $`yarn node ${commandString} --apiHost http://${apiHost}:${apiPort}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch('http://localhost:8910/.redwood/functions/hello') @@ -220,31 +230,34 @@ describe.each([ server.close() }) - it("doesn't error out on unknown args", async () => { - child = execa.command(`${commandString} --foo --bar --baz`) - await new Promise((r) => setTimeout(r, TIMEOUT)) - - const res = await fetch('http://localhost:8910/about') - const body = await res.text() - - expect(res.status).toEqual(200) - expect(body).toEqual( - fs.readFileSync( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) + it('errors out on unknown args', async () => { + try { + await $`yarn node ${commandString} --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchSnapshot() + } }) + + it.todo('changing redwood.toml web.port works') + it.todo("if apiHost isn't set, and apiUrl isn't fully qualified, exits") + it.todo( + "if api host isn't set, and api url is fully qualified, hits upstream" + ) + it.todo( + 'if api host is set, and api url is fully qualified, also breaks cause it tries to proxy?' + ) }) describe('@redwoodjs/cli', () => { describe('both server CLI', () => { - const commandString = commandStrings['@redwoodjs/cli'] - it.todo('handles --socket differently') - it('has help configured', () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it('has help configured', async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve --help` expect(stdout).toMatchInlineSnapshot(` "usage: rw @@ -264,45 +277,51 @@ describe('@redwoodjs/cli', () => { --socket [string] Also see the Redwood CLI Reference - (​https://redwoodjs.com/docs/cli-commands#serve​)" + (​https://redwoodjs.com/docs/cli-commands#serve​) + " `) }) it('errors out on unknown args', async () => { - const { stdout } = execa.commandSync(`${commandString} --foo --bar --baz`) - - expect(stdout).toMatchInlineSnapshot(` - "usage: rw - - Commands: - rw serve Run both api and web servers [default] - rw serve api Start server for serving only the api - rw serve web Start server for serving only the web side - - Options: - --help Show help [boolean] - --version Show version number [boolean] - --cwd Working directory to use (where \`redwood.toml\` is located) - --telemetry Whether to send anonymous usage telemetry to RedwoodJS - [boolean] - -p, --port [number] [default: 8910] - --socket [string] - - Also see the Redwood CLI Reference - (​https://redwoodjs.com/docs/cli-commands#serve​) - - Unknown arguments: foo, bar, baz" - `) + try { + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "usage: rw + + Commands: + rw serve Run both api and web servers [default] + rw serve api Start server for serving only the api + rw serve web Start server for serving only the web side + + Options: + --help Show help [boolean] + --version Show version number [boolean] + --cwd Working directory to use (where \`redwood.toml\` is located) + --telemetry Whether to send anonymous usage telemetry to RedwoodJS + [boolean] + -p, --port [number] [default: 8910] + --socket [string] + + Also see the Redwood CLI Reference + (​https://redwoodjs.com/docs/cli-commands#serve​) + + Unknown arguments: foo, bar, baz + " + `) + } }) }) describe('api server CLI', () => { - const commandString = `${commandStrings['@redwoodjs/cli']} api` - it.todo('handles --socket differently') it('loads dotenv files', async () => { - child = execa.command(`${commandString}`) + p = $`yarn node ${commandStrings['@redwoodjs/cli']} serve api` + await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:8911/env`) @@ -312,8 +331,9 @@ describe('@redwoodjs/cli', () => { expect(body).toEqual({ data: '42' }) }) - it('has help configured', () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it('has help configured', async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve api --help` expect(stdout).toMatchInlineSnapshot(` "rw serve api @@ -330,42 +350,48 @@ describe('@redwoodjs/cli', () => { -p, --port [number] [default: 8911] --socket [string] --apiRootPath, --api-root-path, Root path where your api functions - --rootPath, --root-path are served [string] [default: "/"]" + --rootPath, --root-path are served [string] [default: "/"] + " `) }) it('errors out on unknown args', async () => { - const { stdout } = execa.commandSync(`${commandString} --foo --bar --baz`) - - expect(stdout).toMatchInlineSnapshot(` - "rw serve api - - Start server for serving only the api - - Options: - --help Show help [boolean] - --version Show version number [boolean] - --cwd Working directory to use (where - \`redwood.toml\` is located) - --telemetry Whether to send anonymous usage - telemetry to RedwoodJS [boolean] - -p, --port [number] [default: 8911] - --socket [string] - --apiRootPath, --api-root-path, Root path where your api functions - --rootPath, --root-path are served [string] [default: "/"] - - Unknown arguments: foo, bar, baz" - `) + try { + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve api --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "rw serve api + + Start server for serving only the api + + Options: + --help Show help [boolean] + --version Show version number [boolean] + --cwd Working directory to use (where + \`redwood.toml\` is located) + --telemetry Whether to send anonymous usage + telemetry to RedwoodJS [boolean] + -p, --port [number] [default: 8911] + --socket [string] + --apiRootPath, --api-root-path, Root path where your api functions + --rootPath, --root-path are served [string] [default: "/"] + + Unknown arguments: foo, bar, baz + " + `) + } }) }) describe('web server CLI', () => { - const commandString = `${commandStrings['@redwoodjs/cli']} web` - it.todo('handles --socket differently') - it('has help configured', () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it('has help configured', async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve web --help` expect(stdout).toMatchInlineSnapshot(` "rw serve web @@ -382,44 +408,49 @@ describe('@redwoodjs/cli', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string]" + redwood.toml to this host [string] + " `) }) it('errors out on unknown args', async () => { - const { stdout } = execa.commandSync(`${commandString} --foo --bar --baz`) - - expect(stdout).toMatchInlineSnapshot(` - "rw serve web - - Start server for serving only the web side - - Options: - --help Show help [boolean] - --version Show version number [boolean] - --cwd Working directory to use (where \`redwood.toml\` is - located) - --telemetry Whether to send anonymous usage telemetry to - RedwoodJS [boolean] - -p, --port [number] [default: 8910] - --socket [string] - --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] - - Unknown arguments: foo, bar, baz" - `) + try { + await $`yarn node ${commandStrings['@redwoodjs/cli']} serve web --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "rw serve web + + Start server for serving only the web side + + Options: + --help Show help [boolean] + --version Show version number [boolean] + --cwd Working directory to use (where \`redwood.toml\` is + located) + --telemetry Whether to send anonymous usage telemetry to + RedwoodJS [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + + Unknown arguments: foo, bar, baz + " + `) + } }) }) }) describe('@redwoodjs/api-server', () => { describe('both server CLI', () => { - const commandString = commandStrings['@redwoodjs/api-server'] - it('--socket changes the port', async () => { const socket = 8921 - child = execa.command(`${commandString} --socket ${socket}`) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} --socket ${socket}` await new Promise((r) => setTimeout(r, TIMEOUT)) const webRes = await fetch(`http://localhost:${socket}/about`) @@ -446,9 +477,7 @@ describe('@redwoodjs/api-server', () => { const socket = 8922 const port = 8923 - child = execa.command( - `${commandString} --socket ${socket} --port ${port}` - ) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} --socket ${socket} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const webRes = await fetch(`http://localhost:${socket}/about`) @@ -471,48 +500,60 @@ describe('@redwoodjs/api-server', () => { expect(apiBody).toEqual({ data: 'hello function' }) }) - it("doesn't have help configured", () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it("doesn't have help configured", async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/api-server']} --help` expect(stdout).toMatchInlineSnapshot(` - "Options: - --help Show help [boolean] - --version Show version number [boolean]" - `) - }) - - it("doesn't error out on unknown args", async () => { - child = execa.command(`${commandString} --foo --bar --baz`) - await new Promise((r) => setTimeout(r, TIMEOUT)) + "usage: rw-server - const webRes = await fetch('http://localhost:8910/about') - const webBody = await webRes.text() - - expect(webRes.status).toEqual(200) - expect(webBody).toEqual( - fs.readFileSync( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) + Commands: + rw-server Run both api and web servers [default] + rw-server api Start server for serving only the api + rw-server web Start server for serving only the web side - const apiRes = await fetch( - 'http://localhost:8910/.redwood/functions/hello' - ) - const apiBody = await apiRes.json() + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + " + `) + }) - expect(apiRes.status).toEqual(200) - expect(apiBody).toEqual({ data: 'hello function' }) + it('errors out on unknown args', async () => { + try { + await $`yarn node ${commandStrings['@redwoodjs/api-server']} --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "usage: rw-server + + Commands: + rw-server Run both api and web servers [default] + rw-server api Start server for serving only the api + rw-server web Start server for serving only the web side + + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + + Unknown arguments: foo, bar, baz + " + `) + } }) }) describe('api server CLI', () => { - const commandString = `${commandStrings['@redwoodjs/api-server']} api` - it('--socket changes the port', async () => { const socket = 3001 - child = execa.command(`${commandString} --socket ${socket}`) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} api --socket ${socket}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${socket}/hello`) @@ -526,9 +567,7 @@ describe('@redwoodjs/api-server', () => { const socket = 3002 const port = 3003 - child = execa.command( - `${commandString} --socket ${socket} --port ${port}` - ) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} api --socket ${socket} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${socket}/hello`) @@ -539,7 +578,7 @@ describe('@redwoodjs/api-server', () => { }) it('--loadEnvFiles loads dotenv files', async () => { - child = execa.command(`${commandString} --loadEnvFiles`) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} api --loadEnvFiles` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:8911/env`) @@ -549,35 +588,63 @@ describe('@redwoodjs/api-server', () => { expect(body).toEqual({ data: '42' }) }) - it("doesn't have help configured", () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it('has help configured', async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/api-server']} api --help` expect(stdout).toMatchInlineSnapshot(` - "Options: - --help Show help [boolean] - --version Show version number [boolean]" - `) - }) + "rw-server api - it("doesn't error out on unknown args", async () => { - child = execa.command(`${commandString} --foo --bar --baz`) - await new Promise((r) => setTimeout(r, TIMEOUT)) + Start server for serving only the api - const res = await fetch('http://localhost:8911/hello') - const body = await res.json() + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8911] + --socket [string] + --apiRootPath, --api-root-path, Root path where your api functions + --rootPath, --root-path are served [string] [default: "/"] + --loadEnvFiles Load .env and .env.defaults files + [boolean] [default: false] + " + `) + }) - expect(res.status).toEqual(200) - expect(body).toEqual({ data: 'hello function' }) + it('errors out on unknown args', async () => { + try { + await $`yarn node ${commandStrings['@redwoodjs/api-server']} api --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "rw-server api + + Start server for serving only the api + + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8911] + --socket [string] + --apiRootPath, --api-root-path, Root path where your api functions + --rootPath, --root-path are served [string] [default: "/"] + --loadEnvFiles Load .env and .env.defaults files + [boolean] [default: false] + + Unknown arguments: foo, bar, baz + " + `) + } }) }) describe('web server CLI', () => { - const commandString = `${commandStrings['@redwoodjs/api-server']} web` - it('--socket changes the port', async () => { const socket = 8913 - child = execa.command(`${commandString} --socket ${socket}`) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket}` + await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${socket}/about`) @@ -596,9 +663,7 @@ describe('@redwoodjs/api-server', () => { const socket = 8914 const port = 8915 - child = execa.command( - `${commandString} --socket ${socket} --port ${port}` - ) + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket} --port ${port}` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${socket}/about`) @@ -613,56 +678,74 @@ describe('@redwoodjs/api-server', () => { ) }) - it("doesn't have help configured", () => { - const { stdout } = execa.commandSync(`${commandString} --help`) + it("doesn't have help configured", async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/api-server']} web --help` expect(stdout).toMatchInlineSnapshot(` - "Options: - --help Show help [boolean] - --version Show version number [boolean]" - `) - }) + "rw-server web - it("doesn't error out on unknown args", async () => { - child = execa.command(`${commandString} --foo --bar --baz`, { - stdio: 'inherit', - }) - await new Promise((r) => setTimeout(r, TIMEOUT)) + Start server for serving only the web side - const res = await fetch('http://localhost:8910/about') - const body = await res.text() + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + " + `) + }) - expect(res.status).toEqual(200) - expect(body).toEqual( - fs.readFileSync( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) + it('errors out on unknown args', async () => { + try { + await $`yarn node ${commandStrings['@redwoodjs/api-server']} web --foo --bar --baz` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).toEqual(1) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchInlineSnapshot(` + "rw-server web + + Start server for serving only the web side + + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + + Unknown arguments: foo, bar, baz + " + `) + } }) }) }) describe('@redwoodjs/web-server', () => { - const commandString = commandStrings['@redwoodjs/web-server'] - it.todo('handles --socket differently') - // @redwoodjs/web-server doesn't have help configured in a different way than the others. - // The others output help, it's just empty. This doesn't even do that. It just runs. - it("doesn't have help configured", async () => { - child = execa.command(`${commandString} --help`) - await new Promise((r) => setTimeout(r, TIMEOUT)) + it('has help configured', async () => { + const { stdout } = + await $`yarn node ${commandStrings['@redwoodjs/web-server']} --help` - const res = await fetch('http://localhost:8910/about') - const body = await res.text() + expect(stdout).toMatchInlineSnapshot(` + "rw-web-server - expect(res.status).toEqual(200) - expect(body).toEqual( - fs.readFileSync( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) + Start server for serving only the web side + + Options: + --help Show help [boolean] + --version Show version number [boolean] + -p, --port [number] [default: 8910] + --socket [string] + --apiHost, --api-host Forward requests from the apiUrl, defined in + redwood.toml to this host [string] + " + `) }) }) From 67b7fefe928b5ba675c74a673bed7d07017ee3db Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 10:42:55 -0800 Subject: [PATCH 02/12] Update tasks/server-tests/server.test.mjs Co-authored-by: Tobbe Lundberg --- tasks/server-tests/server.test.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/server-tests/server.test.mjs b/tasks/server-tests/server.test.mjs index 2dc2301bc374..8ead747513f9 100644 --- a/tasks/server-tests/server.test.mjs +++ b/tasks/server-tests/server.test.mjs @@ -241,7 +241,7 @@ describe.each([ } }) - it.todo('changing redwood.toml web.port works') + it.todo('works to change web.port in redwood.toml') it.todo("if apiHost isn't set, and apiUrl isn't fully qualified, exits") it.todo( "if api host isn't set, and api url is fully qualified, hits upstream" From 39194318513027c2803c35a916778eedab0db57f Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 18:49:13 +0000 Subject: [PATCH 03/12] make todos coherent --- tasks/server-tests/server.test.mjs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tasks/server-tests/server.test.mjs b/tasks/server-tests/server.test.mjs index 8ead747513f9..7629e220c5be 100644 --- a/tasks/server-tests/server.test.mjs +++ b/tasks/server-tests/server.test.mjs @@ -116,8 +116,8 @@ describe.each([ expect(apiBody).toEqual({ data: 'hello function' }) }) - it.todo('changing redwood.toml api.port does nothing') - it.todo('changing redwood.toml web.port works') + it.todo("doesn't respect api.port in redwood.toml") + it.todo('respects web.port in redwood.toml') }) describe.each([ @@ -161,8 +161,8 @@ describe.each([ expect(body).toEqual({ data: 'hello function' }) }) - it.todo('changing redwood.toml api.port works') - it.todo('changing redwood.toml web.apiUrl does nothing?') + it.todo('respects api.port in redwood.toml') + it.todo("apiRootPath isn't affected by apiUrl") }) // We can't test @redwoodjs/cli here because it depends on node_modules. @@ -241,14 +241,10 @@ describe.each([ } }) - it.todo('works to change web.port in redwood.toml') - it.todo("if apiHost isn't set, and apiUrl isn't fully qualified, exits") - it.todo( - "if api host isn't set, and api url is fully qualified, hits upstream" - ) - it.todo( - 'if api host is set, and api url is fully qualified, also breaks cause it tries to proxy?' - ) + it.todo('respects web.port in redwood.toml') + it.todo("fails if apiHost isn't set and apiUrl isn't fully qualified") + it.todo("works if apiHost isn't set and apiUrl is fully qualified") + it.todo('fails if apiHost is set and apiUrl is fully qualified') }) describe('@redwoodjs/cli', () => { From 2848100317c5a188f20835fdb975831903b95503 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 19:03:11 +0000 Subject: [PATCH 04/12] update snapshot --- packages/api-server/dist.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/api-server/dist.test.ts b/packages/api-server/dist.test.ts index 120759bd60bc..99b8be0708d0 100644 --- a/packages/api-server/dist.test.ts +++ b/packages/api-server/dist.test.ts @@ -37,6 +37,7 @@ describe('dist', () => { "apiCliOptions": { "apiRootPath": { "alias": [ + "api-root-path", "rootPath", "root-path", ], From ae3af5bbb9b6a8058be2694b557dc11ae8a83512 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 19:19:21 +0000 Subject: [PATCH 05/12] copy fix to api server --- packages/api-server/src/cliHandlers.ts | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/api-server/src/cliHandlers.ts b/packages/api-server/src/cliHandlers.ts index e7fcb0271ac1..62ac141233fa 100644 --- a/packages/api-server/src/cliHandlers.ts +++ b/packages/api-server/src/cliHandlers.ts @@ -128,9 +128,24 @@ export const bothServerHandler = async (options: BothServerArgs) => { export const webServerHandler = async (options: WebServerArgs) => { const { port, socket, apiHost } = options + const apiUrl = getConfig().web.apiUrl + + if (!apiHost && !isFullyQualifiedUrl(apiUrl)) { + console.error( + `${c.red('Error')}: If you don't provide ${c.magenta( + 'apiHost' + )}, ${c.magenta( + 'apiUrl' + )} needs to be a fully-qualified URL. But ${c.magenta( + 'apiUrl' + )} is ${c.yellow(apiUrl)}.` + ) + process.exitCode = 1 + return + } + const tsServer = Date.now() process.stdout.write(c.dim(c.italic('Starting Web Server...\n'))) - const apiUrl = getConfig().web.apiUrl // Construct the graphql url from apiUrl by default // But if apiGraphQLUrl is specified, use that instead const graphqlEndpoint = coerceRootPath( @@ -172,3 +187,13 @@ function coerceRootPath(path: string) { return `${prefix}${path}${suffix}` } + +function isFullyQualifiedUrl(url: string) { + try { + // eslint-disable-next-line no-new + new URL(url) + return true + } catch (e) { + return false + } +} From d53b41585e0864cfe772627b1b8f04d882a07e36 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 20:41:55 +0000 Subject: [PATCH 06/12] fix web-server deps --- packages/web-server/package.json | 3 +-- yarn.lock | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-server/package.json b/packages/web-server/package.json index 152c3a59401c..63dbc2e29abb 100644 --- a/packages/web-server/package.json +++ b/packages/web-server/package.json @@ -34,10 +34,9 @@ "dotenv-defaults": "5.0.2", "fast-glob": "3.3.2", "fastify": "4.24.3", - "yargs-parser": "21.1.1" + "yargs": "17.7.2" }, "devDependencies": { - "@types/yargs-parser": "21.0.3", "esbuild": "0.19.9", "typescript": "5.3.3" }, diff --git a/yarn.lock b/yarn.lock index 3c992ebdd81e..48633b73ef43 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9610,6 +9610,7 @@ __metadata: fast-glob: "npm:3.3.2" fastify: "npm:4.24.3" typescript: "npm:5.3.3" + yargs: "npm:17.7.2" yargs-parser: "npm:21.1.1" bin: rw-web-server: ./dist/server.js From 8bf4330d299057be23c35d6822f6c90a1d5cc746 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Jan 2024 20:48:51 +0000 Subject: [PATCH 07/12] update yarn lock --- yarn.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 48633b73ef43..9557622de5f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9603,7 +9603,6 @@ __metadata: "@fastify/static": "npm:6.12.0" "@fastify/url-data": "npm:5.4.0" "@redwoodjs/project-config": "npm:6.0.7" - "@types/yargs-parser": "npm:21.0.3" chalk: "npm:4.1.2" dotenv-defaults: "npm:5.0.2" esbuild: "npm:0.19.9" @@ -9611,7 +9610,6 @@ __metadata: fastify: "npm:4.24.3" typescript: "npm:5.3.3" yargs: "npm:17.7.2" - yargs-parser: "npm:21.1.1" bin: rw-web-server: ./dist/server.js languageName: unknown From f0512aa2d6baaa5fc22b667381eb85c60cb13765 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Mon, 8 Jan 2024 01:20:33 +0000 Subject: [PATCH 08/12] update tests --- .../__snapshots__/server.test.mjs.snap | 13 ++++ tasks/server-tests/server.test.mjs | 64 +++++++++---------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/tasks/server-tests/__snapshots__/server.test.mjs.snap b/tasks/server-tests/__snapshots__/server.test.mjs.snap index cdb3303211fd..a6a9b7299dee 100644 --- a/tasks/server-tests/__snapshots__/server.test.mjs.snap +++ b/tasks/server-tests/__snapshots__/server.test.mjs.snap @@ -17,6 +17,11 @@ Unknown arguments: foo, bar, baz " `; +exports[`serve web (/Users/dom/projects/redwood/redwood/packages/web-server/dist/server.js) fails if apiHost isn't set and apiUrl isn't fully qualified 1`] = ` +"Error: If you don't provide apiHost, apiUrl needs to be a fully-qualified URL. But apiUrl is /.redwood/functions. +" +`; + exports[`serve web ([ '/Users/dom/projects/redwood/redwood/packages/api-server/dist/index.js', 'web' @@ -36,3 +41,11 @@ Options: Unknown arguments: foo, bar, baz " `; + +exports[`serve web ([ + '/Users/dom/projects/redwood/redwood/packages/api-server/dist/index.js', + 'web' +]) fails if apiHost isn't set and apiUrl isn't fully qualified 1`] = ` +"Error: If you don't provide apiHost, apiUrl needs to be a fully-qualified URL. But apiUrl is /.redwood/functions. +" +`; diff --git a/tasks/server-tests/server.test.mjs b/tasks/server-tests/server.test.mjs index 7629e220c5be..5b0d67c70c8f 100644 --- a/tasks/server-tests/server.test.mjs +++ b/tasks/server-tests/server.test.mjs @@ -170,38 +170,15 @@ describe.each([ [[`${commandStrings['@redwoodjs/api-server']}`, 'web']], [commandStrings['@redwoodjs/web-server']], ])('serve web (%s)', (commandString) => { - it('serves the web side', async () => { - p = $`yarn node ${commandString}` - await new Promise((r) => setTimeout(r, TIMEOUT)) - - const res = await fetch('http://localhost:8910/about') - const body = await res.text() - - expect(res.status).toEqual(200) - expect(body).toEqual( - await fs.readFile( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) - }) - - it('--port changes the port', async () => { - const port = 8912 - - p = $`yarn node ${commandString} --port ${port}` - await new Promise((r) => setTimeout(r, TIMEOUT)) - - const res = await fetch(`http://localhost:${port}/about`) - const body = await res.text() - - expect(res.status).toEqual(200) - expect(body).toEqual( - await fs.readFile( - path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), - 'utf-8' - ) - ) + it("fails if apiHost isn't set and apiUrl isn't fully qualified", async () => { + try { + await $`yarn node ${commandString}` + expect(true).toEqual(false) + } catch (p) { + expect(p.exitCode).not.toEqual(0) + expect(p.stdout).toEqual('') + expect(p.stderr).toMatchSnapshot() + } }) it('--apiHost changes the upstream api url', async () => { @@ -230,6 +207,24 @@ describe.each([ server.close() }) + it('--port changes the port', async () => { + const port = 8912 + + p = $`yarn node ${commandString} --apiHost http://localhost:8916 --port ${port}` + await new Promise((r) => setTimeout(r, TIMEOUT)) + + const res = await fetch(`http://localhost:${port}/about`) + const body = await res.text() + + expect(res.status).toEqual(200) + expect(body).toEqual( + await fs.readFile( + path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'), + 'utf-8' + ) + ) + }) + it('errors out on unknown args', async () => { try { await $`yarn node ${commandString} --foo --bar --baz` @@ -242,7 +237,6 @@ describe.each([ }) it.todo('respects web.port in redwood.toml') - it.todo("fails if apiHost isn't set and apiUrl isn't fully qualified") it.todo("works if apiHost isn't set and apiUrl is fully qualified") it.todo('fails if apiHost is set and apiUrl is fully qualified') }) @@ -639,7 +633,7 @@ describe('@redwoodjs/api-server', () => { it('--socket changes the port', async () => { const socket = 8913 - p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket}` + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket} --apiHost="http://localhost:8910"` await new Promise((r) => setTimeout(r, TIMEOUT)) @@ -659,7 +653,7 @@ describe('@redwoodjs/api-server', () => { const socket = 8914 const port = 8915 - p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket} --port ${port}` + p = $`yarn node ${commandStrings['@redwoodjs/api-server']} web --socket ${socket} --port ${port} --apiHost="http://localhost:8910"` await new Promise((r) => setTimeout(r, TIMEOUT)) const res = await fetch(`http://localhost:${socket}/about`) From e0b64fd2eb3ed0e472dd867ebb53426a86a82391 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Fri, 19 Jan 2024 04:08:56 -0800 Subject: [PATCH 09/12] Update packages/cli/src/index.js Co-authored-by: Tobbe Lundberg --- packages/cli/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/index.js b/packages/cli/src/index.js index 9945e65fcb9f..87553fe11243 100644 --- a/packages/cli/src/index.js +++ b/packages/cli/src/index.js @@ -219,7 +219,7 @@ async function runYargs() { // Run await yarg.parse(process.argv.slice(2), {}, (err, _argv, output) => { // Configuring yargs with `strict` makes it error on unknown args; - // here we're propagating the exit code. + // here we're signaling that with an exit code. if (err) { process.exitCode = 1 } From 95f9697b1d2eddaca34f37dff3e149ff7e55cff1 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Fri, 19 Jan 2024 04:09:04 -0800 Subject: [PATCH 10/12] Update packages/web-server/src/server.ts Co-authored-by: Tobbe Lundberg --- packages/web-server/src/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-server/src/server.ts b/packages/web-server/src/server.ts index de699fb2d99f..974376a83c20 100644 --- a/packages/web-server/src/server.ts +++ b/packages/web-server/src/server.ts @@ -39,7 +39,7 @@ async function serve() { apiHost: { alias: 'api-host', type: 'string', - desc: 'Forward requests from the apiUrl, defined in redwood.toml to this host', + desc: 'Forward requests from the apiUrl, defined in redwood.toml, to this host', }, }) .parseSync() From 47abe03620673136d89f7e3d2e18fa89fea29d71 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Fri, 19 Jan 2024 12:10:03 +0000 Subject: [PATCH 11/12] add comma to description everywhere else --- packages/api-server/dist.test.ts | 2 +- packages/api-server/src/cliHandlers.ts | 2 +- packages/cli/src/commands/serve.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/api-server/dist.test.ts b/packages/api-server/dist.test.ts index 99b8be0708d0..5dbc290a5937 100644 --- a/packages/api-server/dist.test.ts +++ b/packages/api-server/dist.test.ts @@ -75,7 +75,7 @@ describe('dist', () => { "webCliOptions": { "apiHost": { "alias": "api-host", - "desc": "Forward requests from the apiUrl, defined in redwood.toml to this host", + "desc": "Forward requests from the apiUrl, defined in redwood.toml, to this host", "type": "string", }, "port": { diff --git a/packages/api-server/src/cliHandlers.ts b/packages/api-server/src/cliHandlers.ts index 62ac141233fa..a1fadee69b47 100644 --- a/packages/api-server/src/cliHandlers.ts +++ b/packages/api-server/src/cliHandlers.ts @@ -49,7 +49,7 @@ export const webCliOptions = { apiHost: { alias: 'api-host', type: 'string', - desc: 'Forward requests from the apiUrl, defined in redwood.toml to this host', + desc: 'Forward requests from the apiUrl, defined in redwood.toml, to this host', }, } as const diff --git a/packages/cli/src/commands/serve.js b/packages/cli/src/commands/serve.js index d06a3e871a00..296ac6715871 100644 --- a/packages/cli/src/commands/serve.js +++ b/packages/cli/src/commands/serve.js @@ -122,7 +122,7 @@ export const builder = async (yargs) => { apiHost: { alias: 'api-host', type: 'string', - desc: 'Forward requests from the apiUrl, defined in redwood.toml to this host', + desc: 'Forward requests from the apiUrl, defined in redwood.toml, to this host', }, }), handler: async (argv) => { From af2ce5a3e46f929abf2d1aa981d2b9b779ba0c15 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Fri, 19 Jan 2024 12:17:02 +0000 Subject: [PATCH 12/12] update snapshots --- tasks/server-tests/__snapshots__/server.test.mjs.snap | 4 ++-- tasks/server-tests/server.test.mjs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tasks/server-tests/__snapshots__/server.test.mjs.snap b/tasks/server-tests/__snapshots__/server.test.mjs.snap index a6a9b7299dee..4db853b513af 100644 --- a/tasks/server-tests/__snapshots__/server.test.mjs.snap +++ b/tasks/server-tests/__snapshots__/server.test.mjs.snap @@ -11,7 +11,7 @@ Options: -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] Unknown arguments: foo, bar, baz " @@ -36,7 +36,7 @@ Options: -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] Unknown arguments: foo, bar, baz " diff --git a/tasks/server-tests/server.test.mjs b/tasks/server-tests/server.test.mjs index 5b0d67c70c8f..7b32fb434719 100644 --- a/tasks/server-tests/server.test.mjs +++ b/tasks/server-tests/server.test.mjs @@ -398,7 +398,7 @@ describe('@redwoodjs/cli', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] " `) }) @@ -425,7 +425,7 @@ describe('@redwoodjs/cli', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] Unknown arguments: foo, bar, baz " @@ -683,7 +683,7 @@ describe('@redwoodjs/api-server', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] " `) }) @@ -706,7 +706,7 @@ describe('@redwoodjs/api-server', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] Unknown arguments: foo, bar, baz " @@ -734,7 +734,7 @@ describe('@redwoodjs/web-server', () => { -p, --port [number] [default: 8910] --socket [string] --apiHost, --api-host Forward requests from the apiUrl, defined in - redwood.toml to this host [string] + redwood.toml, to this host [string] " `) })