Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
84e103e
chore: v12.0.0 release
kamilmysliwiec Mar 5, 2026
6373599
feat: minor updates
kamilmysliwiec Mar 7, 2026
1e35d4b
build: replace gulp with a simple script
kamilmysliwiec Mar 7, 2026
a904566
feat: ensure local vs global module format match
kamilmysliwiec Mar 8, 2026
d093b80
test: add tsconfig-paths tests
kamilmysliwiec Mar 8, 2026
eb5d409
chore: upgrade deps
kamilmysliwiec Mar 9, 2026
8c49548
ci: run e2e tests
kamilmysliwiec Mar 9, 2026
5454397
ci: fix tests
kamilmysliwiec Mar 9, 2026
58c64b6
Initial plan
Copilot Mar 11, 2026
799e8f8
Initial plan
Copilot Mar 11, 2026
a3aa6ee
Initial plan
Copilot Mar 11, 2026
06ac422
Initial plan
Copilot Mar 11, 2026
4c603ed
Initial plan
Copilot Mar 11, 2026
a7e6ff4
Initial plan
Copilot Mar 11, 2026
687406b
Initial plan
Copilot Mar 11, 2026
676a7ff
Initial plan
Copilot Mar 11, 2026
b0f6325
fix: replace require('fs') with ESM import in e2e build tests
Copilot Mar 11, 2026
d3044aa
fix: handle optional dependencies fields in package.json parsing
Copilot Mar 11, 2026
2d80ee7
fix: replace require('fs') with ESM import in build.command.e2e-spec.ts
Copilot Mar 11, 2026
671d402
fix: add cli override support for rspack config path
Copilot Mar 11, 2026
7745a9d
fix(test): fix mocks for sync file system methods
Copilot Mar 11, 2026
9549045
fix: remove unused execSync import from postinstall.cjs
Copilot Mar 11, 2026
116267c
fix: align comment in postinstall.cjs with actual prepare lifecycle hook
Copilot Mar 11, 2026
49b63e2
Merge pull request #3282 from nestjs/copilot/sub-pr-3280
kamilmysliwiec Mar 11, 2026
b0ae68c
Merge pull request #3283 from nestjs/copilot/sub-pr-3280-again
kamilmysliwiec Mar 11, 2026
a22584b
Merge pull request #3284 from nestjs/copilot/sub-pr-3280-another-one
kamilmysliwiec Mar 11, 2026
e9b35f8
Merge pull request #3285 from nestjs/copilot/sub-pr-3280-yet-again
kamilmysliwiec Mar 11, 2026
7541476
fix: remove unused stat import from tools/clean.js
Copilot Mar 11, 2026
8d89b2c
Merge pull request #3286 from nestjs/copilot/sub-pr-3280-one-more-time
kamilmysliwiec Mar 11, 2026
a35cae8
Merge pull request #3287 from nestjs/copilot/sub-pr-3280-please-work
kamilmysliwiec Mar 11, 2026
39a6986
Merge pull request #3288 from nestjs/copilot/sub-pr-3280-51abd158-61b…
kamilmysliwiec Mar 11, 2026
55fa12e
Merge pull request #3289 from nestjs/copilot/sub-pr-3280-f7e0d8c5-483…
kamilmysliwiec Mar 11, 2026
880d8b8
fix(swc): support silent mode for running log
vinubabu323 Mar 28, 2026
e7ec1be
chore: upgrade typescript
kamilmysliwiec Apr 1, 2026
9be5b77
chore: migrate to oxlint from eslint
kamilmysliwiec Apr 1, 2026
6370dc4
chore: remove optional from npmrc
kamilmysliwiec Apr 1, 2026
4d8b996
test: update e2e tests
kamilmysliwiec Apr 1, 2026
0ac11ed
Merge pull request #3295 from vinubabu323/fix/3164-swc-silent-log
kamilmysliwiec Apr 7, 2026
deb1a4e
chore: merge latest
kamilmysliwiec Apr 7, 2026
112dfce
chore: resolve conflicts
kamilmysliwiec Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ aliases:
- &run-unit-tests
run:
name: Test
command: npm run test -- --runInBand --no-cache
command: npm run test

jobs:
build:
Expand Down Expand Up @@ -51,6 +51,19 @@ jobs:
command: npm run clean
- *run-unit-tests

e2e_tests:
working_directory: ~/nest
docker:
- image: cimg/node:24.13.0
steps:
- checkout
- *restore-cache
- *install-deps
- *build-packages
- run:
name: E2E tests
command: npm run test:e2e

workflows:
version: 2
build-and-test:
Expand All @@ -59,3 +72,6 @@ workflows:
- unit_tests:
requires:
- build
- e2e_tests:
requires:
- build
4 changes: 0 additions & 4 deletions .eslintignore

This file was deleted.

25 changes: 0 additions & 25 deletions .eslintrc.js

This file was deleted.

9 changes: 9 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ignorePatterns": ["**/*.js", "**/*.d.ts", "node_modules/", "dist/", "test/"],
"rules": {
"no-unused-vars": [
"warn",
{ "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
]
}
}
8 changes: 1 addition & 7 deletions actions/abstract.action.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import { Input } from '../commands';

