fix(node): pass projectNameAndRootFormat to js lib generator from nest lib generator (#18891)
This commit is contained in:
parent
759c5e1a4e
commit
74e5879e8d
@ -7,24 +7,25 @@ describe('app', () => {
|
|||||||
let appTree: Tree;
|
let appTree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
appTree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
appTree = createTreeWithEmptyWorkspace();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await applicationGenerator(appTree, {
|
await applicationGenerator(appTree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
|
|
||||||
const mainFile = appTree.read('apps/my-node-app/src/main.ts').toString();
|
const mainFile = appTree.read('my-node-app/src/main.ts').toString();
|
||||||
expect(mainFile).toContain(`import express from 'express';`);
|
expect(mainFile).toContain(`import express from 'express';`);
|
||||||
|
|
||||||
const tsconfig = readJson(appTree, 'apps/my-node-app/tsconfig.json');
|
const tsconfig = readJson(appTree, 'my-node-app/tsconfig.json');
|
||||||
expect(tsconfig).toMatchInlineSnapshot(`
|
expect(tsconfig).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
},
|
},
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -38,11 +39,11 @@ describe('app', () => {
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const eslintrcJson = readJson(appTree, 'apps/my-node-app/.eslintrc.json');
|
const eslintrcJson = readJson(appTree, 'my-node-app/.eslintrc.json');
|
||||||
expect(eslintrcJson).toMatchInlineSnapshot(`
|
expect(eslintrcJson).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"../../.eslintrc.json",
|
"../.eslintrc.json",
|
||||||
],
|
],
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"!**/*",
|
"!**/*",
|
||||||
@ -79,14 +80,15 @@ describe('app', () => {
|
|||||||
it('should add types to the tsconfig.app.json', async () => {
|
it('should add types to the tsconfig.app.json', async () => {
|
||||||
await applicationGenerator(appTree, {
|
await applicationGenerator(appTree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
const tsconfig = readJson(appTree, 'apps/my-node-app/tsconfig.app.json');
|
const tsconfig = readJson(appTree, 'my-node-app/tsconfig.app.json');
|
||||||
expect(tsconfig.compilerOptions.types).toContain('express');
|
expect(tsconfig.compilerOptions.types).toContain('express');
|
||||||
expect(tsconfig).toMatchInlineSnapshot(`
|
expect(tsconfig).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"outDir": "../../dist/out-tsc",
|
"outDir": "../dist/out-tsc",
|
||||||
"types": [
|
"types": [
|
||||||
"node",
|
"node",
|
||||||
"express",
|
"express",
|
||||||
@ -110,23 +112,21 @@ describe('app', () => {
|
|||||||
await applicationGenerator(appTree, {
|
await applicationGenerator(appTree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
js: true,
|
js: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
|
|
||||||
expect(appTree.exists('apps/my-node-app/src/main.js')).toBeTruthy();
|
expect(appTree.exists('my-node-app/src/main.js')).toBeTruthy();
|
||||||
expect(appTree.read('apps/my-node-app/src/main.js').toString()).toContain(
|
expect(appTree.read('my-node-app/src/main.js').toString()).toContain(
|
||||||
`import express from 'express';`
|
`import express from 'express';`
|
||||||
);
|
);
|
||||||
|
|
||||||
const tsConfig = readJson(appTree, 'apps/my-node-app/tsconfig.json');
|
const tsConfig = readJson(appTree, 'my-node-app/tsconfig.json');
|
||||||
expect(tsConfig.compilerOptions).toEqual({
|
expect(tsConfig.compilerOptions).toEqual({
|
||||||
allowJs: true,
|
allowJs: true,
|
||||||
esModuleInterop: true,
|
esModuleInterop: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tsConfigApp = readJson(
|
const tsConfigApp = readJson(appTree, 'my-node-app/tsconfig.app.json');
|
||||||
appTree,
|
|
||||||
'apps/my-node-app/tsconfig.app.json'
|
|
||||||
);
|
|
||||||
expect(tsConfigApp.include).toEqual(['src/**/*.ts', 'src/**/*.js']);
|
expect(tsConfigApp.include).toEqual(['src/**/*.ts', 'src/**/*.js']);
|
||||||
expect(tsConfigApp.exclude).toEqual([
|
expect(tsConfigApp.exclude).toEqual([
|
||||||
'jest.config.ts',
|
'jest.config.ts',
|
||||||
|
|||||||
@ -1,9 +1,4 @@
|
|||||||
import {
|
import { addDependenciesToPackageJson, readJson, Tree } from '@nx/devkit';
|
||||||
addDependenciesToPackageJson,
|
|
||||||
readJson,
|
|
||||||
NxJsonConfiguration,
|
|
||||||
Tree,
|
|
||||||
} from '@nx/devkit';
|
|
||||||
import { expressVersion } from '../../utils/versions';
|
import { expressVersion } from '../../utils/versions';
|
||||||
import initGenerator from './init';
|
import initGenerator from './init';
|
||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||||
@ -12,7 +7,7 @@ describe('init', () => {
|
|||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
|
|||||||
@ -9,12 +9,15 @@ describe('application generator', () => {
|
|||||||
const appDirectory = 'my-node-app';
|
const appDirectory = 'my-node-app';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate project configurations', async () => {
|
it('should generate project configurations', async () => {
|
||||||
await applicationGenerator(tree, { name: appName });
|
await applicationGenerator(tree, {
|
||||||
|
name: appName,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const projectConfigurations = devkit.getProjects(tree);
|
const projectConfigurations = devkit.getProjects(tree);
|
||||||
|
|
||||||
@ -23,33 +26,32 @@ describe('application generator', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await applicationGenerator(tree, { name: appName });
|
await applicationGenerator(tree, {
|
||||||
|
name: appName,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(tree.exists(`apps/${appDirectory}/src/main.ts`)).toBeTruthy();
|
expect(tree.exists(`${appDirectory}/src/main.ts`)).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
tree.exists(`apps/${appDirectory}/src/app/app.controller.spec.ts`)
|
tree.exists(`${appDirectory}/src/app/app.controller.spec.ts`)
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
tree.exists(`apps/${appDirectory}/src/app/app.controller.ts`)
|
tree.exists(`${appDirectory}/src/app/app.controller.ts`)
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
expect(tree.exists(`${appDirectory}/src/app/app.module.ts`)).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
tree.exists(`apps/${appDirectory}/src/app/app.module.ts`)
|
tree.exists(`${appDirectory}/src/app/app.service.spec.ts`)
|
||||||
).toBeTruthy();
|
|
||||||
expect(
|
|
||||||
tree.exists(`apps/${appDirectory}/src/app/app.service.spec.ts`)
|
|
||||||
).toBeTruthy();
|
|
||||||
expect(
|
|
||||||
tree.exists(`apps/${appDirectory}/src/app/app.service.ts`)
|
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
expect(tree.exists(`${appDirectory}/src/app/app.service.ts`)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should configure tsconfig correctly', async () => {
|
it('should configure tsconfig correctly', async () => {
|
||||||
await applicationGenerator(tree, { name: appName });
|
await applicationGenerator(tree, {
|
||||||
|
name: appName,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsConfig = devkit.readJson(
|
const tsConfig = devkit.readJson(tree, `${appDirectory}/tsconfig.app.json`);
|
||||||
tree,
|
|
||||||
`apps/${appDirectory}/tsconfig.app.json`
|
|
||||||
);
|
|
||||||
expect(tsConfig.compilerOptions.emitDecoratorMetadata).toBe(true);
|
expect(tsConfig.compilerOptions.emitDecoratorMetadata).toBe(true);
|
||||||
expect(tsConfig.compilerOptions.target).toBe('es2021');
|
expect(tsConfig.compilerOptions.target).toBe('es2021');
|
||||||
expect(tsConfig.exclude).toEqual([
|
expect(tsConfig.exclude).toEqual([
|
||||||
@ -60,11 +62,12 @@ describe('application generator', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add strict checks with --strict', async () => {
|
it('should add strict checks with --strict', async () => {
|
||||||
await applicationGenerator(tree, { name: appName, strict: true });
|
await applicationGenerator(tree, {
|
||||||
const tsConfig = devkit.readJson(
|
name: appName,
|
||||||
tree,
|
strict: true,
|
||||||
`apps/${appDirectory}/tsconfig.app.json`
|
projectNameAndRootFormat: 'as-provided',
|
||||||
);
|
});
|
||||||
|
const tsConfig = devkit.readJson(tree, `${appDirectory}/tsconfig.app.json`);
|
||||||
|
|
||||||
expect(tsConfig.compilerOptions.strictNullChecks).toBeTruthy();
|
expect(tsConfig.compilerOptions.strictNullChecks).toBeTruthy();
|
||||||
expect(tsConfig.compilerOptions.noImplicitAny).toBeTruthy();
|
expect(tsConfig.compilerOptions.noImplicitAny).toBeTruthy();
|
||||||
@ -79,7 +82,10 @@ describe('application generator', () => {
|
|||||||
it('should format files', async () => {
|
it('should format files', async () => {
|
||||||
jest.spyOn(devkit, 'formatFiles');
|
jest.spyOn(devkit, 'formatFiles');
|
||||||
|
|
||||||
await applicationGenerator(tree, { name: appName });
|
await applicationGenerator(tree, {
|
||||||
|
name: appName,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(devkit.formatFiles).toHaveBeenCalled();
|
expect(devkit.formatFiles).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -87,7 +93,11 @@ describe('application generator', () => {
|
|||||||
it('should not format files when --skipFormat=true', async () => {
|
it('should not format files when --skipFormat=true', async () => {
|
||||||
jest.spyOn(devkit, 'formatFiles');
|
jest.spyOn(devkit, 'formatFiles');
|
||||||
|
|
||||||
await applicationGenerator(tree, { name: appName, skipFormat: true });
|
await applicationGenerator(tree, {
|
||||||
|
name: appName,
|
||||||
|
skipFormat: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(devkit.formatFiles).not.toHaveBeenCalled();
|
expect(devkit.formatFiles).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -98,6 +108,7 @@ describe('application generator', () => {
|
|||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: appName,
|
name: appName,
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectConfigurations = devkit.getProjects(tree);
|
const projectConfigurations = devkit.getProjects(tree);
|
||||||
|
|||||||
@ -18,16 +18,16 @@ exports[`convert-tslint-to-eslint should work for NestJS applications 1`] = `
|
|||||||
|
|
||||||
exports[`convert-tslint-to-eslint should work for NestJS applications 2`] = `
|
exports[`convert-tslint-to-eslint should work for NestJS applications 2`] = `
|
||||||
{
|
{
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||||
"name": "nest-app-1",
|
"name": "nest-app-1",
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"root": "apps/nest-app-1",
|
"root": "nest-app-1",
|
||||||
"targets": {
|
"targets": {
|
||||||
"lint": {
|
"lint": {
|
||||||
"executor": "@nx/linter:eslint",
|
"executor": "@nx/linter:eslint",
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": [
|
"lintFilePatterns": [
|
||||||
"apps/nest-app-1/**/*.ts",
|
"nest-app-1/**/*.ts",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@ -246,7 +246,7 @@ exports[`convert-tslint-to-eslint should work for NestJS applications 3`] = `
|
|||||||
exports[`convert-tslint-to-eslint should work for NestJS applications 4`] = `
|
exports[`convert-tslint-to-eslint should work for NestJS applications 4`] = `
|
||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"../../.eslintrc.json",
|
"../.eslintrc.json",
|
||||||
],
|
],
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"!**/*",
|
"!**/*",
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { exampleRootTslintJson } from '@nx/linter';
|
|||||||
import { conversionGenerator } from './convert-tslint-to-eslint';
|
import { conversionGenerator } from './convert-tslint-to-eslint';
|
||||||
|
|
||||||
const appProjectName = 'nest-app-1';
|
const appProjectName = 'nest-app-1';
|
||||||
const appProjectRoot = `apps/${appProjectName}`;
|
const appProjectRoot = `${appProjectName}`;
|
||||||
const appProjectTSLintJsonPath = joinPathFragments(
|
const appProjectTSLintJsonPath = joinPathFragments(
|
||||||
appProjectRoot,
|
appProjectRoot,
|
||||||
'tslint.json'
|
'tslint.json'
|
||||||
@ -98,7 +98,7 @@ describe('convert-tslint-to-eslint', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.spyOn(devkit, 'installPackagesTask');
|
jest.spyOn(devkit, 'installPackagesTask');
|
||||||
host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
host = createTreeWithEmptyWorkspace();
|
||||||
|
|
||||||
writeJson(host, 'tslint.json', exampleRootTslintJson.raw);
|
writeJson(host, 'tslint.json', exampleRootTslintJson.raw);
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ describe('convert-tslint-to-eslint', () => {
|
|||||||
lint: {
|
lint: {
|
||||||
executor: '@angular-devkit/build-angular:tslint',
|
executor: '@angular-devkit/build-angular:tslint',
|
||||||
options: {
|
options: {
|
||||||
exclude: ['**/node_modules/**', '!apps/nest-app-1/**/*'],
|
exclude: ['**/node_modules/**', '!nest-app-1/**/*'],
|
||||||
tsConfig: ['apps/nest-app-1/tsconfig.app.json'],
|
tsConfig: ['nest-app-1/tsconfig.app.json'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -143,7 +143,7 @@ describe('convert-tslint-to-eslint', () => {
|
|||||||
/**
|
/**
|
||||||
* Existing tslint.json file for the app project
|
* Existing tslint.json file for the app project
|
||||||
*/
|
*/
|
||||||
writeJson(host, 'apps/nest-app-1/tslint.json', projectTslintJsonData.raw);
|
writeJson(host, 'nest-app-1/tslint.json', projectTslintJsonData.raw);
|
||||||
/**
|
/**
|
||||||
* Existing tslint.json file for the lib project
|
* Existing tslint.json file for the lib project
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -12,7 +12,7 @@ describe('init generator', () => {
|
|||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -4,12 +4,12 @@ exports[`lib --testEnvironment should set target jest testEnvironment to jsdom 1
|
|||||||
"/* eslint-disable */
|
"/* eslint-disable */
|
||||||
export default {
|
export default {
|
||||||
displayName: 'my-lib',
|
displayName: 'my-lib',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../jest.preset.js',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||||
coverageDirectory: '../../coverage/libs/my-lib',
|
coverageDirectory: '../coverage/my-lib',
|
||||||
};
|
};
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
@ -18,13 +18,13 @@ exports[`lib --testEnvironment should set target jest testEnvironment to node by
|
|||||||
"/* eslint-disable */
|
"/* eslint-disable */
|
||||||
export default {
|
export default {
|
||||||
displayName: 'my-lib',
|
displayName: 'my-lib',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../jest.preset.js',
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||||
coverageDirectory: '../../coverage/libs/my-lib',
|
coverageDirectory: '../coverage/my-lib',
|
||||||
};
|
};
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
@ -40,7 +40,7 @@ exports[`lib --unit-test-runner none should not generate test configuration 1`]
|
|||||||
"noPropertyAccessFromIndexSignature": true,
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
},
|
},
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -56,7 +56,7 @@ exports[`lib --unit-test-runner none should not generate test configuration 2`]
|
|||||||
"executor": "@nx/linter:eslint",
|
"executor": "@nx/linter:eslint",
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": [
|
"lintFilePatterns": [
|
||||||
"libs/my-lib/**/*.ts",
|
"my-lib/**/*.ts",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@ -76,7 +76,7 @@ exports[`lib nested should create a local tsconfig.json 1`] = `
|
|||||||
"noPropertyAccessFromIndexSignature": true,
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
},
|
},
|
||||||
"extends": "../../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -114,7 +114,7 @@ exports[`lib not nested should create a local tsconfig.json 1`] = `
|
|||||||
"noPropertyAccessFromIndexSignature": true,
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
},
|
},
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -131,7 +131,7 @@ exports[`lib not nested should create a local tsconfig.json 1`] = `
|
|||||||
exports[`lib not nested should generate files 1`] = `
|
exports[`lib not nested should generate files 1`] = `
|
||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"../../.eslintrc.json",
|
"../.eslintrc.json",
|
||||||
],
|
],
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"!**/*",
|
"!**/*",
|
||||||
|
|||||||
@ -69,5 +69,6 @@ export function toJsLibraryGeneratorOptions(
|
|||||||
unitTestRunner: options.unitTestRunner,
|
unitTestRunner: options.unitTestRunner,
|
||||||
config: options.standaloneConfig ? 'project' : 'workspace',
|
config: options.standaloneConfig ? 'project' : 'workspace',
|
||||||
setParserOptionsProject: options.setParserOptionsProject,
|
setParserOptionsProject: options.setParserOptionsProject,
|
||||||
|
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,33 +6,34 @@ import { libraryGenerator } from './library';
|
|||||||
|
|
||||||
describe('lib', () => {
|
describe('lib', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
const libFileName = 'my-lib';
|
|
||||||
const libName = 'myLib';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('not nested', () => {
|
describe('not nested', () => {
|
||||||
it('should update project configuration', async () => {
|
it('should update project configuration', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const config = readProjectConfiguration(tree, libFileName);
|
const config = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(config.root).toEqual(`libs/${libFileName}`);
|
expect(config.root).toEqual(`my-lib`);
|
||||||
expect(config.targets.build).toBeUndefined();
|
expect(config.targets.build).toBeUndefined();
|
||||||
expect(config.targets.lint).toEqual({
|
expect(config.targets.lint).toEqual({
|
||||||
executor: '@nx/linter:eslint',
|
executor: '@nx/linter:eslint',
|
||||||
outputs: ['{options.outputFile}'],
|
outputs: ['{options.outputFile}'],
|
||||||
options: {
|
options: {
|
||||||
lintFilePatterns: [`libs/${libFileName}/**/*.ts`],
|
lintFilePatterns: [`my-lib/**/*.ts`],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(config.targets.test).toEqual({
|
expect(config.targets.test).toEqual({
|
||||||
executor: '@nx/jest:jest',
|
executor: '@nx/jest:jest',
|
||||||
outputs: [`{workspaceRoot}/coverage/{projectRoot}`],
|
outputs: [`{workspaceRoot}/coverage/{projectRoot}`],
|
||||||
options: {
|
options: {
|
||||||
jestConfig: `libs/${libFileName}/jest.config.ts`,
|
jestConfig: `my-lib/jest.config.ts`,
|
||||||
passWithNoTests: true,
|
passWithNoTests: true,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
@ -45,111 +46,119 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should include a controller', async () => {
|
it('should include a controller', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, controller: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
controller: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.exists(`my-lib/src/lib/my-lib.controller.ts`)).toBeTruthy();
|
||||||
tree.exists(`libs/${libFileName}/src/lib/${libFileName}.controller.ts`)
|
|
||||||
).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include a service', async () => {
|
it('should include a service', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, service: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
service: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.exists(`my-lib/src/lib/my-lib.service.ts`)).toBeTruthy();
|
||||||
tree.exists(`libs/${libFileName}/src/lib/${libFileName}.service.ts`)
|
|
||||||
).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add the @Global decorator', async () => {
|
it('should add the @Global decorator', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, global: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
global: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.read(
|
tree.read(`my-lib/src/lib/my-lib.module.ts`, 'utf-8')
|
||||||
`libs/${libFileName}/src/lib/${libFileName}.module.ts`,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the default file from @nx/node:lib', async () => {
|
it('should remove the default file from @nx/node:lib', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, global: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
global: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.exists(`my-lib/src/lib/my-lib.spec.ts`)).toBeFalsy();
|
||||||
tree.exists(`libs/${libFileName}/src/lib/${libFileName}.spec.ts`)
|
expect(tree.exists(`my-lib/src/lib/my-lib.ts`)).toBeFalsy();
|
||||||
).toBeFalsy();
|
|
||||||
expect(
|
|
||||||
tree.exists(`libs/${libFileName}/src/lib/${libFileName}.ts`)
|
|
||||||
).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should provide the controller and service', async () => {
|
it('should provide the controller and service', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: libName,
|
name: 'myLib',
|
||||||
controller: true,
|
controller: true,
|
||||||
service: true,
|
service: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.read(
|
tree.read(`my-lib/src/lib/my-lib.module.ts`, 'utf-8')
|
||||||
`libs/${libFileName}/src/lib/${libFileName}.module.ts`,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
expect(
|
expect(
|
||||||
tree.read(
|
tree.read(`my-lib/src/lib/my-lib.controller.ts`, 'utf-8')
|
||||||
`libs/${libFileName}/src/lib/${libFileName}.controller.ts`,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
).toMatchSnapshot();
|
|
||||||
expect(
|
|
||||||
tree.read(`libs/${libFileName}/src/index.ts`, 'utf-8')
|
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
|
expect(tree.read(`my-lib/src/index.ts`, 'utf-8')).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update tags', async () => {
|
it('should update tags', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, tags: 'one,two' });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
tags: 'one,two',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const projects = Object.fromEntries(devkit.getProjects(tree));
|
const projects = Object.fromEntries(devkit.getProjects(tree));
|
||||||
expect(projects).toEqual({
|
expect(projects).toEqual({
|
||||||
[libFileName]: expect.objectContaining({
|
['my-lib']: expect.objectContaining({
|
||||||
tags: ['one', 'two'],
|
tags: ['one', 'two'],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update root tsconfig.json', async () => {
|
it('should update root tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
expect(
|
expect(tsconfigJson.compilerOptions.paths[`@proj/my-lib`]).toEqual([
|
||||||
tsconfigJson.compilerOptions.paths[`@proj/${libFileName}`]
|
`my-lib/src/index.ts`,
|
||||||
).toEqual([`libs/${libFileName}/src/index.ts`]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a local tsconfig.json', async () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(tree, `libs/${libFileName}/tsconfig.json`);
|
const tsconfigJson = readJson(tree, `my-lib/tsconfig.json`);
|
||||||
expect(tsconfigJson).toMatchSnapshot();
|
expect(tsconfigJson).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(
|
const tsconfigJson = readJson(tree, `my-lib/tsconfig.spec.json`);
|
||||||
tree,
|
|
||||||
`libs/${libFileName}/tsconfig.spec.json`
|
|
||||||
);
|
|
||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(
|
const tsconfigJson = readJson(tree, `my-lib/tsconfig.lib.json`);
|
||||||
tree,
|
|
||||||
`libs/${libFileName}/tsconfig.lib.json`
|
|
||||||
);
|
|
||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
expect(tsconfigJson.exclude).toEqual([
|
expect(tsconfigJson.exclude).toEqual([
|
||||||
'jest.config.ts',
|
'jest.config.ts',
|
||||||
@ -159,95 +168,99 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(tree.exists(`libs/${libFileName}/jest.config.ts`)).toBeTruthy();
|
expect(tree.exists(`my-lib/jest.config.ts`)).toBeTruthy();
|
||||||
expect(tree.exists(`libs/${libFileName}/src/index.ts`)).toBeTruthy();
|
expect(tree.exists(`my-lib/src/index.ts`)).toBeTruthy();
|
||||||
expect(
|
expect(tree.exists(`my-lib/src/lib/my-lib.spec.ts`)).toBeFalsy();
|
||||||
tree.exists(`libs/${libFileName}/src/lib/${libFileName}.spec.ts`)
|
expect(readJson(tree, `my-lib/.eslintrc.json`)).toMatchSnapshot();
|
||||||
).toBeFalsy();
|
|
||||||
expect(
|
|
||||||
readJson(tree, `libs/${libFileName}/.eslintrc.json`)
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('nested', () => {
|
describe('nested', () => {
|
||||||
const dirName = 'myDir';
|
|
||||||
const dirFileName = 'my-dir';
|
|
||||||
const nestedLibFileName = `${dirFileName}-${libFileName}`;
|
|
||||||
|
|
||||||
it('should update tags', async () => {
|
it('should update tags', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: libName,
|
name: 'myLib',
|
||||||
directory: dirName,
|
directory: 'my-dir/my-lib',
|
||||||
tags: 'one,two',
|
tags: 'one,two',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const projects = Object.fromEntries(devkit.getProjects(tree));
|
const projects = Object.fromEntries(devkit.getProjects(tree));
|
||||||
expect(projects).toEqual({
|
expect(projects).toEqual({
|
||||||
[nestedLibFileName]: expect.objectContaining({ tags: ['one', 'two'] }),
|
[`my-lib`]: expect.objectContaining({
|
||||||
|
tags: ['one', 'two'],
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, directory: dirName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
directory: 'my-dir/my-lib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.exists(`my-dir/my-lib/jest.config.ts`)).toBeTruthy();
|
||||||
tree.exists(`libs/${dirFileName}/${libFileName}/jest.config.ts`)
|
expect(tree.exists(`my-dir/my-lib/src/index.ts`)).toBeTruthy();
|
||||||
).toBeTruthy();
|
expect(tree.exists(`my-dir/my-lib/src/lib/my-lib.spec.ts`)).toBeFalsy();
|
||||||
expect(
|
|
||||||
tree.exists(`libs/${dirFileName}/${libFileName}/src/index.ts`)
|
|
||||||
).toBeTruthy();
|
|
||||||
expect(
|
|
||||||
tree.exists(
|
|
||||||
`libs/${dirFileName}/${libFileName}/src/lib/${libFileName}.spec.ts`
|
|
||||||
)
|
|
||||||
).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update workspace.json', async () => {
|
it('should update workspace.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, directory: dirName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
directory: 'my-dir/my-lib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, nestedLibFileName);
|
const project = readProjectConfiguration(tree, `my-lib`);
|
||||||
expect(project.root).toEqual(`libs/${dirFileName}/${libFileName}`);
|
expect(project.root).toEqual(`my-dir/my-lib`);
|
||||||
expect(project.targets.lint).toEqual({
|
expect(project.targets.lint).toEqual({
|
||||||
executor: '@nx/linter:eslint',
|
executor: '@nx/linter:eslint',
|
||||||
outputs: ['{options.outputFile}'],
|
outputs: ['{options.outputFile}'],
|
||||||
options: {
|
options: {
|
||||||
lintFilePatterns: [`libs/${dirFileName}/${libFileName}/**/*.ts`],
|
lintFilePatterns: [`my-dir/my-lib/**/*.ts`],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update tsconfig.json', async () => {
|
it('should update tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, directory: dirName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
directory: 'my-dir/my-lib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
expect(
|
expect(tsconfigJson.compilerOptions.paths[`@proj/my-lib`]).toEqual([
|
||||||
tsconfigJson.compilerOptions.paths[
|
`my-dir/my-lib/src/index.ts`,
|
||||||
`@proj/${dirFileName}/${libFileName}`
|
]);
|
||||||
]
|
expect(tsconfigJson.compilerOptions.paths[`my-lib/*`]).toBeUndefined();
|
||||||
).toEqual([`libs/${dirFileName}/${libFileName}/src/index.ts`]);
|
|
||||||
expect(
|
|
||||||
tsconfigJson.compilerOptions.paths[`${nestedLibFileName}/*`]
|
|
||||||
).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a local tsconfig.json', async () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, directory: dirName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
directory: 'my-dir/my-lib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(readJson(tree, `my-dir/my-lib/tsconfig.json`)).toMatchSnapshot();
|
||||||
readJson(tree, `libs/${dirFileName}/${libFileName}/tsconfig.json`)
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--strict', () => {
|
describe('--strict', () => {
|
||||||
it('should update the projects tsconfig with strict true', async () => {
|
it('should update the projects tsconfig with strict true', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, strict: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
strict: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsConfig = readJson(tree, `/libs/${libFileName}/tsconfig.lib.json`);
|
const tsConfig = readJson(tree, `/my-lib/tsconfig.lib.json`);
|
||||||
expect(tsConfig.compilerOptions.strictNullChecks).toBeTruthy();
|
expect(tsConfig.compilerOptions.strictNullChecks).toBeTruthy();
|
||||||
expect(tsConfig.compilerOptions.noImplicitAny).toBeTruthy();
|
expect(tsConfig.compilerOptions.noImplicitAny).toBeTruthy();
|
||||||
expect(tsConfig.compilerOptions.strictBindCallApply).toBeTruthy();
|
expect(tsConfig.compilerOptions.strictBindCallApply).toBeTruthy();
|
||||||
@ -260,17 +273,17 @@ describe('lib', () => {
|
|||||||
|
|
||||||
describe('--unit-test-runner none', () => {
|
describe('--unit-test-runner none', () => {
|
||||||
it('should not generate test configuration', async () => {
|
it('should not generate test configuration', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, unitTestRunner: 'none' });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(tree.exists(`libs/${libFileName}/tsconfig.spec.json`)).toBeFalsy();
|
expect(tree.exists(`my-lib/tsconfig.spec.json`)).toBeFalsy();
|
||||||
expect(tree.exists(`libs/${libFileName}/jest.config.ts`)).toBeFalsy();
|
expect(tree.exists(`my-lib/jest.config.ts`)).toBeFalsy();
|
||||||
expect(
|
expect(tree.exists(`my-lib/lib/my-lib.spec.ts`)).toBeFalsy();
|
||||||
tree.exists(`libs/${libFileName}/lib/${libFileName}.spec.ts`)
|
expect(readJson(tree, `my-lib/tsconfig.json`)).toMatchSnapshot();
|
||||||
).toBeFalsy();
|
const project = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(
|
|
||||||
readJson(tree, `libs/${libFileName}/tsconfig.json`)
|
|
||||||
).toMatchSnapshot();
|
|
||||||
const project = readProjectConfiguration(tree, libFileName);
|
|
||||||
expect(project.targets.test).toBeUndefined();
|
expect(project.targets.test).toBeUndefined();
|
||||||
expect(project.targets.lint).toMatchSnapshot();
|
expect(project.targets.lint).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
@ -278,37 +291,39 @@ describe('lib', () => {
|
|||||||
|
|
||||||
describe('publishable package', () => {
|
describe('publishable package', () => {
|
||||||
it('should update package.json', async () => {
|
it('should update package.json', async () => {
|
||||||
const importPath = `@proj/${libName}`;
|
const importPath = `@proj/myLib`;
|
||||||
|
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: libName,
|
name: 'myLib',
|
||||||
publishable: true,
|
publishable: true,
|
||||||
importPath,
|
importPath,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const packageJson = readJson(tree, `libs/${libFileName}/package.json`);
|
const packageJson = readJson(tree, `my-lib/package.json`);
|
||||||
expect(packageJson.name).toEqual(importPath);
|
expect(packageJson.name).toEqual(importPath);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compiler options target', () => {
|
describe('compiler options target', () => {
|
||||||
it('should set target to es6 in tsconfig.lib.json by default', async () => {
|
it('should set target to es6 in tsconfig.lib.json by default', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(
|
const tsconfigJson = readJson(tree, `my-lib/tsconfig.lib.json`);
|
||||||
tree,
|
|
||||||
`libs/${libFileName}/tsconfig.lib.json`
|
|
||||||
);
|
|
||||||
expect(tsconfigJson.compilerOptions.target).toEqual('es6');
|
expect(tsconfigJson.compilerOptions.target).toEqual('es6');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set target to es2021 in tsconfig.lib.json', async () => {
|
it('should set target to es2021 in tsconfig.lib.json', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, target: 'es2021' });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
target: 'es2021',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(
|
const tsconfigJson = readJson(tree, `my-lib/tsconfig.lib.json`);
|
||||||
tree,
|
|
||||||
`libs/${libFileName}/tsconfig.lib.json`
|
|
||||||
);
|
|
||||||
expect(tsconfigJson.compilerOptions.target).toEqual('es2021');
|
expect(tsconfigJson.compilerOptions.target).toEqual('es2021');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -317,7 +332,10 @@ describe('lib', () => {
|
|||||||
it('should format files by default', async () => {
|
it('should format files by default', async () => {
|
||||||
jest.spyOn(devkit, 'formatFiles');
|
jest.spyOn(devkit, 'formatFiles');
|
||||||
|
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(devkit.formatFiles).toHaveBeenCalled();
|
expect(devkit.formatFiles).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -325,7 +343,11 @@ describe('lib', () => {
|
|||||||
it('should not format files when --skipFormat=true', async () => {
|
it('should not format files when --skipFormat=true', async () => {
|
||||||
jest.spyOn(devkit, 'formatFiles');
|
jest.spyOn(devkit, 'formatFiles');
|
||||||
|
|
||||||
await libraryGenerator(tree, { name: libName, skipFormat: true });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
skipFormat: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(devkit.formatFiles).not.toHaveBeenCalled();
|
expect(devkit.formatFiles).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -333,56 +355,56 @@ describe('lib', () => {
|
|||||||
|
|
||||||
describe('--testEnvironment', () => {
|
describe('--testEnvironment', () => {
|
||||||
it('should set target jest testEnvironment to node by default', async () => {
|
it('should set target jest testEnvironment to node by default', async () => {
|
||||||
await libraryGenerator(tree, { name: libName });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.read(`my-lib/jest.config.ts`, 'utf-8')).toMatchSnapshot();
|
||||||
tree.read(`libs/${libFileName}/jest.config.ts`, 'utf-8')
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set target jest testEnvironment to jsdom', async () => {
|
it('should set target jest testEnvironment to jsdom', async () => {
|
||||||
await libraryGenerator(tree, { name: libName, testEnvironment: 'jsdom' });
|
await libraryGenerator(tree, {
|
||||||
|
name: 'myLib',
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(tree.read(`my-lib/jest.config.ts`, 'utf-8')).toMatchSnapshot();
|
||||||
tree.read(`libs/${libFileName}/jest.config.ts`, 'utf-8')
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--simpleName', () => {
|
describe('--simpleName', () => {
|
||||||
it('should generate a library with a simple name', async () => {
|
it('should generate a library with a simple name', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: libName,
|
name: 'myLib',
|
||||||
simpleName: true,
|
simpleName: true,
|
||||||
directory: 'api',
|
directory: 'api/my-lib',
|
||||||
service: true,
|
service: true,
|
||||||
controller: true,
|
controller: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const indexFile = tree.read('libs/api/my-lib/src/index.ts', 'utf-8');
|
const indexFile = tree.read('api/my-lib/src/index.ts', 'utf-8');
|
||||||
|
|
||||||
expect(indexFile).toContain(`export * from './lib/my-lib.module';`);
|
expect(indexFile).toContain(`export * from './lib/my-lib.module';`);
|
||||||
expect(indexFile).toContain(`export * from './lib/my-lib.service';`);
|
expect(indexFile).toContain(`export * from './lib/my-lib.service';`);
|
||||||
expect(indexFile).toContain(`export * from './lib/my-lib.controller';`);
|
expect(indexFile).toContain(`export * from './lib/my-lib.controller';`);
|
||||||
|
|
||||||
|
expect(tree.exists('api/my-lib/src/lib/my-lib.module.ts')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(tree.exists('api/my-lib/src/lib/my-lib.service.ts')).toBeTruthy();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/api/my-lib/src/lib/my-lib.module.ts')
|
tree.exists('api/my-lib/src/lib/my-lib.service.spec.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/api/my-lib/src/lib/my-lib.service.ts')
|
tree.exists('api/my-lib/src/lib/my-lib.controller.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/api/my-lib/src/lib/my-lib.service.spec.ts')
|
tree.exists('api/my-lib/src/lib/my-lib.controller.spec.ts')
|
||||||
).toBeTruthy();
|
|
||||||
|
|
||||||
expect(
|
|
||||||
tree.exists('libs/api/my-lib/src/lib/my-lib.controller.ts')
|
|
||||||
).toBeTruthy();
|
|
||||||
|
|
||||||
expect(
|
|
||||||
tree.exists('libs/api/my-lib/src/lib/my-lib.controller.spec.ts')
|
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { addProjectConfiguration, Tree } from '@nx/devkit';
|
|||||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||||
|
|
||||||
export function createTreeWithNestApplication(appName: string): Tree {
|
export function createTreeWithNestApplication(appName: string): Tree {
|
||||||
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
const tree = createTreeWithEmptyWorkspace();
|
||||||
addProjectConfiguration(tree, appName, {
|
addProjectConfiguration(tree, appName, {
|
||||||
root: `apps/${appName}`,
|
root: `${appName}`,
|
||||||
sourceRoot: `apps/${appName}/src`,
|
sourceRoot: `${appName}/src`,
|
||||||
projectType: 'application',
|
projectType: 'application',
|
||||||
targets: {},
|
targets: {},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -26,6 +26,7 @@ describe('app', () => {
|
|||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
bundler: 'webpack',
|
bundler: 'webpack',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
const project = readProjectConfiguration(tree, 'my-node-app');
|
const project = readProjectConfiguration(tree, 'my-node-app');
|
||||||
expect(project.root).toEqual('my-node-app');
|
expect(project.root).toEqual('my-node-app');
|
||||||
@ -83,6 +84,7 @@ describe('app', () => {
|
|||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
tags: 'one,two',
|
tags: 'one,two',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
const projects = Object.fromEntries(getProjects(tree));
|
const projects = Object.fromEntries(getProjects(tree));
|
||||||
expect(projects).toMatchObject({
|
expect(projects).toMatchObject({
|
||||||
@ -95,6 +97,7 @@ describe('app', () => {
|
|||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
expect(tree.exists(`my-node-app/jest.config.ts`)).toBeTruthy();
|
expect(tree.exists(`my-node-app/jest.config.ts`)).toBeTruthy();
|
||||||
expect(tree.exists('my-node-app/src/main.ts')).toBeTruthy();
|
expect(tree.exists('my-node-app/src/main.ts')).toBeTruthy();
|
||||||
@ -170,6 +173,7 @@ describe('app', () => {
|
|||||||
|
|
||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const tsconfig = readJson(tree, 'my-node-app/tsconfig.json');
|
const tsconfig = readJson(tree, 'my-node-app/tsconfig.json');
|
||||||
@ -181,9 +185,10 @@ describe('app', () => {
|
|||||||
it('should update project config', async () => {
|
it('should update project config', async () => {
|
||||||
await applicationGenerator(tree, {
|
await applicationGenerator(tree, {
|
||||||
name: 'myNodeApp',
|
name: 'myNodeApp',
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-node-app',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
const project = readProjectConfiguration(tree, 'my-dir-my-node-app');
|
const project = readProjectConfiguration(tree, 'my-node-app');
|
||||||
|
|
||||||
expect(project.root).toEqual('my-dir/my-node-app');
|
expect(project.root).toEqual('my-dir/my-node-app');
|
||||||
|
|
||||||
@ -196,7 +201,7 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(() =>
|
expect(() =>
|
||||||
readProjectConfiguration(tree, 'my-dir-my-node-app-e2e')
|
readProjectConfiguration(tree, 'my-node-app-e2e')
|
||||||
).not.toThrow();
|
).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ describe('e2eProjectGenerator', () => {
|
|||||||
name: 'api',
|
name: 'api',
|
||||||
framework: 'express',
|
framework: 'express',
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
await e2eProjectGenerator(tree, {
|
await e2eProjectGenerator(tree, {
|
||||||
projectType: 'server',
|
projectType: 'server',
|
||||||
@ -29,6 +30,7 @@ describe('e2eProjectGenerator', () => {
|
|||||||
framework: 'express',
|
framework: 'express',
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
rootProject: true,
|
rootProject: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
await e2eProjectGenerator(tree, {
|
await e2eProjectGenerator(tree, {
|
||||||
projectType: 'server',
|
projectType: 'server',
|
||||||
@ -44,6 +46,7 @@ describe('e2eProjectGenerator', () => {
|
|||||||
name: 'api',
|
name: 'api',
|
||||||
framework: 'none',
|
framework: 'none',
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
await e2eProjectGenerator(tree, {
|
await e2eProjectGenerator(tree, {
|
||||||
projectType: 'cli',
|
projectType: 'cli',
|
||||||
|
|||||||
@ -13,7 +13,7 @@ describe('init', () => {
|
|||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
|
|||||||
@ -12,33 +12,34 @@ import { libraryGenerator } from './library';
|
|||||||
const baseLibraryConfig = {
|
const baseLibraryConfig = {
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
compiler: 'tsc' as const,
|
compiler: 'tsc' as const,
|
||||||
|
projectNameAndRootFormat: 'as-provided' as const,
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('lib', () => {
|
describe('lib', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('not nested', () => {
|
describe('not nested', () => {
|
||||||
it('should update configuration', async () => {
|
it('should update configuration', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const configuration = readProjectConfiguration(tree, 'my-lib');
|
const configuration = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(configuration.root).toEqual('libs/my-lib');
|
expect(configuration.root).toEqual('my-lib');
|
||||||
expect(configuration.targets.build).toBeUndefined();
|
expect(configuration.targets.build).toBeUndefined();
|
||||||
expect(configuration.targets.lint).toEqual({
|
expect(configuration.targets.lint).toEqual({
|
||||||
executor: '@nx/linter:eslint',
|
executor: '@nx/linter:eslint',
|
||||||
outputs: ['{options.outputFile}'],
|
outputs: ['{options.outputFile}'],
|
||||||
options: {
|
options: {
|
||||||
lintFilePatterns: ['libs/my-lib/**/*.ts'],
|
lintFilePatterns: ['my-lib/**/*.ts'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(configuration.targets.test).toEqual({
|
expect(configuration.targets.test).toEqual({
|
||||||
executor: '@nx/jest:jest',
|
executor: '@nx/jest:jest',
|
||||||
outputs: ['{workspaceRoot}/coverage/{projectRoot}'],
|
outputs: ['{workspaceRoot}/coverage/{projectRoot}'],
|
||||||
options: {
|
options: {
|
||||||
jestConfig: 'libs/my-lib/jest.config.ts',
|
jestConfig: 'my-lib/jest.config.ts',
|
||||||
passWithNoTests: true,
|
passWithNoTests: true,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
@ -85,19 +86,19 @@ describe('lib', () => {
|
|||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||||
'libs/my-lib/src/index.ts',
|
'my-lib/src/index.ts',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a local tsconfig.json', async () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json');
|
const tsconfigJson = readJson(tree, 'my-lib/tsconfig.json');
|
||||||
expect(tsconfigJson).toMatchInlineSnapshot(`
|
expect(tsconfigJson).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
},
|
},
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -114,20 +115,20 @@ describe('lib', () => {
|
|||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.spec.json');
|
const tsconfigJson = readJson(tree, 'my-lib/tsconfig.spec.json');
|
||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json');
|
const tsconfigJson = readJson(tree, 'my-lib/tsconfig.lib.json');
|
||||||
expect(tsconfigJson.compilerOptions.types).toContain('node');
|
expect(tsconfigJson.compilerOptions.types).toContain('node');
|
||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should exclude test files from tsconfig.lib.json', async () => {
|
it('should exclude test files from tsconfig.lib.json', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json');
|
const tsconfigJson = readJson(tree, 'my-lib/tsconfig.lib.json');
|
||||||
expect(tsconfigJson.exclude).toEqual([
|
expect(tsconfigJson.exclude).toEqual([
|
||||||
'jest.config.ts',
|
'jest.config.ts',
|
||||||
'src/**/*.spec.ts',
|
'src/**/*.spec.ts',
|
||||||
@ -137,14 +138,14 @@ describe('lib', () => {
|
|||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await libraryGenerator(tree, baseLibraryConfig);
|
await libraryGenerator(tree, baseLibraryConfig);
|
||||||
expect(tree.exists(`libs/my-lib/jest.config.ts`)).toBeTruthy();
|
expect(tree.exists(`my-lib/jest.config.ts`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
|
expect(tree.exists('my-lib/src/index.ts')).toBeTruthy();
|
||||||
|
|
||||||
const eslintrc = readJson(tree, 'libs/my-lib/.eslintrc.json');
|
const eslintrc = readJson(tree, 'my-lib/.eslintrc.json');
|
||||||
expect(eslintrc).toMatchInlineSnapshot(`
|
expect(eslintrc).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"../../.eslintrc.json",
|
"../.eslintrc.json",
|
||||||
],
|
],
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"!**/*",
|
"!**/*",
|
||||||
@ -183,12 +184,12 @@ describe('lib', () => {
|
|||||||
it('should update tags', async () => {
|
it('should update tags', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
tags: 'one',
|
tags: 'one',
|
||||||
});
|
});
|
||||||
let projects = Object.fromEntries(getProjects(tree));
|
let projects = Object.fromEntries(getProjects(tree));
|
||||||
expect(projects).toMatchObject({
|
expect(projects).toMatchObject({
|
||||||
'my-dir-my-lib': {
|
'my-lib': {
|
||||||
tags: ['one'],
|
tags: ['one'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -196,15 +197,15 @@ describe('lib', () => {
|
|||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib-2',
|
||||||
tags: 'one,two',
|
tags: 'one,two',
|
||||||
});
|
});
|
||||||
projects = Object.fromEntries(getProjects(tree));
|
projects = Object.fromEntries(getProjects(tree));
|
||||||
expect(projects).toMatchObject({
|
expect(projects).toMatchObject({
|
||||||
'my-dir-my-lib': {
|
'my-lib': {
|
||||||
tags: ['one'],
|
tags: ['one'],
|
||||||
},
|
},
|
||||||
'my-dir-my-lib2': {
|
'my-lib2': {
|
||||||
tags: ['one', 'two'],
|
tags: ['one', 'two'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -213,25 +214,25 @@ describe('lib', () => {
|
|||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
});
|
});
|
||||||
expect(tree.exists(`libs/my-dir/my-lib/jest.config.ts`)).toBeTruthy();
|
expect(tree.exists(`my-dir/my-lib/jest.config.ts`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
expect(tree.exists('my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update workspace.json', async () => {
|
it('should update workspace.json', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
});
|
});
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'my-dir-my-lib');
|
const project = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(project.root).toEqual('libs/my-dir/my-lib');
|
expect(project.root).toEqual('my-dir/my-lib');
|
||||||
expect(project.targets.lint).toEqual({
|
expect(project.targets.lint).toEqual({
|
||||||
executor: '@nx/linter:eslint',
|
executor: '@nx/linter:eslint',
|
||||||
outputs: ['{options.outputFile}'],
|
outputs: ['{options.outputFile}'],
|
||||||
options: {
|
options: {
|
||||||
lintFilePatterns: ['libs/my-dir/my-lib/**/*.ts'],
|
lintFilePatterns: ['my-dir/my-lib/**/*.ts'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -239,15 +240,13 @@ describe('lib', () => {
|
|||||||
it('should update tsconfig.json', async () => {
|
it('should update tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
});
|
});
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
|
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||||
['libs/my-dir/my-lib/src/index.ts']
|
'my-dir/my-lib/src/index.ts',
|
||||||
);
|
]);
|
||||||
expect(
|
expect(tsconfigJson.compilerOptions.paths['my-lib/*']).toBeUndefined();
|
||||||
tsconfigJson.compilerOptions.paths['my-dir-my-lib/*']
|
|
||||||
).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an exception when not passing importPath when using --publishable', async () => {
|
it('should throw an exception when not passing importPath when using --publishable', async () => {
|
||||||
@ -256,7 +255,7 @@ describe('lib', () => {
|
|||||||
try {
|
try {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
publishable: true,
|
publishable: true,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -269,11 +268,11 @@ describe('lib', () => {
|
|||||||
it('should create a local tsconfig.json', async () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
});
|
});
|
||||||
|
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json');
|
const tsconfigJson = readJson(tree, 'my-dir/my-lib/tsconfig.json');
|
||||||
expect(tsconfigJson.extends).toEqual('../../../tsconfig.base.json');
|
expect(tsconfigJson.extends).toEqual('../../tsconfig.base.json');
|
||||||
expect(tsconfigJson.references).toEqual([
|
expect(tsconfigJson.references).toEqual([
|
||||||
{
|
{
|
||||||
path: './tsconfig.lib.json',
|
path: './tsconfig.lib.json',
|
||||||
@ -287,17 +286,15 @@ describe('lib', () => {
|
|||||||
it('should generate filenames that do not contain directory with --simpleModuleName', async () => {
|
it('should generate filenames that do not contain directory with --simpleModuleName', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
simpleModuleName: true,
|
simpleModuleName: true,
|
||||||
});
|
});
|
||||||
expect(tree.exists(`libs/my-dir/my-lib/jest.config.ts`)).toBeTruthy();
|
expect(tree.exists(`my-dir/my-lib/jest.config.ts`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
expect(tree.exists('my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/lib/my-lib.ts')).toBeTruthy();
|
expect(tree.exists('my-dir/my-lib/src/lib/my-lib.ts')).toBeTruthy();
|
||||||
expect(
|
expect(tree.exists('my-dir/my-lib/src/lib/my-lib.spec.ts')).toBeTruthy();
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-lib.spec.ts')
|
expect(tree.exists('my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||||
).toBeTruthy();
|
expect(tree.exists(`my-dir/my-lib/.eslintrc.json`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
|
||||||
expect(tree.exists(`libs/my-dir/my-lib/.eslintrc.json`)).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -333,14 +330,14 @@ describe('lib', () => {
|
|||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
unitTestRunner: 'none',
|
unitTestRunner: 'none',
|
||||||
});
|
});
|
||||||
expect(tree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy();
|
expect(tree.exists('my-lib/tsconfig.spec.json')).toBeFalsy();
|
||||||
expect(tree.exists('libs/my-lib/jest.config.ts')).toBeFalsy();
|
expect(tree.exists('my-lib/jest.config.ts')).toBeFalsy();
|
||||||
expect(tree.exists('libs/my-lib/lib/my-lib.spec.ts')).toBeFalsy();
|
expect(tree.exists('my-lib/lib/my-lib.spec.ts')).toBeFalsy();
|
||||||
expect(
|
expect(
|
||||||
readProjectConfiguration(tree, 'my-lib').targets.test
|
readProjectConfiguration(tree, 'my-lib').targets.test
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json');
|
const tsconfigJson = readJson(tree, 'my-lib/tsconfig.json');
|
||||||
expect(tsconfigJson.extends).toEqual('../../tsconfig.base.json');
|
expect(tsconfigJson.extends).toEqual('../tsconfig.base.json');
|
||||||
expect(tsconfigJson.references).toEqual([
|
expect(tsconfigJson.references).toEqual([
|
||||||
{
|
{
|
||||||
path: './tsconfig.lib.json',
|
path: './tsconfig.lib.json',
|
||||||
@ -357,19 +354,19 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(projectConfiguration.root).toEqual('libs/my-lib');
|
expect(projectConfiguration.root).toEqual('my-lib');
|
||||||
|
|
||||||
expect(projectConfiguration.targets.build).toMatchInlineSnapshot(`
|
expect(projectConfiguration.targets.build).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"executor": "@nx/js:tsc",
|
"executor": "@nx/js:tsc",
|
||||||
"options": {
|
"options": {
|
||||||
"assets": [
|
"assets": [
|
||||||
"libs/my-lib/*.md",
|
"my-lib/*.md",
|
||||||
],
|
],
|
||||||
"main": "libs/my-lib/src/index.ts",
|
"main": "my-lib/src/index.ts",
|
||||||
"outputPath": "dist/libs/my-lib",
|
"outputPath": "dist/my-lib",
|
||||||
"packageJson": "libs/my-lib/package.json",
|
"packageJson": "my-lib/package.json",
|
||||||
"tsConfig": "libs/my-lib/tsconfig.lib.json",
|
"tsConfig": "my-lib/tsconfig.lib.json",
|
||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
"{options.outputPath}",
|
"{options.outputPath}",
|
||||||
@ -388,7 +385,7 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(projectConfiguration.root).toEqual('libs/my-lib');
|
expect(projectConfiguration.root).toEqual('my-lib');
|
||||||
expect(projectConfiguration.targets.build).toBeDefined();
|
expect(projectConfiguration.targets.build).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -400,7 +397,7 @@ describe('lib', () => {
|
|||||||
importPath: '@proj/mylib',
|
importPath: '@proj/mylib',
|
||||||
});
|
});
|
||||||
|
|
||||||
let packageJsonContent = readJson(tree, 'libs/mylib/package.json');
|
let packageJsonContent = readJson(tree, 'mylib/package.json');
|
||||||
|
|
||||||
expect(packageJsonContent.name).toEqual('@proj/mylib');
|
expect(packageJsonContent.name).toEqual('@proj/mylib');
|
||||||
});
|
});
|
||||||
@ -411,10 +408,10 @@ describe('lib', () => {
|
|||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...baseLibraryConfig,
|
...baseLibraryConfig,
|
||||||
publishable: true,
|
publishable: true,
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
importPath: '@myorg/lib',
|
importPath: '@myorg/lib',
|
||||||
});
|
});
|
||||||
const packageJson = readJson(tree, 'libs/my-dir/my-lib/package.json');
|
const packageJson = readJson(tree, 'my-dir/my-lib/package.json');
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
|
|
||||||
expect(packageJson.name).toBe('@myorg/lib');
|
expect(packageJson.name).toBe('@myorg/lib');
|
||||||
@ -455,18 +452,18 @@ describe('lib', () => {
|
|||||||
babelJest: true,
|
babelJest: true,
|
||||||
} as Schema);
|
} as Schema);
|
||||||
|
|
||||||
expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8'))
|
expect(tree.read(`my-lib/jest.config.ts`, 'utf-8'))
|
||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
"/* eslint-disable */
|
"/* eslint-disable */
|
||||||
export default {
|
export default {
|
||||||
displayName: 'my-lib',
|
displayName: 'my-lib',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../jest.preset.js',
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\\\.[tj]s$': 'babel-jest',
|
'^.+\\\\.[tj]s$': 'babel-jest',
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||||
coverageDirectory: '../../coverage/libs/my-lib',
|
coverageDirectory: '../coverage/my-lib',
|
||||||
};
|
};
|
||||||
"
|
"
|
||||||
`);
|
`);
|
||||||
@ -479,22 +476,20 @@ describe('lib', () => {
|
|||||||
js: true,
|
js: true,
|
||||||
} as Schema);
|
} as Schema);
|
||||||
|
|
||||||
expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy();
|
expect(tree.exists(`my-lib/jest.config.js`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/index.js')).toBeTruthy();
|
expect(tree.exists('my-lib/src/index.js')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.js')).toBeTruthy();
|
expect(tree.exists('my-lib/src/lib/my-lib.js')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.spec.js')).toBeTruthy();
|
expect(tree.exists('my-lib/src/lib/my-lib.spec.js')).toBeTruthy();
|
||||||
|
|
||||||
expect(
|
expect(readJson(tree, 'my-lib/tsconfig.json').compilerOptions).toEqual({
|
||||||
readJson(tree, 'libs/my-lib/tsconfig.json').compilerOptions
|
|
||||||
).toEqual({
|
|
||||||
allowJs: true,
|
allowJs: true,
|
||||||
module: 'commonjs',
|
module: 'commonjs',
|
||||||
});
|
});
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.lib.json').include).toEqual([
|
expect(readJson(tree, 'my-lib/tsconfig.lib.json').include).toEqual([
|
||||||
'src/**/*.ts',
|
'src/**/*.ts',
|
||||||
'src/**/*.js',
|
'src/**/*.js',
|
||||||
]);
|
]);
|
||||||
expect(readJson(tree, 'libs/my-lib/tsconfig.lib.json').exclude).toEqual([
|
expect(readJson(tree, 'my-lib/tsconfig.lib.json').exclude).toEqual([
|
||||||
'jest.config.ts',
|
'jest.config.ts',
|
||||||
'src/**/*.spec.ts',
|
'src/**/*.spec.ts',
|
||||||
'src/**/*.test.ts',
|
'src/**/*.test.ts',
|
||||||
@ -507,7 +502,7 @@ describe('lib', () => {
|
|||||||
await libraryGenerator(tree, { name: 'myLib', js: true } as Schema);
|
await libraryGenerator(tree, { name: 'myLib', js: true } as Schema);
|
||||||
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
|
||||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||||
'libs/my-lib/src/index.js',
|
'my-lib/src/index.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -519,27 +514,24 @@ describe('lib', () => {
|
|||||||
} as Schema);
|
} as Schema);
|
||||||
|
|
||||||
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
const projectConfiguration = readProjectConfiguration(tree, 'my-lib');
|
||||||
expect(projectConfiguration.root).toEqual('libs/my-lib');
|
expect(projectConfiguration.root).toEqual('my-lib');
|
||||||
|
|
||||||
expect(projectConfiguration.targets.build.options.main).toEqual(
|
expect(projectConfiguration.targets.build.options.main).toEqual(
|
||||||
'libs/my-lib/src/index.js'
|
'my-lib/src/index.js'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate js files for nested libs as well', async () => {
|
it('should generate js files for nested libs as well', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
js: true,
|
js: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy();
|
expect(tree.exists(`my-dir/my-lib/jest.config.js`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/index.js')).toBeTruthy();
|
expect(tree.exists('my-dir/my-lib/src/index.js')).toBeTruthy();
|
||||||
expect(
|
expect(tree.exists('my-dir/my-lib/src/lib/my-lib.js')).toBeTruthy();
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.js')
|
expect(tree.exists('my-dir/my-lib/src/lib/my-lib.spec.js')).toBeTruthy();
|
||||||
).toBeTruthy();
|
|
||||||
expect(
|
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.spec.js')
|
|
||||||
).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -548,31 +540,25 @@ describe('lib', () => {
|
|||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
pascalCaseFiles: true,
|
pascalCaseFiles: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
expect(tree.exists('libs/my-lib/src/lib/MyLib.ts')).toBeTruthy();
|
expect(tree.exists('my-lib/src/lib/MyLib.ts')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/MyLib.spec.ts')).toBeTruthy();
|
expect(tree.exists('my-lib/src/lib/MyLib.spec.ts')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.spec.ts')).toBeFalsy();
|
expect(tree.exists('my-lib/src/lib/my-lib.spec.ts')).toBeFalsy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.ts')).toBeFalsy();
|
expect(tree.exists('my-lib/src/lib/my-lib.ts')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files with upper case names for nested libs as well', async () => {
|
it('should generate files with upper case names for nested libs as well', async () => {
|
||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
directory: 'myDir',
|
directory: 'my-dir/my-lib',
|
||||||
pascalCaseFiles: true,
|
pascalCaseFiles: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
} as Schema);
|
} as Schema);
|
||||||
expect(
|
expect(tree.exists('my-dir/my-lib/src/lib/MyLib.ts')).toBeTruthy();
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/MyDirMyLib.ts')
|
expect(tree.exists('my-dir/my-lib/src/lib/MyLib.spec.ts')).toBeTruthy();
|
||||||
).toBeTruthy();
|
expect(tree.exists('my-dir/my-lib/src/lib/my-lib.ts')).toBeFalsy();
|
||||||
expect(
|
expect(tree.exists('my-lib/src/lib/my-lib.spec.ts')).toBeFalsy();
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/MyDirMyLib.spec.ts')
|
|
||||||
).toBeTruthy();
|
|
||||||
expect(
|
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.ts')
|
|
||||||
).toBeFalsy();
|
|
||||||
expect(
|
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.spec.ts')
|
|
||||||
).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,6 +14,7 @@ describe('setupDockerGenerator', () => {
|
|||||||
framework: 'express',
|
framework: 'express',
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
docker: true,
|
docker: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'api');
|
const project = readProjectConfiguration(tree, 'api');
|
||||||
@ -37,6 +38,7 @@ describe('setupDockerGenerator', () => {
|
|||||||
framework: 'fastify',
|
framework: 'fastify',
|
||||||
rootProject: true,
|
rootProject: true,
|
||||||
docker: true,
|
docker: true,
|
||||||
|
projectNameAndRootFormat: 'as-provided',
|
||||||
});
|
});
|
||||||
|
|
||||||
const project = readProjectConfiguration(tree, 'api');
|
const project = readProjectConfiguration(tree, 'api');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user