feat(core): Upgrade oclif (no-changelog) (#8381)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-01-22 18:25:36 +01:00 committed by GitHub
parent 2c146cca62
commit 913c8c6b0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 234 additions and 677 deletions

View file

@ -153,7 +153,7 @@ jobs:
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Cypress run - name: Cypress run
uses: cypress-io/github-action@v5.8.3 uses: cypress-io/github-action@v6.6.1
with: with:
install: false install: false
start: pnpm start start: pnpm start
@ -172,6 +172,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
E2E_TESTS: true E2E_TESTS: true
COMMIT_INFO_MESSAGE: 🌳 ${{ inputs.branch }} 🖥️ ${{ inputs.run-env }} 🤖 ${{ inputs.user }} 🗃️ ${{ inputs.spec }} COMMIT_INFO_MESSAGE: 🌳 ${{ inputs.branch }} 🖥️ ${{ inputs.run-env }} 🤖 ${{ inputs.user }} 🗃️ ${{ inputs.spec }}
SHELL: /bin/sh
# Check if all tests passed and set the output variable # Check if all tests passed and set the output variable
check_testing_matrix: check_testing_matrix:

1
.gitignore vendored
View file

@ -22,4 +22,3 @@ cypress/screenshots/*
cypress/downloads/* cypress/downloads/*
*.swp *.swp
CHANGELOG-*.md CHANGELOG-*.md
packages/cli/oclif.manifest.json

View file

@ -44,7 +44,7 @@ if (process.env.NODEJS_PREFER_IPV4 === 'true') {
require('dns').setDefaultResultOrder('ipv4first'); require('dns').setDefaultResultOrder('ipv4first');
} }
require('@oclif/command') (async () => {
.run() const oclif = await import('@oclif/core');
.then(require('@oclif/command/flush')) await oclif.execute({});
.catch(require('@oclif/errors/handle')); })();

View file

@ -29,8 +29,6 @@
"format": "prettier --write . --ignore-path ../../.prettierignore", "format": "prettier --write . --ignore-path ../../.prettierignore",
"lint": "eslint . --quiet", "lint": "eslint . --quiet",
"lintfix": "eslint . --fix", "lintfix": "eslint . --fix",
"postpack": "rm -f oclif.manifest.json",
"prepack": "OCLIF_TS_NODE=0 oclif-dev manifest",
"start": "run-script-os", "start": "run-script-os",
"start:default": "cd bin && ./n8n", "start:default": "cd bin && ./n8n",
"start:windows": "cd bin && n8n", "start:windows": "cd bin && n8n",
@ -59,12 +57,10 @@
"bin", "bin",
"templates", "templates",
"dist", "dist",
"oclif.manifest.json",
"!dist/**/e2e.*" "!dist/**/e2e.*"
], ],
"devDependencies": { "devDependencies": {
"@redocly/cli": "^1.6.0", "@redocly/cli": "^1.6.0",
"@oclif/dev-cli": "^1.22.2",
"@types/basic-auth": "^1.1.3", "@types/basic-auth": "^1.1.3",
"@types/bcryptjs": "^2.4.2", "@types/bcryptjs": "^2.4.2",
"@types/compression": "1.0.1", "@types/compression": "1.0.1",
@ -101,10 +97,7 @@
"@n8n/n8n-nodes-langchain": "workspace:*", "@n8n/n8n-nodes-langchain": "workspace:*",
"@n8n/permissions": "workspace:*", "@n8n/permissions": "workspace:*",
"@n8n_io/license-sdk": "2.7.2", "@n8n_io/license-sdk": "2.7.2",
"@oclif/command": "1.8.18", "@oclif/core": "3.18.1",
"@oclif/config": "1.18.17",
"@oclif/core": "1.16.6",
"@oclif/errors": "1.3.6",
"@rudderstack/rudder-sdk-node": "1.0.6", "@rudderstack/rudder-sdk-node": "1.0.6",
"@sentry/integrations": "7.87.0", "@sentry/integrations": "7.87.0",
"@sentry/node": "7.87.0", "@sentry/node": "7.87.0",

View file

@ -1,7 +1,7 @@
import 'reflect-metadata'; import 'reflect-metadata';
import { Command } from '@oclif/command';
import { ExitError } from '@oclif/errors';
import { Container } from 'typedi'; import { Container } from 'typedi';
import { Command } from '@oclif/core';
import { ExitError } from '@oclif/core/lib/errors';
import { ApplicationError, ErrorReporterProxy as ErrorReporter, sleep } from 'n8n-workflow'; import { ApplicationError, ErrorReporterProxy as ErrorReporter, sleep } from 'n8n-workflow';
import { BinaryDataService, InstanceSettings, ObjectStoreService } from 'n8n-core'; import { BinaryDataService, InstanceSettings, ObjectStoreService } from 'n8n-core';
import type { AbstractServer } from '@/AbstractServer'; import type { AbstractServer } from '@/AbstractServer';

View file

@ -1,12 +1,13 @@
import { flags } from '@oclif/command'; import { Container } from 'typedi';
import { Flags } from '@oclif/core';
import { ApplicationError } from 'n8n-workflow';
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service'; import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
import { RISK_CATEGORIES } from '@/security-audit/constants'; import { RISK_CATEGORIES } from '@/security-audit/constants';
import config from '@/config'; import config from '@/config';
import type { Risk } from '@/security-audit/types'; import type { Risk } from '@/security-audit/types';
import { BaseCommand } from './BaseCommand'; import { BaseCommand } from './BaseCommand';
import { Container } from 'typedi';
import { InternalHooks } from '@/InternalHooks'; import { InternalHooks } from '@/InternalHooks';
import { ApplicationError } from 'n8n-workflow';
export class SecurityAudit extends BaseCommand { export class SecurityAudit extends BaseCommand {
static description = 'Generate a security audit report for this n8n instance'; static description = 'Generate a security audit report for this n8n instance';
@ -18,20 +19,20 @@ export class SecurityAudit extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
categories: flags.string({ categories: Flags.string({
default: RISK_CATEGORIES.join(','), default: RISK_CATEGORIES.join(','),
description: 'Comma-separated list of categories to include in the audit', description: 'Comma-separated list of categories to include in the audit',
}), }),
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
'days-abandoned-workflow': flags.integer({ 'days-abandoned-workflow': Flags.integer({
default: config.getEnv('security.audit.daysAbandonedWorkflow'), default: config.getEnv('security.audit.daysAbandonedWorkflow'),
description: 'Days for a workflow to be considered abandoned if not executed', description: 'Days for a workflow to be considered abandoned if not executed',
}), }),
}; };
async run() { async run() {
const { flags: auditFlags } = this.parse(SecurityAudit); const { flags: auditFlags } = await this.parse(SecurityAudit);
const categories = const categories =
auditFlags.categories?.split(',').filter((c): c is Risk.Category => c !== '') ?? auditFlags.categories?.split(',').filter((c): c is Risk.Category => c !== '') ??

View file

@ -1,4 +1,4 @@
import { Command, flags } from '@oclif/command'; import { Command, Flags } from '@oclif/core';
import type { DataSourceOptions as ConnectionOptions } from 'typeorm'; import type { DataSourceOptions as ConnectionOptions } from 'typeorm';
import { DataSource as Connection } from 'typeorm'; import { DataSource as Connection } from 'typeorm';
import { Container } from 'typedi'; import { Container } from 'typedi';
@ -14,7 +14,7 @@ export class DbRevertMigrationCommand extends Command {
static examples = ['$ n8n db:revert']; static examples = ['$ n8n db:revert'];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
}; };
protected logger = Container.get(Logger); protected logger = Container.get(Logger);
@ -22,7 +22,7 @@ export class DbRevertMigrationCommand extends Command {
private connection: Connection; private connection: Connection;
async init() { async init() {
this.parse(DbRevertMigrationCommand); await this.parse(DbRevertMigrationCommand);
} }
async run() { async run() {

View file

@ -1,5 +1,6 @@
import { Container } from 'typedi';
import { Flags } from '@oclif/core';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import { flags } from '@oclif/command';
import { PLACEHOLDER_EMPTY_WORKFLOW_ID } from 'n8n-core'; import { PLACEHOLDER_EMPTY_WORKFLOW_ID } from 'n8n-core';
import type { IWorkflowBase } from 'n8n-workflow'; import type { IWorkflowBase } from 'n8n-workflow';
import { ApplicationError, ExecutionBaseError } from 'n8n-workflow'; import { ApplicationError, ExecutionBaseError } from 'n8n-workflow';
@ -9,7 +10,7 @@ import { WorkflowRunner } from '@/WorkflowRunner';
import type { IWorkflowExecutionDataProcess } from '@/Interfaces'; import type { IWorkflowExecutionDataProcess } from '@/Interfaces';
import { findCliWorkflowStart, isWorkflowIdValid } from '@/utils'; import { findCliWorkflowStart, isWorkflowIdValid } from '@/utils';
import { BaseCommand } from './BaseCommand'; import { BaseCommand } from './BaseCommand';
import { Container } from 'typedi';
import { WorkflowRepository } from '@db/repositories/workflow.repository'; import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { OwnershipService } from '@/services/ownership.service'; import { OwnershipService } from '@/services/ownership.service';
@ -19,14 +20,14 @@ export class Execute extends BaseCommand {
static examples = ['$ n8n execute --id=5', '$ n8n execute --file=workflow.json']; static examples = ['$ n8n execute --id=5', '$ n8n execute --file=workflow.json'];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
file: flags.string({ file: Flags.string({
description: 'path to a workflow file to execute', description: 'path to a workflow file to execute',
}), }),
id: flags.string({ id: Flags.string({
description: 'id of the workflow to execute', description: 'id of the workflow to execute',
}), }),
rawOutput: flags.boolean({ rawOutput: Flags.boolean({
description: 'Outputs only JSON data, with no other text', description: 'Outputs only JSON data, with no other text',
}), }),
}; };
@ -38,8 +39,7 @@ export class Execute extends BaseCommand {
} }
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(Execute);
const { flags } = this.parse(Execute);
if (!flags.id && !flags.file) { if (!flags.id && !flags.file) {
this.logger.info('Either option "--id" or "--file" have to be set!'); this.logger.info('Either option "--id" or "--file" have to be set!');

View file

@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-loop-func */ /* eslint-disable @typescript-eslint/no-loop-func */
import { Container } from 'typedi';
import { Flags } from '@oclif/core';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
import { flags } from '@oclif/command';
import type { IRun, ITaskData } from 'n8n-workflow'; import type { IRun, ITaskData } from 'n8n-workflow';
import { ApplicationError, jsonParse, sleep } from 'n8n-workflow'; import { ApplicationError, jsonParse, sleep } from 'n8n-workflow';
import { sep } from 'path'; import { sep } from 'path';
@ -12,9 +13,11 @@ import { ActiveExecutions } from '@/ActiveExecutions';
import { WorkflowRunner } from '@/WorkflowRunner'; import { WorkflowRunner } from '@/WorkflowRunner';
import type { IWorkflowDb, IWorkflowExecutionDataProcess } from '@/Interfaces'; import type { IWorkflowDb, IWorkflowExecutionDataProcess } from '@/Interfaces';
import type { User } from '@db/entities/User'; import type { User } from '@db/entities/User';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { OwnershipService } from '@/services/ownership.service';
import { findCliWorkflowStart } from '@/utils'; import { findCliWorkflowStart } from '@/utils';
import { BaseCommand } from './BaseCommand'; import { BaseCommand } from './BaseCommand';
import { Container } from 'typedi';
import type { import type {
IExecutionResult, IExecutionResult,
INodeSpecialCase, INodeSpecialCase,
@ -22,8 +25,6 @@ import type {
IResult, IResult,
IWorkflowExecutionProgress, IWorkflowExecutionProgress,
} from '../types/commands.types'; } from '../types/commands.types';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { OwnershipService } from '@/services/ownership.service';
const re = /\d+/; const re = /\d+/;
@ -60,49 +61,49 @@ export class ExecuteBatch extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
debug: flags.boolean({ debug: Flags.boolean({
description: 'Toggles on displaying all errors and debug messages.', description: 'Toggles on displaying all errors and debug messages.',
}), }),
ids: flags.string({ ids: Flags.string({
description: description:
'Specifies workflow IDs to get executed, separated by a comma or a file containing the ids', 'Specifies workflow IDs to get executed, separated by a comma or a file containing the ids',
}), }),
concurrency: flags.integer({ concurrency: Flags.integer({
default: 1, default: 1,
description: description:
'How many workflows can run in parallel. Defaults to 1 which means no concurrency.', 'How many workflows can run in parallel. Defaults to 1 which means no concurrency.',
}), }),
output: flags.string({ output: Flags.string({
description: description:
'Enable execution saving, You must inform an existing folder to save execution via this param', 'Enable execution saving, You must inform an existing folder to save execution via this param',
}), }),
snapshot: flags.string({ snapshot: Flags.string({
description: description:
'Enables snapshot saving. You must inform an existing folder to save snapshots via this param.', 'Enables snapshot saving. You must inform an existing folder to save snapshots via this param.',
}), }),
compare: flags.string({ compare: Flags.string({
description: description:
'Compares current execution with an existing snapshot. You must inform an existing folder where the snapshots are saved.', 'Compares current execution with an existing snapshot. You must inform an existing folder where the snapshots are saved.',
}), }),
shallow: flags.boolean({ shallow: Flags.boolean({
description: description:
'Compares only if attributes output from node are the same, with no regards to nested JSON objects.', 'Compares only if attributes output from node are the same, with no regards to nested JSON objects.',
}), }),
githubWorkflow: flags.boolean({ githubWorkflow: Flags.boolean({
description: description:
'Enables more lenient comparison for GitHub workflows. This is useful for reducing false positives when comparing Test workflows.', 'Enables more lenient comparison for GitHub workflows. This is useful for reducing false positives when comparing Test workflows.',
}), }),
skipList: flags.string({ skipList: Flags.string({
description: 'File containing a comma separated list of workflow IDs to skip.', description: 'File containing a comma separated list of workflow IDs to skip.',
}), }),
retries: flags.integer({ retries: Flags.integer({
description: 'Retries failed workflows up to N tries. Default is 1. Set 0 to disable.', description: 'Retries failed workflows up to N tries. Default is 1. Set 0 to disable.',
default: 1, default: 1,
}), }),
shortOutput: flags.boolean({ shortOutput: Flags.boolean({
description: 'Omits the full execution information from output, displaying only summary.', description: 'Omits the full execution information from output, displaying only summary.',
}), }),
}; };
@ -185,8 +186,7 @@ export class ExecuteBatch extends BaseCommand {
} }
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ExecuteBatch);
const { flags } = this.parse(ExecuteBatch);
ExecuteBatch.debug = flags.debug; ExecuteBatch.debug = flags.debug;
ExecuteBatch.concurrency = flags.concurrency || 1; ExecuteBatch.concurrency = flags.concurrency || 1;

View file

@ -1,4 +1,4 @@
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { Credentials } from 'n8n-core'; import { Credentials } from 'n8n-core';
@ -20,37 +20,36 @@ export class ExportCredentialsCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
all: flags.boolean({ all: Flags.boolean({
description: 'Export all credentials', description: 'Export all credentials',
}), }),
backup: flags.boolean({ backup: Flags.boolean({
description: description:
'Sets --all --pretty --separate for simple backups. Only --output has to be set additionally.', 'Sets --all --pretty --separate for simple backups. Only --output has to be set additionally.',
}), }),
id: flags.string({ id: Flags.string({
description: 'The ID of the credential to export', description: 'The ID of the credential to export',
}), }),
output: flags.string({ output: Flags.string({
char: 'o', char: 'o',
description: 'Output file name or directory if using separate files', description: 'Output file name or directory if using separate files',
}), }),
pretty: flags.boolean({ pretty: Flags.boolean({
description: 'Format the output in an easier to read fashion', description: 'Format the output in an easier to read fashion',
}), }),
separate: flags.boolean({ separate: Flags.boolean({
description: description:
'Exports one file per credential (useful for versioning). Must inform a directory via --output.', 'Exports one file per credential (useful for versioning). Must inform a directory via --output.',
}), }),
decrypted: flags.boolean({ decrypted: Flags.boolean({
description: description:
'Exports data decrypted / in plain text. ALL SENSITIVE INFORMATION WILL BE VISIBLE IN THE FILES. Use to migrate from a installation to another that have a different secret key (in the config file).', 'Exports data decrypted / in plain text. ALL SENSITIVE INFORMATION WILL BE VISIBLE IN THE FILES. Use to migrate from a installation to another that have a different secret key (in the config file).',
}), }),
}; };
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ExportCredentialsCommand);
const { flags } = this.parse(ExportCredentialsCommand);
if (flags.backup) { if (flags.backup) {
flags.all = true; flags.all = true;

View file

@ -1,4 +1,4 @@
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { BaseCommand } from '../BaseCommand'; import { BaseCommand } from '../BaseCommand';
@ -17,33 +17,32 @@ export class ExportWorkflowsCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
all: flags.boolean({ all: Flags.boolean({
description: 'Export all workflows', description: 'Export all workflows',
}), }),
backup: flags.boolean({ backup: Flags.boolean({
description: description:
'Sets --all --pretty --separate for simple backups. Only --output has to be set additionally.', 'Sets --all --pretty --separate for simple backups. Only --output has to be set additionally.',
}), }),
id: flags.string({ id: Flags.string({
description: 'The ID of the workflow to export', description: 'The ID of the workflow to export',
}), }),
output: flags.string({ output: Flags.string({
char: 'o', char: 'o',
description: 'Output file name or directory if using separate files', description: 'Output file name or directory if using separate files',
}), }),
pretty: flags.boolean({ pretty: Flags.boolean({
description: 'Format the output in an easier to read fashion', description: 'Format the output in an easier to read fashion',
}), }),
separate: flags.boolean({ separate: Flags.boolean({
description: description:
'Exports one file per workflow (useful for versioning). Must inform a directory via --output.', 'Exports one file per workflow (useful for versioning). Must inform a directory via --output.',
}), }),
}; };
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ExportWorkflowsCommand);
const { flags } = this.parse(ExportWorkflowsCommand);
if (flags.backup) { if (flags.backup) {
flags.all = true; flags.all = true;

View file

@ -1,9 +1,10 @@
import { flags } from '@oclif/command'; import { Container } from 'typedi';
import { Flags } from '@oclif/core';
import { Cipher } from 'n8n-core'; import { Cipher } from 'n8n-core';
import fs from 'fs'; import fs from 'fs';
import glob from 'fast-glob'; import glob from 'fast-glob';
import { Container } from 'typedi';
import type { EntityManager } from 'typeorm'; import type { EntityManager } from 'typeorm';
import * as Db from '@/Db'; import * as Db from '@/Db';
import type { User } from '@db/entities/User'; import type { User } from '@db/entities/User';
import { SharedCredentials } from '@db/entities/SharedCredentials'; import { SharedCredentials } from '@db/entities/SharedCredentials';
@ -28,15 +29,15 @@ export class ImportCredentialsCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
input: flags.string({ input: Flags.string({
char: 'i', char: 'i',
description: 'Input file name or directory if --separate is used', description: 'Input file name or directory if --separate is used',
}), }),
separate: flags.boolean({ separate: Flags.boolean({
description: 'Imports *.json files from directory provided by --input', description: 'Imports *.json files from directory provided by --input',
}), }),
userId: flags.string({ userId: Flags.string({
description: 'The ID of the user to assign the imported credentials to', description: 'The ID of the user to assign the imported credentials to',
}), }),
}; };
@ -51,8 +52,7 @@ export class ImportCredentialsCommand extends BaseCommand {
} }
async run(): Promise<void> { async run(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ImportCredentialsCommand);
const { flags } = this.parse(ImportCredentialsCommand);
if (!flags.input) { if (!flags.input) {
this.logger.info('An input file or directory with --input must be provided'); this.logger.info('An input file or directory with --input must be provided');

View file

@ -1,18 +1,19 @@
import { flags } from '@oclif/command'; import { Container } from 'typedi';
import { Flags } from '@oclif/core';
import { ApplicationError, jsonParse } from 'n8n-workflow'; import { ApplicationError, jsonParse } from 'n8n-workflow';
import fs from 'fs'; import fs from 'fs';
import glob from 'fast-glob'; import glob from 'fast-glob';
import { Container } from 'typedi';
import { UM_FIX_INSTRUCTION } from '@/constants';
import { WorkflowEntity } from '@db/entities/WorkflowEntity'; import { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { disableAutoGeneratedIds } from '@db/utils/commandHelpers'; import { disableAutoGeneratedIds } from '@db/utils/commandHelpers';
import type { IWorkflowToImport } from '@/Interfaces';
import { BaseCommand } from '../BaseCommand';
import { generateNanoId } from '@db/utils/generators'; import { generateNanoId } from '@db/utils/generators';
import { RoleService } from '@/services/role.service';
import { UM_FIX_INSTRUCTION } from '@/constants';
import { UserRepository } from '@db/repositories/user.repository'; import { UserRepository } from '@db/repositories/user.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import type { IWorkflowToImport } from '@/Interfaces';
import { RoleService } from '@/services/role.service';
import { ImportService } from '@/services/import.service'; import { ImportService } from '@/services/import.service';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository'; import { BaseCommand } from '../BaseCommand';
function assertHasWorkflowsToImport(workflows: unknown): asserts workflows is IWorkflowToImport[] { function assertHasWorkflowsToImport(workflows: unknown): asserts workflows is IWorkflowToImport[] {
if (!Array.isArray(workflows)) { if (!Array.isArray(workflows)) {
@ -43,15 +44,15 @@ export class ImportWorkflowsCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
input: flags.string({ input: Flags.string({
char: 'i', char: 'i',
description: 'Input file name or directory if --separate is used', description: 'Input file name or directory if --separate is used',
}), }),
separate: flags.boolean({ separate: Flags.boolean({
description: 'Imports *.json files from directory provided by --input', description: 'Imports *.json files from directory provided by --input',
}), }),
userId: flags.string({ userId: Flags.string({
description: 'The ID of the user to assign the imported workflows to', description: 'The ID of the user to assign the imported workflows to',
}), }),
}; };
@ -62,8 +63,7 @@ export class ImportWorkflowsCommand extends BaseCommand {
} }
async run(): Promise<void> { async run(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ImportWorkflowsCommand);
const { flags } = this.parse(ImportWorkflowsCommand);
if (!flags.input) { if (!flags.input) {
this.logger.info('An input file or directory with --input must be provided'); this.logger.info('An input file or directory with --input must be provided');

View file

@ -1,7 +1,7 @@
import { Container } from 'typedi';
import { SETTINGS_LICENSE_CERT_KEY } from '@/constants'; import { SETTINGS_LICENSE_CERT_KEY } from '@/constants';
import { BaseCommand } from '../BaseCommand'; import { BaseCommand } from '../BaseCommand';
import { SettingsRepository } from '@db/repositories/settings.repository'; import { SettingsRepository } from '@db/repositories/settings.repository';
import Container from 'typedi';
export class ClearLicenseCommand extends BaseCommand { export class ClearLicenseCommand extends BaseCommand {
static description = 'Clear license'; static description = 'Clear license';

View file

@ -1,5 +1,5 @@
import { License } from '@/License';
import { Container } from 'typedi'; import { Container } from 'typedi';
import { License } from '@/License';
import { BaseCommand } from '../BaseCommand'; import { BaseCommand } from '../BaseCommand';
export class LicenseInfoCommand extends BaseCommand { export class LicenseInfoCommand extends BaseCommand {

View file

@ -1,7 +1,7 @@
import { flags } from '@oclif/command';
import { BaseCommand } from '../BaseCommand';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi'; import Container from 'typedi';
import { Flags } from '@oclif/core';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { BaseCommand } from '../BaseCommand';
export class ListWorkflowCommand extends BaseCommand { export class ListWorkflowCommand extends BaseCommand {
static description = '\nList workflows'; static description = '\nList workflows';
@ -13,18 +13,17 @@ export class ListWorkflowCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
active: flags.string({ active: Flags.string({
description: 'Filters workflows by active status. Can be true or false', description: 'Filters workflows by active status. Can be true or false',
}), }),
onlyId: flags.boolean({ onlyId: Flags.boolean({
description: 'Outputs workflow IDs only, one per line.', description: 'Outputs workflow IDs only, one per line.',
}), }),
}; };
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(ListWorkflowCommand);
const { flags } = this.parse(ListWorkflowCommand);
if (flags.active !== undefined && !['true', 'false'].includes(flags.active)) { if (flags.active !== undefined && !['true', 'false'].includes(flags.active)) {
this.error('The --active flag has to be passed using true or false'); this.error('The --active flag has to be passed using true or false');

View file

@ -1,7 +1,7 @@
import { flags } from '@oclif/command';
import { BaseCommand } from '../BaseCommand';
import Container from 'typedi'; import Container from 'typedi';
import { Flags } from '@oclif/core';
import { UserRepository } from '@db/repositories/user.repository'; import { UserRepository } from '@db/repositories/user.repository';
import { BaseCommand } from '../BaseCommand';
export class DisableMFACommand extends BaseCommand { export class DisableMFACommand extends BaseCommand {
static description = 'Disable MFA authentication for a user'; static description = 'Disable MFA authentication for a user';
@ -9,8 +9,8 @@ export class DisableMFACommand extends BaseCommand {
static examples = ['$ n8n mfa:disable --email=johndoe@example.com']; static examples = ['$ n8n mfa:disable --email=johndoe@example.com'];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
email: flags.string({ email: Flags.string({
description: 'The email of the user to disable the MFA authentication', description: 'The email of the user to disable the MFA authentication',
}), }),
}; };
@ -20,8 +20,7 @@ export class DisableMFACommand extends BaseCommand {
} }
async run(): Promise<void> { async run(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(DisableMFACommand);
const { flags } = this.parse(DisableMFACommand);
if (!flags.email) { if (!flags.email) {
this.logger.info('An email with --email must be provided'); this.logger.info('An email with --email must be provided');

View file

@ -1,27 +1,24 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Container } from 'typedi'; import { Container } from 'typedi';
import { Flags, type Config } from '@oclif/core';
import path from 'path'; import path from 'path';
import { mkdir } from 'fs/promises'; import { mkdir } from 'fs/promises';
import { createReadStream, createWriteStream, existsSync } from 'fs'; import { createReadStream, createWriteStream, existsSync } from 'fs';
import { flags } from '@oclif/command';
import stream from 'stream'; import stream from 'stream';
import replaceStream from 'replacestream'; import replaceStream from 'replacestream';
import { promisify } from 'util'; import { promisify } from 'util';
import glob from 'fast-glob'; import glob from 'fast-glob';
import { sleep, jsonParse } from 'n8n-workflow'; import { sleep, jsonParse } from 'n8n-workflow';
import config from '@/config';
import config from '@/config';
import { ActiveExecutions } from '@/ActiveExecutions'; import { ActiveExecutions } from '@/ActiveExecutions';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner'; import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { Server } from '@/Server'; import { Server } from '@/Server';
import { EDITOR_UI_DIST_DIR, LICENSE_FEATURES } from '@/constants'; import { EDITOR_UI_DIST_DIR, LICENSE_FEATURES } from '@/constants';
import { eventBus } from '@/eventbus'; import { eventBus } from '@/eventbus';
import { BaseCommand } from './BaseCommand';
import { InternalHooks } from '@/InternalHooks'; import { InternalHooks } from '@/InternalHooks';
import { License } from '@/License'; import { License } from '@/License';
import type { IConfig } from '@oclif/config';
import { OrchestrationService } from '@/services/orchestration.service'; import { OrchestrationService } from '@/services/orchestration.service';
import { OrchestrationHandlerMainService } from '@/services/orchestration/main/orchestration.handler.main.service'; import { OrchestrationHandlerMainService } from '@/services/orchestration/main/orchestration.handler.main.service';
import { PruningService } from '@/services/pruning.service'; import { PruningService } from '@/services/pruning.service';
@ -30,6 +27,7 @@ import { SettingsRepository } from '@db/repositories/settings.repository';
import { ExecutionRepository } from '@db/repositories/execution.repository'; import { ExecutionRepository } from '@db/repositories/execution.repository';
import { FeatureNotLicensedError } from '@/errors/feature-not-licensed.error'; import { FeatureNotLicensedError } from '@/errors/feature-not-licensed.error';
import { WaitTracker } from '@/WaitTracker'; import { WaitTracker } from '@/WaitTracker';
import { BaseCommand } from './BaseCommand';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const open = require('open'); const open = require('open');
@ -46,16 +44,16 @@ export class Start extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
open: flags.boolean({ open: Flags.boolean({
char: 'o', char: 'o',
description: 'opens the UI automatically in browser', description: 'opens the UI automatically in browser',
}), }),
tunnel: flags.boolean({ tunnel: Flags.boolean({
description: description:
'runs the webhooks via a hooks.n8n.cloud tunnel server. Use only for testing and development!', 'runs the webhooks via a hooks.n8n.cloud tunnel server. Use only for testing and development!',
}), }),
reinstallMissingPackages: flags.boolean({ reinstallMissingPackages: Flags.boolean({
description: description:
'Attempts to self heal n8n if packages with nodes are missing. Might drastically increase startup times.', 'Attempts to self heal n8n if packages with nodes are missing. Might drastically increase startup times.',
}), }),
@ -67,7 +65,7 @@ export class Start extends BaseCommand {
private pruningService: PruningService; private pruningService: PruningService;
constructor(argv: string[], cmdConfig: IConfig) { constructor(argv: string[], cmdConfig: Config) {
super(argv, cmdConfig); super(argv, cmdConfig);
this.setInstanceType('main'); this.setInstanceType('main');
this.setInstanceQueueModeId(); this.setInstanceQueueModeId();
@ -260,8 +258,7 @@ export class Start extends BaseCommand {
} }
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(Start);
const { flags } = this.parse(Start);
// Load settings from database and set them to config. // Load settings from database and set them to config.
const databaseSettings = await Container.get(SettingsRepository).findBy({ const databaseSettings = await Container.get(SettingsRepository).findBy({

View file

@ -1,7 +1,7 @@
import { flags } from '@oclif/command'; import { Container } from 'typedi';
import { BaseCommand } from '../BaseCommand'; import { Flags } from '@oclif/core';
import { WorkflowRepository } from '@db/repositories/workflow.repository'; import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi'; import { BaseCommand } from '../BaseCommand';
export class UpdateWorkflowCommand extends BaseCommand { export class UpdateWorkflowCommand extends BaseCommand {
static description = 'Update workflows'; static description = 'Update workflows';
@ -12,21 +12,20 @@ export class UpdateWorkflowCommand extends BaseCommand {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
active: flags.string({ active: Flags.string({
description: 'Active state the workflow/s should be set to', description: 'Active state the workflow/s should be set to',
}), }),
all: flags.boolean({ all: Flags.boolean({
description: 'Operate on all workflows', description: 'Operate on all workflows',
}), }),
id: flags.string({ id: Flags.string({
description: 'The ID of the workflow to operate on', description: 'The ID of the workflow to operate on',
}), }),
}; };
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(UpdateWorkflowCommand);
const { flags } = this.parse(UpdateWorkflowCommand);
if (!flags.all && !flags.id) { if (!flags.all && !flags.id) {
console.info('Either option "--all" or "--id" have to be set!'); console.info('Either option "--all" or "--id" have to be set!');

View file

@ -1,12 +1,13 @@
import { flags } from '@oclif/command'; import { Container } from 'typedi';
import { Flags, type Config } from '@oclif/core';
import { sleep } from 'n8n-workflow'; import { sleep } from 'n8n-workflow';
import config from '@/config'; import config from '@/config';
import { ActiveExecutions } from '@/ActiveExecutions'; import { ActiveExecutions } from '@/ActiveExecutions';
import { WebhookServer } from '@/WebhookServer'; import { WebhookServer } from '@/WebhookServer';
import { Queue } from '@/Queue'; import { Queue } from '@/Queue';
import { BaseCommand } from './BaseCommand'; import { BaseCommand } from './BaseCommand';
import { Container } from 'typedi';
import type { IConfig } from '@oclif/config';
import { OrchestrationWebhookService } from '@/services/orchestration/webhook/orchestration.webhook.service'; import { OrchestrationWebhookService } from '@/services/orchestration/webhook/orchestration.webhook.service';
import { OrchestrationHandlerWebhookService } from '@/services/orchestration/webhook/orchestration.handler.webhook.service'; import { OrchestrationHandlerWebhookService } from '@/services/orchestration/webhook/orchestration.handler.webhook.service';
@ -16,12 +17,12 @@ export class Webhook extends BaseCommand {
static examples = ['$ n8n webhook']; static examples = ['$ n8n webhook'];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
}; };
protected server = Container.get(WebhookServer); protected server = Container.get(WebhookServer);
constructor(argv: string[], cmdConfig: IConfig) { constructor(argv: string[], cmdConfig: Config) {
super(argv, cmdConfig); super(argv, cmdConfig);
this.setInstanceType('webhook'); this.setInstanceType('webhook');
if (this.queueModeId) { if (this.queueModeId) {

View file

@ -1,11 +1,9 @@
import { Container } from 'typedi';
import { Flags, type Config } from '@oclif/core';
import express from 'express'; import express from 'express';
import http from 'http'; import http from 'http';
import type PCancelable from 'p-cancelable'; import type PCancelable from 'p-cancelable';
import { Container } from 'typedi';
import { flags } from '@oclif/command';
import { WorkflowExecute } from 'n8n-core'; import { WorkflowExecute } from 'n8n-core';
import type { import type {
ExecutionError, ExecutionError,
ExecutionStatus, ExecutionStatus,
@ -20,13 +18,11 @@ import * as ResponseHelper from '@/ResponseHelper';
import * as WebhookHelpers from '@/WebhookHelpers'; import * as WebhookHelpers from '@/WebhookHelpers';
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData'; import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
import { PermissionChecker } from '@/UserManagement/PermissionChecker'; import { PermissionChecker } from '@/UserManagement/PermissionChecker';
import config from '@/config'; import config from '@/config';
import type { Job, JobId, JobResponse, WebhookResponse } from '@/Queue'; import type { Job, JobId, JobResponse, WebhookResponse } from '@/Queue';
import { Queue } from '@/Queue'; import { Queue } from '@/Queue';
import { generateFailedExecutionFromError } from '@/WorkflowHelpers'; import { generateFailedExecutionFromError } from '@/WorkflowHelpers';
import { N8N_VERSION } from '@/constants'; import { N8N_VERSION } from '@/constants';
import { BaseCommand } from './BaseCommand';
import { ExecutionRepository } from '@db/repositories/execution.repository'; import { ExecutionRepository } from '@db/repositories/execution.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository'; import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { OwnershipService } from '@/services/ownership.service'; import { OwnershipService } from '@/services/ownership.service';
@ -36,11 +32,11 @@ import { rawBodyReader, bodyParser } from '@/middlewares';
import { eventBus } from '@/eventbus'; import { eventBus } from '@/eventbus';
import type { RedisServicePubSubSubscriber } from '@/services/redis/RedisServicePubSubSubscriber'; import type { RedisServicePubSubSubscriber } from '@/services/redis/RedisServicePubSubSubscriber';
import { EventMessageGeneric } from '@/eventbus/EventMessageClasses/EventMessageGeneric'; import { EventMessageGeneric } from '@/eventbus/EventMessageClasses/EventMessageGeneric';
import type { IConfig } from '@oclif/config';
import { OrchestrationHandlerWorkerService } from '@/services/orchestration/worker/orchestration.handler.worker.service'; import { OrchestrationHandlerWorkerService } from '@/services/orchestration/worker/orchestration.handler.worker.service';
import { OrchestrationWorkerService } from '@/services/orchestration/worker/orchestration.worker.service'; import { OrchestrationWorkerService } from '@/services/orchestration/worker/orchestration.worker.service';
import type { WorkerJobStatusSummary } from '../services/orchestration/worker/types'; import type { WorkerJobStatusSummary } from '@/services/orchestration/worker/types';
import { ServiceUnavailableError } from '@/errors/response-errors/service-unavailable.error'; import { ServiceUnavailableError } from '@/errors/response-errors/service-unavailable.error';
import { BaseCommand } from './BaseCommand';
export class Worker extends BaseCommand { export class Worker extends BaseCommand {
static description = '\nStarts a n8n worker'; static description = '\nStarts a n8n worker';
@ -48,8 +44,8 @@ export class Worker extends BaseCommand {
static examples = ['$ n8n worker --concurrency=5']; static examples = ['$ n8n worker --concurrency=5'];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
concurrency: flags.integer({ concurrency: Flags.integer({
default: 10, default: 10,
description: 'How many jobs can run in parallel.', description: 'How many jobs can run in parallel.',
}), }),
@ -257,7 +253,7 @@ export class Worker extends BaseCommand {
}; };
} }
constructor(argv: string[], cmdConfig: IConfig) { constructor(argv: string[], cmdConfig: Config) {
super(argv, cmdConfig); super(argv, cmdConfig);
if (!process.env.N8N_ENCRYPTION_KEY) { if (!process.env.N8N_ENCRYPTION_KEY) {
@ -333,8 +329,7 @@ export class Worker extends BaseCommand {
} }
async initQueue() { async initQueue() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(Worker);
const { flags } = this.parse(Worker);
const redisConnectionTimeoutLimit = config.getEnv('queue.bull.redis.timeoutThreshold'); const redisConnectionTimeoutLimit = config.getEnv('queue.bull.redis.timeoutThreshold');
@ -495,8 +490,7 @@ export class Worker extends BaseCommand {
} }
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(Worker);
const { flags } = this.parse(Worker);
this.logger.info('\nn8n worker is now ready'); this.logger.info('\nn8n worker is now ready');
this.logger.info(` * Version: ${N8N_VERSION}`); this.logger.info(` * Version: ${N8N_VERSION}`);

View file

@ -1,4 +1,4 @@
import * as Config from '@oclif/config'; import { Config } from '@oclif/core';
import { InternalHooks } from '@/InternalHooks'; import { InternalHooks } from '@/InternalHooks';
import { ImportCredentialsCommand } from '@/commands/import/credentials'; import { ImportCredentialsCommand } from '@/commands/import/credentials';
@ -8,6 +8,8 @@ import { mockInstance } from '../../shared/mocking';
import * as testDb from '../shared/testDb'; import * as testDb from '../shared/testDb';
import { getAllCredentials } from '../shared/db/credentials'; import { getAllCredentials } from '../shared/db/credentials';
const oclifConfig = new Config({ root: __dirname });
beforeAll(async () => { beforeAll(async () => {
mockInstance(InternalHooks); mockInstance(InternalHooks);
mockInstance(LoadNodesAndCredentials); mockInstance(LoadNodesAndCredentials);
@ -23,12 +25,11 @@ afterAll(async () => {
}); });
test('import:credentials should import a credential', async () => { test('import:credentials should import a credential', async () => {
const config: Config.IConfig = new Config.Config({ root: __dirname });
const before = await getAllCredentials(); const before = await getAllCredentials();
expect(before.length).toBe(0); expect(before.length).toBe(0);
const importer = new ImportCredentialsCommand( const importer = new ImportCredentialsCommand(
['--input=./test/integration/commands/importCredentials/credentials.json'], ['--input=./test/integration/commands/importCredentials/credentials.json'],
config, oclifConfig,
); );
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => { const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit'); throw new Error('process.exit');

View file

@ -1,4 +1,4 @@
import * as Config from '@oclif/config'; import { Config } from '@oclif/core';
import { InternalHooks } from '@/InternalHooks'; import { InternalHooks } from '@/InternalHooks';
import { ImportWorkflowsCommand } from '@/commands/import/workflow'; import { ImportWorkflowsCommand } from '@/commands/import/workflow';
@ -8,6 +8,8 @@ import { mockInstance } from '../../shared/mocking';
import * as testDb from '../shared/testDb'; import * as testDb from '../shared/testDb';
import { getAllWorkflows } from '../shared/db/workflows'; import { getAllWorkflows } from '../shared/db/workflows';
const oclifConfig = new Config({ root: __dirname });
beforeAll(async () => { beforeAll(async () => {
mockInstance(InternalHooks); mockInstance(InternalHooks);
mockInstance(LoadNodesAndCredentials); mockInstance(LoadNodesAndCredentials);
@ -23,12 +25,11 @@ afterAll(async () => {
}); });
test('import:workflow should import active workflow and deactivate it', async () => { test('import:workflow should import active workflow and deactivate it', async () => {
const config: Config.IConfig = new Config.Config({ root: __dirname });
const before = await getAllWorkflows(); const before = await getAllWorkflows();
expect(before.length).toBe(0); expect(before.length).toBe(0);
const importer = new ImportWorkflowsCommand( const importer = new ImportWorkflowsCommand(
['--separate', '--input=./test/integration/commands/importWorkflows/separate'], ['--separate', '--input=./test/integration/commands/importWorkflows/separate'],
config, oclifConfig,
); );
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => { const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit'); throw new Error('process.exit');
@ -50,12 +51,11 @@ test('import:workflow should import active workflow and deactivate it', async ()
}); });
test('import:workflow should import active workflow from combined file and deactivate it', async () => { test('import:workflow should import active workflow from combined file and deactivate it', async () => {
const config: Config.IConfig = new Config.Config({ root: __dirname });
const before = await getAllWorkflows(); const before = await getAllWorkflows();
expect(before.length).toBe(0); expect(before.length).toBe(0);
const importer = new ImportWorkflowsCommand( const importer = new ImportWorkflowsCommand(
['--input=./test/integration/commands/importWorkflows/combined/combined.json'], ['--input=./test/integration/commands/importWorkflows/combined/combined.json'],
config, oclifConfig,
); );
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => { const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit'); throw new Error('process.exit');

View file

@ -1,5 +1,5 @@
import { Config } from '@oclif/core';
import { Worker } from '@/commands/worker'; import { Worker } from '@/commands/worker';
import * as Config from '@oclif/config';
import config from '@/config'; import config from '@/config';
import { Telemetry } from '@/telemetry'; import { Telemetry } from '@/telemetry';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee'; import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
@ -20,7 +20,7 @@ import { OrchestrationService } from '@/services/orchestration.service';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '../../shared/mocking';
const oclifConfig: Config.IConfig = new Config.Config({ root: __dirname }); const oclifConfig = new Config({ root: __dirname });
beforeAll(async () => { beforeAll(async () => {
config.set('executions.mode', 'queue'); config.set('executions.mode', 'queue');

View file

@ -1,5 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
require('@oclif/command').run() (async () => {
.then(require('@oclif/command/flush')) const oclif = await import('@oclif/core');
.catch(require('@oclif/errors/handle')); await oclif.execute({});
})();

View file

@ -1,6 +1,6 @@
import { Container } from 'typedi'; import { Container } from 'typedi';
import { Command, Flags } from '@oclif/core';
import { InstanceSettings } from 'n8n-core'; import { InstanceSettings } from 'n8n-core';
import { Command, flags } from '@oclif/command';
import type { IBuildOptions } from '../src'; import type { IBuildOptions } from '../src';
import { buildFiles } from '../src'; import { buildFiles } from '../src';
@ -15,22 +15,21 @@ export class Build extends Command {
]; ];
static flags = { static flags = {
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
destination: flags.string({ destination: Flags.string({
char: 'd', char: 'd',
description: `The path to copy the compiled files to [default: ${ description: `The path to copy the compiled files to [default: ${
Container.get(InstanceSettings).customExtensionDir Container.get(InstanceSettings).customExtensionDir
}]`, }]`,
}), }),
watch: flags.boolean({ watch: Flags.boolean({
description: description:
'Starts in watch mode and automatically builds and copies file whenever they change', 'Starts in watch mode and automatically builds and copies file whenever they change',
}), }),
}; };
async run() { async run() {
// eslint-disable-next-line @typescript-eslint/no-shadow const { flags } = await this.parse(Build);
const { flags } = this.parse(Build);
this.log('\nBuild credentials and nodes'); this.log('\nBuild credentials and nodes');
this.log('========================='); this.log('=========================');

View file

@ -2,10 +2,10 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { Command } from '@oclif/core';
import * as changeCase from 'change-case'; import * as changeCase from 'change-case';
import * as fs from 'fs'; import * as fs from 'fs';
import * as inquirer from 'inquirer'; import * as inquirer from 'inquirer';
import { Command } from '@oclif/command';
import { join } from 'path'; import { join } from 'path';
import { createTemplate } from '../src'; import { createTemplate } from '../src';

View file

@ -26,8 +26,7 @@
"format": "prettier --write . --ignore-path ../../.prettierignore", "format": "prettier --write . --ignore-path ../../.prettierignore",
"lint": "eslint . --quiet", "lint": "eslint . --quiet",
"lintfix": "eslint . --fix", "lintfix": "eslint . --fix",
"postpack": "rm -f oclif.manifest.json", "prepack": "echo \"Building project...\" && rm -rf dist && tsc -b",
"prepack": "echo \"Building project...\" && rm -rf dist && tsc -b && oclif-dev manifest",
"watch": "tsc --watch" "watch": "tsc --watch"
}, },
"bin": { "bin": {
@ -43,16 +42,13 @@
"bin", "bin",
"dist", "dist",
"templates", "templates",
"oclif.manifest.json",
"src/tsconfig-build.json" "src/tsconfig-build.json"
], ],
"devDependencies": { "devDependencies": {
"@oclif/dev-cli": "^1.22.2",
"@types/inquirer": "^6.5.0" "@types/inquirer": "^6.5.0"
}, },
"dependencies": { "dependencies": {
"@oclif/command": "^1.5.18", "@oclif/core": "3.18.1",
"@oclif/errors": "^1.2.2",
"change-case": "^4.1.1", "change-case": "^4.1.1",
"fast-glob": "^3.2.5", "fast-glob": "^3.2.5",
"inquirer": "^7.0.1", "inquirer": "^7.0.1",

File diff suppressed because it is too large Load diff