export abstract class AbstractAction {
public abstract handle(
inputs?: Input[],
options?: Input[],
extraFlags?: string[],
): Promise<void>;
public abstract handle(context?: any): Promise<void>;
}
82 changes: 28 additions & 54 deletions actions/add.action.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,60 @@
import { red } from 'ansis';
import { Input } from '../commands';
import { getValueOrDefault } from '../lib/compiler/helpers/get-value-or-default';
import { AddCommandContext } from '../commands/index.js';
import { getValueOrDefault } from '../lib/compiler/helpers/get-value-or-default.js';
import {
AbstractPackageManager,
PackageManagerFactory,
} from '../lib/package-managers';
} from '../lib/package-managers/index.js';
import {
AbstractCollection,
CollectionFactory,
SchematicOption,
} from '../lib/schematics';
import { MESSAGES } from '../lib/ui';
import { loadConfiguration } from '../lib/utils/load-configuration';
} from '../lib/schematics/index.js';
import { MESSAGES } from '../lib/ui/index.js';
import { loadConfiguration } from '../lib/utils/load-configuration.js';
import {
askForProjectName,
hasValidOptionFlag,
moveDefaultProjectToStart,
shouldAskForProject,
} from '../lib/utils/project-utils';
import { AbstractAction } from './abstract.action';
} from '../lib/utils/project-utils.js';
import { AbstractAction } from './abstract.action.js';

const schematicName = 'nest-add';

export class AddAction extends AbstractAction {
public async handle(inputs: Input[], options: Input[], extraFlags: string[]) {
const libraryName = this.getLibraryName(inputs);
public async handle(context: AddCommandContext) {
const libraryName = context.library;
const packageName = this.getPackageName(libraryName);
const collectionName = this.getCollectionName(libraryName, packageName);
const tagName = this.getTagName(packageName);
const skipInstall = hasValidOptionFlag('skip-install', options);
const packageInstallSuccess =
skipInstall || (await this.installPackage(collectionName, tagName));
context.skipInstall ||
(await this.installPackage(collectionName, tagName));
if (packageInstallSuccess) {
const sourceRootOption: Input = await this.getSourceRoot(
inputs.concat(options),
);
options.push(sourceRootOption);

await this.addLibrary(collectionName, options, extraFlags);
const sourceRoot = await this.getSourceRoot(context.project);
await this.addLibrary(collectionName, sourceRoot, context.extraFlags);
} else {
console.error(
red(
MESSAGES.LIBRARY_INSTALLATION_FAILED_BAD_PACKAGE(libraryName),
),
red(MESSAGES.LIBRARY_INSTALLATION_FAILED_BAD_PACKAGE(libraryName)),
);
throw new Error(
MESSAGES.LIBRARY_INSTALLATION_FAILED_BAD_PACKAGE(libraryName),
);
}
}

private async getSourceRoot(inputs: Input[]): Promise<Input> {
private async getSourceRoot(project?: string): Promise<string> {
const configuration = await loadConfiguration();
const configurationProjects = configuration.projects;

const appName = inputs.find((option) => option.name === 'project')!
.value as string;

let sourceRoot = appName
? getValueOrDefault(configuration, 'sourceRoot', appName)
let sourceRoot = project
? getValueOrDefault(configuration, 'sourceRoot', project)
: configuration.sourceRoot;

const shouldAsk = shouldAskForProject(
schematicName,
configurationProjects,
appName,
project ?? '',
);
if (shouldAsk) {
const defaultLabel = ' [ Default ]';
Expand All @@ -90,12 +80,12 @@ export class AddAction extends AbstractAction {
MESSAGES.LIBRARY_PROJECT_SELECTION_QUESTION,
projects,
)) as string;
const project = selectedProject.replace(defaultLabel, '');
if (project !== configuration.sourceRoot) {
sourceRoot = configurationProjects[project].sourceRoot;
const projectName = selectedProject.replace(defaultLabel, '');
if (projectName !== configuration.sourceRoot) {
sourceRoot = configurationProjects[projectName].sourceRoot;
}
}
return { name: 'sourceRoot', value: sourceRoot };
return sourceRoot;
}

private async installPackage(
Expand All @@ -108,7 +98,7 @@ export class AddAction extends AbstractAction {
try {
installResult = await manager.addProduction([collectionName], tagName);
} catch (error) {
if (error && error.message) {
if (error instanceof Error) {
console.error(red(error.message));
}
}
Expand All @@ -117,17 +107,12 @@ export class AddAction extends AbstractAction {

private async addLibrary(
collectionName: string,
options: Input[],
sourceRoot: string,
extraFlags: string[],
) {
console.info(MESSAGES.LIBRARY_INSTALLATION_STARTS);
const schematicOptions: SchematicOption[] = [];
schematicOptions.push(
new SchematicOption(
'sourceRoot',
options.find((option) => option.name === 'sourceRoot')!.value as string,
),
);
schematicOptions.push(new SchematicOption('sourceRoot', sourceRoot));
const extraFlagsString = extraFlags ? extraFlags.join(' ') : undefined;

try {
Expand All @@ -139,24 +124,13 @@ export class AddAction extends AbstractAction {
extraFlagsString,
);
} catch (error) {
if (error && error.message) {
if (error instanceof Error) {
console.error(red(error.message));
return Promise.reject();
}
throw error;
}
}

private getLibraryName(inputs: Input[]): string {
const libraryInput: Input = inputs.find(
(input) => input.name === 'library',
) as Input;

if (!libraryInput) {
throw new Error('No library found in command input');
}
return libraryInput.value as string;
}

private getPackageName(library: string): string {
return library.startsWith('@')
? library.split('/', 2).join('/')
Expand Down
Loading