diff --git a/docs/generated/packages/node/generators/application.json b/docs/generated/packages/node/generators/application.json index 475858fdab230..1384e97cdf1b7 100644 --- a/docs/generated/packages/node/generators/application.json +++ b/docs/generated/packages/node/generators/application.json @@ -104,6 +104,12 @@ "default": false, "hidden": true, "x-priority": "internal" + }, + "e2eTestRunner": { + "type": "string", + "enum": ["jest", "none"], + "description": "Test runner to use for end to end (e2e) tests", + "default": "jest" } }, "required": [], diff --git a/e2e/node/src/node-server.test.ts b/e2e/node/src/node-server.test.ts new file mode 100644 index 0000000000000..150214dc80c09 --- /dev/null +++ b/e2e/node/src/node-server.test.ts @@ -0,0 +1,63 @@ +import { + checkFilesDoNotExist, + cleanupProject, + killPort, + newProject, + promisifiedTreeKill, + runCLI, + runCommandUntil, + uniq, +} from '@nrwl/e2e/utils'; + +describe('Node Applications + webpack', () => { + beforeEach(() => newProject()); + + afterEach(() => cleanupProject()); + + async function runE2eTests(appName: string) { + process.env.PORT = '5000'; + const childProcess = await runCommandUntil(`serve ${appName}`, (output) => { + return output.includes('http://localhost:5000'); + }); + const result = runCLI(`e2e ${appName}-e2e`); + expect(result).toContain('Setting up...'); + expect(result).toContain('Tearing down..'); + expect(result).toContain('Successfully ran target e2e'); + + await promisifiedTreeKill(childProcess.pid, 'SIGKILL'); + await killPort(5000); + process.env.PORT = ''; + } + + it('should generate an app using webpack', async () => { + const expressApp = uniq('expressapp'); + const fastifyApp = uniq('fastifyapp'); + const koaApp = uniq('koaapp'); + + runCLI( + `generate @nrwl/node:app ${expressApp} --framework=express --no-interactive` + ); + runCLI( + `generate @nrwl/node:app ${fastifyApp} --framework=fastify --no-interactive` + ); + runCLI( + `generate @nrwl/node:app ${koaApp} --framework=koa --no-interactive` + ); + + // Use esbuild by default + checkFilesDoNotExist(`apps/${expressApp}/webpack.config.js`); + checkFilesDoNotExist(`apps/${fastifyApp}/webpack.config.js`); + checkFilesDoNotExist(`apps/${koaApp}/webpack.config.js`); + + expect(() => runCLI(`lint ${expressApp}`)).not.toThrow(); + expect(() => runCLI(`lint ${fastifyApp}`)).not.toThrow(); + expect(() => runCLI(`lint ${koaApp}`)).not.toThrow(); + expect(() => runCLI(`lint ${expressApp}-e2e`)).not.toThrow(); + expect(() => runCLI(`lint ${fastifyApp}-e2e`)).not.toThrow(); + expect(() => runCLI(`lint ${koaApp}-e2e`)).not.toThrow(); + + await runE2eTests(expressApp); + await runE2eTests(fastifyApp); + await runE2eTests(koaApp); + }, 300_000); +}); diff --git a/packages/node/package.json b/packages/node/package.json index 78dce2e90deaf..445db110b3648 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -37,7 +37,6 @@ "@nrwl/linter": "file:../linter", "@nrwl/webpack": "file:../webpack", "@nrwl/workspace": "file:../workspace", - "enquirer": "~2.3.6", "tslib": "^2.3.0" }, "publishConfig": { diff --git a/packages/node/src/generators/application/application.spec.ts b/packages/node/src/generators/application/application.spec.ts index f1c4c81f24f11..c6e7bbaa6e27f 100644 --- a/packages/node/src/generators/application/application.spec.ts +++ b/packages/node/src/generators/application/application.spec.ts @@ -87,9 +87,9 @@ describe('app', () => { lintFilePatterns: ['my-node-app/**/*.ts'], }, }); - expect(() => readProjectConfiguration(tree, 'my-node-app-e2e')).toThrow( - /Cannot find/ - ); + expect(() => + readProjectConfiguration(tree, 'my-node-app-e2e') + ).not.toThrow(); }); it('should update tags', async () => { diff --git a/packages/node/src/generators/application/application.ts b/packages/node/src/generators/application/application.ts index 18d175f79e238..8ac6ab2c50ffa 100644 --- a/packages/node/src/generators/application/application.ts +++ b/packages/node/src/generators/application/application.ts @@ -27,7 +27,7 @@ import { Linter, lintProjectGenerator } from '@nrwl/linter'; import { jestProjectGenerator } from '@nrwl/jest'; import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial'; -import { NodeJsFrameWorks, Schema } from './schema'; +import { Schema } from './schema'; import { initGenerator } from '../init/init'; import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript'; import { @@ -41,9 +41,9 @@ import { koaVersion, nxVersion, } from '../../utils/versions'; -import { prompt } from 'enquirer'; import * as shared from '@nrwl/workspace/src/utils/create-ts-config'; +import { e2eProjectGenerator } from '../e2e-project/e2e-project'; export interface NormalizedSchema extends Schema { appProjectRoot: string; @@ -318,15 +318,16 @@ function updateTsConfigOptions(tree: Tree, options: NormalizedSchema) { export async function applicationGenerator(tree: Tree, schema: Schema) { const options = normalizeOptions(tree, schema); - const tasks: GeneratorCallback[] = []; + const initTask = await initGenerator(tree, { ...options, skipFormat: true, }); tasks.push(initTask); - addProjectDependencies(tree, options); + const installTask = addProjectDependencies(tree, options); + tasks.push(installTask); addAppFiles(tree, options); addProject(tree, options); @@ -347,12 +348,24 @@ export async function applicationGenerator(tree: Tree, schema: Schema) { setupFile: 'none', skipSerializers: true, supportTsx: options.js, - babelJest: options.babelJest, testEnvironment: 'node', + compiler: 'tsc', skipFormat: true, }); tasks.push(jestTask); } + + if (options.e2eTestRunner === 'jest') { + const e2eTask = await e2eProjectGenerator(tree, { + ...options, + projectType: options.framework === 'none' ? 'cli' : 'server', + name: options.rootProject ? 'e2e' : `${options.name}-e2e`, + project: options.name, + port: options.port, + }); + tasks.push(e2eTask); + } + if (options.js) { updateTsConfigsToJs(tree, { projectRoot: options.appProjectRoot }); } @@ -385,6 +398,7 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema { : joinPathFragments(appsDir, appDirectory); options.bundler = options.bundler ?? 'esbuild'; + options.e2eTestRunner = options.e2eTestRunner ?? 'jest'; const parsedTags = options.tags ? options.tags.split(',').map((s) => s.trim()) @@ -400,6 +414,7 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema { parsedTags, linter: options.linter ?? Linter.EsLint, unitTestRunner: options.unitTestRunner ?? 'jest', + rootProject: options.rootProject ?? false, port: options.port ?? 3000, }; } diff --git a/packages/node/src/generators/application/files/connect/src/main.ts__tmpl__ b/packages/node/src/generators/application/files/connect/src/main.ts__tmpl__ index 51ff1d4c91e9d..abb5dd17808b4 100644 --- a/packages/node/src/generators/application/files/connect/src/main.ts__tmpl__ +++ b/packages/node/src/generators/application/files/connect/src/main.ts__tmpl__ @@ -1,11 +1,13 @@ import connect from 'connect'; +const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; + const app = connect(); app.use((req, res) => { res.end(JSON.stringify({ 'message': 'Hello API' })); }); -app.listen(<%= port %>, () => { - // Server is running -}) \ No newline at end of file +app.listen(port, () => { + console.log(`[ ready ] http://localhost:${port}`); +}) diff --git a/packages/node/src/generators/application/files/express/src/main.ts__tmpl__ b/packages/node/src/generators/application/files/express/src/main.ts__tmpl__ index 4b3ab24cd7340..ff8cc91f14916 100644 --- a/packages/node/src/generators/application/files/express/src/main.ts__tmpl__ +++ b/packages/node/src/generators/application/files/express/src/main.ts__tmpl__ @@ -1,11 +1,13 @@ import express from 'express'; -const app = express(); +const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; + +const app = express(); app.get('/', (req, res) => { res.send({ 'message': 'Hello API'}); }); -app.listen(<%= port %>, () => { - // Server is running -}); \ No newline at end of file +app.listen(port, () => { + console.log(`[ ready ] http://localhost:${port}`); +}); diff --git a/packages/node/src/generators/application/files/fastify/src/main.ts__tmpl__ b/packages/node/src/generators/application/files/fastify/src/main.ts__tmpl__ index 578ded217b4bb..55d5885312e96 100644 --- a/packages/node/src/generators/application/files/fastify/src/main.ts__tmpl__ +++ b/packages/node/src/generators/application/files/fastify/src/main.ts__tmpl__ @@ -1,5 +1,7 @@ import fastify from 'fastify'; +const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; + const app = fastify(); app.get('/', async (req, res) => { @@ -8,11 +10,12 @@ app.get('/', async (req, res) => { const start = async() => { try { - await app.listen({ port: <%= port %> }) + await app.listen({ port }); + console.log(`[ ready ] http://localhost:${port}`); } catch (err) { // Errors are logged here process.exit(1); } } -start(); \ No newline at end of file +start(); diff --git a/packages/node/src/generators/application/files/koa/src/main.ts__tmpl__ b/packages/node/src/generators/application/files/koa/src/main.ts__tmpl__ index 0266c0862196d..34b4ed4bfc878 100644 --- a/packages/node/src/generators/application/files/koa/src/main.ts__tmpl__ +++ b/packages/node/src/generators/application/files/koa/src/main.ts__tmpl__ @@ -1,11 +1,13 @@ import koa from 'koa'; +const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; + const app = new koa(); app.use(async ctx =>{ ctx.body = { 'message': 'Hello API'}; }); -app.listen(<%= port %>, () => { - // Server is running -}); \ No newline at end of file +app.listen(port, () => { + console.log(`[ ready ] http://localhost:${port}`); +}); diff --git a/packages/node/src/generators/application/schema.d.ts b/packages/node/src/generators/application/schema.d.ts index bebf50f8ff83d..d84dc2abcf8ec 100644 --- a/packages/node/src/generators/application/schema.d.ts +++ b/packages/node/src/generators/application/schema.d.ts @@ -6,6 +6,7 @@ export interface Schema { skipPackageJson?: boolean; directory?: string; unitTestRunner?: 'jest' | 'none'; + e2eTestRunner?: 'jest' | 'none'; linter?: Linter; tags?: string; frontendProject?: string; diff --git a/packages/node/src/generators/application/schema.json b/packages/node/src/generators/application/schema.json index 77ddc8d2ac22c..1c6603344e65c 100644 --- a/packages/node/src/generators/application/schema.json +++ b/packages/node/src/generators/application/schema.json @@ -104,6 +104,12 @@ "default": false, "hidden": true, "x-priority": "internal" + }, + "e2eTestRunner": { + "type": "string", + "enum": ["jest", "none"], + "description": "Test runner to use for end to end (e2e) tests", + "default": "jest" } }, "required": [] diff --git a/packages/node/src/generators/e2e-project/e2e-project.ts b/packages/node/src/generators/e2e-project/e2e-project.ts new file mode 100644 index 0000000000000..dbc2740ca92d6 --- /dev/null +++ b/packages/node/src/generators/e2e-project/e2e-project.ts @@ -0,0 +1,123 @@ +import * as path from 'path'; +import { + addDependenciesToPackageJson, + addProjectConfiguration, + convertNxGenerator, + extractLayoutDirectory, + formatFiles, + generateFiles, + GeneratorCallback, + getWorkspaceLayout, + joinPathFragments, + names, + offsetFromRoot, + readProjectConfiguration, + Tree, +} from '@nrwl/devkit'; +import { Linter, lintProjectGenerator } from '@nrwl/linter'; + +import { Schema } from './schema'; +import { axiosVersion } from '../../utils/versions'; +import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial'; + +export async function e2eProjectGenerator(host: Tree, _options: Schema) { + const tasks: GeneratorCallback[] = []; + const options = normalizeOptions(host, _options); + const appProject = readProjectConfiguration(host, options.project); + + addProjectConfiguration(host, options.projectName, { + root: options.projectRoot, + targets: { + e2e: { + executor: '@nrwl/jest:jest', + outputs: ['{workspaceRoot}/coverage/{projectRoot}'], + options: { + jestConfig: `${options.projectRoot}/jest.config.ts`, + passWithNoTests: true, + }, + }, + }, + }); + + if (options.projectType === 'server') { + generateFiles( + host, + path.join(__dirname, 'files/server'), + options.projectRoot, + { + ...options, + ...names(options.projectName), + offsetFromRoot: offsetFromRoot(options.projectRoot), + tmpl: '', + } + ); + } else if (options.projectType === 'cli') { + const mainFile = appProject.targets.build?.options?.outputPath; + generateFiles( + host, + path.join(__dirname, 'files/cli'), + options.projectRoot, + { + ...options, + ...names(options.projectName), + mainFile, + offsetFromRoot: offsetFromRoot(options.projectRoot), + tmpl: '', + } + ); + } + + // axios is more than likely used in the application code, so install it as a regular dependency. + const installTask = addDependenciesToPackageJson( + host, + { axios: axiosVersion }, + {} + ); + tasks.push(installTask); + + if (options.linter === 'eslint') { + const linterTask = await lintProjectGenerator(host, { + project: options.projectName, + linter: Linter.EsLint, + skipFormat: true, + tsConfigPaths: [joinPathFragments(options.projectRoot, 'tsconfig.json')], + eslintFilePatterns: [`${options.projectRoot}/**/*.{js,ts}`], + setParserOptionsProject: false, + skipPackageJson: false, + rootProject: options.rootProject, + }); + tasks.push(linterTask); + } + + if (options.formatFile) { + await formatFiles(host); + } + + return runTasksInSerial(...tasks); +} + +function normalizeOptions( + tree: Tree, + options: Schema +): Omit & { projectRoot: string; projectName: string } { + const { layoutDirectory, projectDirectory } = extractLayoutDirectory( + options.directory + ); + const appsDir = layoutDirectory ?? getWorkspaceLayout(tree).appsDir; + const name = options.name ?? `${options.project}-e2e`; + + const appDirectory = projectDirectory + ? `${names(projectDirectory).fileName}/${names(name).fileName}` + : names(name).fileName; + + const projectName = appDirectory.replace(new RegExp('/', 'g'), '-'); + + const projectRoot = options.rootProject + ? 'e2e' + : joinPathFragments(appsDir, appDirectory); + + return { ...options, projectRoot, projectName, port: options.port ?? 3000 }; +} + +export default e2eProjectGenerator; +export const e2eProjectSchematic = convertNxGenerator(e2eProjectGenerator); diff --git a/packages/node/src/generators/e2e-project/files/cli/jest.config.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/cli/jest.config.ts__tmpl__ new file mode 100644 index 0000000000000..8ad05dd08ee50 --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/cli/jest.config.ts__tmpl__ @@ -0,0 +1,17 @@ +/* eslint-disable */ +export default { + displayName: '<%= projectName %>', + preset: '<%= offsetFromRoot %>/jest.preset.js', + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + }, + }, + setupFiles: ['/src/test-setup.ts'], + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '<%= offsetFromRoot %>/coverage/<%= projectName %>', +}; diff --git a/packages/node/src/generators/e2e-project/files/cli/src/__fileName__/__fileName__.spec.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/cli/src/__fileName__/__fileName__.spec.ts__tmpl__ new file mode 100644 index 0000000000000..1b1971bb24ba9 --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/cli/src/__fileName__/__fileName__.spec.ts__tmpl__ @@ -0,0 +1,13 @@ +import { execSync } from 'child_process'; +import { join } from 'path'; + +describe('CLI tests', () => { + it('should print a message', () => { + const cliPath = join(process.cwd(), <%= mainFile %>); + + const output = execSync(`node ${cliPath}`).toString(); + + expect(output).toMatch(/Hello World/); + }); +}); + diff --git a/packages/node/src/generators/e2e-project/files/cli/src/test-setup.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/cli/src/test-setup.ts__tmpl__ new file mode 100644 index 0000000000000..8337712ea57f0 --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/cli/src/test-setup.ts__tmpl__ @@ -0,0 +1 @@ +// diff --git a/packages/node/src/generators/e2e-project/files/cli/tsconfig.json__tmpl__ b/packages/node/src/generators/e2e-project/files/cli/tsconfig.json__tmpl__ new file mode 100644 index 0000000000000..a038446e2badf --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/cli/tsconfig.json__tmpl__ @@ -0,0 +1,13 @@ +{ + "extends": "<%= offsetFromRoot %><% if (rootProject) { %>tsconfig.json<% } else { %>tsconfig.base.json<% } %>", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/packages/node/src/generators/e2e-project/files/cli/tsconfig.spec.json__tmpl__ b/packages/node/src/generators/e2e-project/files/cli/tsconfig.spec.json__tmpl__ new file mode 100644 index 0000000000000..2c05fb02dcbab --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/cli/tsconfig.spec.json__tmpl__ @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "<%= offsetFromRoot %>/dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.ts" + ] +} diff --git a/packages/node/src/generators/e2e-project/files/server/jest.config.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/server/jest.config.ts__tmpl__ new file mode 100644 index 0000000000000..075bd21f96a2c --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/jest.config.ts__tmpl__ @@ -0,0 +1,19 @@ +/* eslint-disable */ +export default { + displayName: '<%= projectName %>', + preset: '<%= offsetFromRoot %>jest.preset.js', + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + }, + }, + globalSetup: '/src/support/global-setup.ts', + globalTeardown: '/src/support/global-teardown.ts', + setupFiles: ['/src/support/test-setup.ts'], + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '<%= offsetFromRoot %>coverage/<%= projectName %>', +}; diff --git a/packages/node/src/generators/e2e-project/files/server/src/__fileName__/__fileName__.spec.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/server/src/__fileName__/__fileName__.spec.ts__tmpl__ new file mode 100644 index 0000000000000..c3fa5675f3716 --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/src/__fileName__/__fileName__.spec.ts__tmpl__ @@ -0,0 +1,10 @@ +import axios from 'axios'; + +describe('GET /', () => { + it('should return a message', async () => { + const res = await axios.get(`/`); + + expect(res.status).toBe(200);; + expect(res.data).toEqual({ message: 'Hello API' }); + }); +}) diff --git a/packages/node/src/generators/e2e-project/files/server/src/support/global-setup.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/server/src/support/global-setup.ts__tmpl__ new file mode 100644 index 0000000000000..d18e0f2947ea3 --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/src/support/global-setup.ts__tmpl__ @@ -0,0 +1,11 @@ +/* eslint-disable */ +var __TEARDOWN_MESSAGE__: string; + +module.exports = async function() { + // Start services that that the app needs to run (e.g. database, docker-compose, etc.). + console.log('\nSetting up...\n'); + + // Hint: Use `globalThis` to pass variables to global teardown. + globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n'; +}; + diff --git a/packages/node/src/generators/e2e-project/files/server/src/support/global-teardown.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/server/src/support/global-teardown.ts__tmpl__ new file mode 100644 index 0000000000000..67746cebd358c --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/src/support/global-teardown.ts__tmpl__ @@ -0,0 +1,7 @@ +/* eslint-disable */ + +module.exports = async function() { + // Put clean up logic here (e.g. stopping services, docker-compose, etc.). + // Hint: `globalThis` is shared between setup and teardown. + console.log(globalThis.__TEARDOWN_MESSAGE__); +}; diff --git a/packages/node/src/generators/e2e-project/files/server/src/support/test-setup.ts__tmpl__ b/packages/node/src/generators/e2e-project/files/server/src/support/test-setup.ts__tmpl__ new file mode 100644 index 0000000000000..79ff96994111f --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/src/support/test-setup.ts__tmpl__ @@ -0,0 +1,10 @@ +/* eslint-disable */ + +import axios from 'axios'; + +module.exports = async function() { + // Configure axios for tests to use. + const host = process.env.HOST ?? 'localhost'; + const port = process.env.PORT ?? '<%= port %>'; + axios.defaults.baseURL = `http://${host}:${port}`; +}; diff --git a/packages/node/src/generators/e2e-project/files/server/tsconfig.json__tmpl__ b/packages/node/src/generators/e2e-project/files/server/tsconfig.json__tmpl__ new file mode 100644 index 0000000000000..a038446e2badf --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/tsconfig.json__tmpl__ @@ -0,0 +1,13 @@ +{ + "extends": "<%= offsetFromRoot %><% if (rootProject) { %>tsconfig.json<% } else { %>tsconfig.base.json<% } %>", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/packages/node/src/generators/e2e-project/files/server/tsconfig.spec.json__tmpl__ b/packages/node/src/generators/e2e-project/files/server/tsconfig.spec.json__tmpl__ new file mode 100644 index 0000000000000..c0816756157bc --- /dev/null +++ b/packages/node/src/generators/e2e-project/files/server/tsconfig.spec.json__tmpl__ @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "<%= offsetFromRoot %>dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.ts" + ] +} diff --git a/packages/node/src/generators/e2e-project/schema.d.ts b/packages/node/src/generators/e2e-project/schema.d.ts new file mode 100644 index 0000000000000..64220c1cc2a86 --- /dev/null +++ b/packages/node/src/generators/e2e-project/schema.d.ts @@ -0,0 +1,10 @@ +export interface Schema { + project: string; + projectType: 'server' | 'cli'; + directory?: string; + name?: string; + port?: number; + linter?: 'eslint' | 'none'; + formatFile?: boolean; + rootProject?: boolean; +} diff --git a/packages/node/src/generators/e2e-project/schema.json b/packages/node/src/generators/e2e-project/schema.json new file mode 100644 index 0000000000000..ac1f325d1711a --- /dev/null +++ b/packages/node/src/generators/e2e-project/schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/schema", + "cli": "nx", + "$id": "SchematicsNxNodeE2eProject", + "title": "Node E2E Project Generator", + "description": "Generate an E2E project for a Node server application.", + "type": "object", + "properties": { + "project": { + "type": "string", + "description": "The name of the project.", + "$default": { "$source": "argv", "index": 0 }, + "x-dropdown": "project", + "x-prompt": "What project is this for?" + }, + "directory": { + "description": "The directory of the e2e project.", + "type": "string", + "x-priority": "important" + }, + "name": { + "description": "The name of the e2e project. Defaults to the project name with '-e2e' suffix.", + "type": "string" + }, + "projectType": { + "description": "The type of application that is being tested.", + "type": "string", + "enum": ["server", "cli"], + "default": "server" + }, + "port": { + "description": "The port that the server runs on. Only application for server application.", + "type": "number", + "default": 3000 + }, + "linter": { + "description": "Linter to be used for the E2E project", + "type": "string", + "enum": ["eslint", "none"], + "default": "eslint" + }, + "rootProject": { + "description": "Create node application at the root of the workspace.", + "type": "boolean", + "default": false, + "hidden": true, + "x-priority": "internal" + }, + "formatFiles": { + "description": "Format generated files.", + "type": "boolean", + "default": true, + "hidden": true, + "x-priority": "internal" + } + }, + "required": ["project"] +} diff --git a/packages/node/src/utils/versions.ts b/packages/node/src/utils/versions.ts index 049060134f7da..677b5905e466b 100644 --- a/packages/node/src/utils/versions.ts +++ b/packages/node/src/utils/versions.ts @@ -16,3 +16,5 @@ export const fastifyVersion = '4.11.0'; export const connectVersion = '3.7.0'; export const connectTypingsVersion = '3.4.35'; + +export const axiosVersion = '^1.0.0';