mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
ci: Fix prettier auto-formatting (no-changelog) (#7063)
This commit is contained in:
parent
fa3d7070b0
commit
a693b29134
104
.github/scripts/check-tests.mjs
vendored
104
.github/scripts/check-tests.mjs
vendored
|
@ -2,90 +2,100 @@ import fs from 'fs';
|
|||
import path from 'path';
|
||||
import util from 'util';
|
||||
import { exec } from 'child_process';
|
||||
import { glob } from "glob";
|
||||
import { glob } from 'glob';
|
||||
import ts from 'typescript';
|
||||
|
||||
const readFileAsync = util.promisify(fs.readFile);
|
||||
const execAsync = util.promisify(exec);
|
||||
|
||||
const filterAsync = async (asyncPredicate, arr) => {
|
||||
const filterResults = await Promise.all(arr.map(async item => ({
|
||||
item,
|
||||
shouldKeep: await asyncPredicate(item)
|
||||
})));
|
||||
const filterResults = await Promise.all(
|
||||
arr.map(async (item) => ({
|
||||
item,
|
||||
shouldKeep: await asyncPredicate(item),
|
||||
})),
|
||||
);
|
||||
|
||||
return filterResults.filter(({shouldKeep}) => shouldKeep).map(({item}) => item);
|
||||
}
|
||||
return filterResults.filter(({ shouldKeep }) => shouldKeep).map(({ item }) => item);
|
||||
};
|
||||
|
||||
const isAbstractClass = (node) => {
|
||||
if (ts.isClassDeclaration(node)) {
|
||||
return node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword) || false;
|
||||
return (
|
||||
node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword) || false
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const isAbstractMethod = (node) => {
|
||||
return ts.isMethodDeclaration(node) && Boolean(node.modifiers?.find((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword));
|
||||
}
|
||||
};
|
||||
|
||||
const isAbstractMethod = (node) => {
|
||||
return (
|
||||
ts.isMethodDeclaration(node) &&
|
||||
Boolean(node.modifiers?.find((modifier) => modifier.kind === ts.SyntaxKind.AbstractKeyword))
|
||||
);
|
||||
};
|
||||
|
||||
// Function to check if a file has a function declaration, function expression, object method or class
|
||||
const hasFunctionOrClass = async filePath => {
|
||||
const hasFunctionOrClass = async (filePath) => {
|
||||
const fileContent = await readFileAsync(filePath, 'utf-8');
|
||||
const sourceFile = ts.createSourceFile(filePath, fileContent, ts.ScriptTarget.Latest, true);
|
||||
|
||||
let hasFunctionOrClass = false;
|
||||
const visit = node => {
|
||||
const visit = (node) => {
|
||||
if (
|
||||
ts.isFunctionDeclaration(node)
|
||||
|| ts.isFunctionExpression(node)
|
||||
|| ts.isArrowFunction(node)
|
||||
|| (ts.isMethodDeclaration(node) && !isAbstractMethod(node))
|
||||
|| (ts.isClassDeclaration(node) && !isAbstractClass(node))
|
||||
ts.isFunctionDeclaration(node) ||
|
||||
ts.isFunctionExpression(node) ||
|
||||
ts.isArrowFunction(node) ||
|
||||
(ts.isMethodDeclaration(node) && !isAbstractMethod(node)) ||
|
||||
(ts.isClassDeclaration(node) && !isAbstractClass(node))
|
||||
) {
|
||||
hasFunctionOrClass = true;
|
||||
}
|
||||
node.forEachChild(visit);
|
||||
}
|
||||
};
|
||||
|
||||
visit(sourceFile);
|
||||
|
||||
return hasFunctionOrClass;
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
// Run a git command to get a list of all changed files in the branch (branch has to be up to date with master)
|
||||
const changedFiles = await execAsync(
|
||||
'git diff --name-only --diff-filter=d origin/master..HEAD',
|
||||
).then(({ stdout }) => stdout.trim().split('\n').filter(Boolean));
|
||||
|
||||
// Run a git command to get a list of all changed files in the branch (branch has to be up to date with master)
|
||||
const changedFiles = await execAsync('git diff --name-only --diff-filter=d origin/master..HEAD')
|
||||
.then(({stdout}) => stdout.trim().split('\n').filter(Boolean));
|
||||
|
||||
// Get all .spec.ts and .test.ts files from the packages
|
||||
// Get all .spec.ts and .test.ts files from the packages
|
||||
const specAndTestTsFiles = await glob('packages/*/**/{test,__tests__}/**/*.{spec,test}.ts');
|
||||
const specAndTestTsFilesNames = specAndTestTsFiles.map(file => path.parse(file).name.replace(/\.(test|spec)/, ''));
|
||||
|
||||
// Filter out the .ts and .vue files from the changed files
|
||||
const changedVueFiles = changedFiles.filter(file => file.endsWith('.vue'));
|
||||
// .ts files with any kind of function declaration or class and not in any of the test folders
|
||||
const changedTsFilesWithFunction = await filterAsync(
|
||||
async filePath =>
|
||||
filePath.endsWith('.ts') &&
|
||||
!(await glob('packages/*/**/{test,__tests__}/*.ts')).includes(filePath) &&
|
||||
await hasFunctionOrClass(filePath),
|
||||
changedFiles
|
||||
const specAndTestTsFilesNames = specAndTestTsFiles.map((file) =>
|
||||
path.parse(file).name.replace(/\.(test|spec)/, ''),
|
||||
);
|
||||
|
||||
// For each .ts or .vue file, check if there's a corresponding .test.ts or .spec.ts file in the repository
|
||||
const missingTests = changedVueFiles.concat(changedTsFilesWithFunction).reduce((filesList, nextFile) => {
|
||||
const fileName = path.parse(nextFile).name;
|
||||
// Filter out the .ts and .vue files from the changed files
|
||||
const changedVueFiles = changedFiles.filter((file) => file.endsWith('.vue'));
|
||||
// .ts files with any kind of function declaration or class and not in any of the test folders
|
||||
const changedTsFilesWithFunction = await filterAsync(
|
||||
async (filePath) =>
|
||||
filePath.endsWith('.ts') &&
|
||||
!(await glob('packages/*/**/{test,__tests__}/*.ts')).includes(filePath) &&
|
||||
(await hasFunctionOrClass(filePath)),
|
||||
changedFiles,
|
||||
);
|
||||
|
||||
if (!specAndTestTsFilesNames.includes(fileName)) {
|
||||
filesList.push(nextFile);
|
||||
}
|
||||
// For each .ts or .vue file, check if there's a corresponding .test.ts or .spec.ts file in the repository
|
||||
const missingTests = changedVueFiles
|
||||
.concat(changedTsFilesWithFunction)
|
||||
.reduce((filesList, nextFile) => {
|
||||
const fileName = path.parse(nextFile).name;
|
||||
|
||||
return filesList;
|
||||
}, []);
|
||||
if (!specAndTestTsFilesNames.includes(fileName)) {
|
||||
filesList.push(nextFile);
|
||||
}
|
||||
|
||||
if(missingTests.length) {
|
||||
return filesList;
|
||||
}, []);
|
||||
|
||||
if (missingTests.length) {
|
||||
console.error(`Missing tests for:\n${missingTests.join('\n')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ coverage
|
|||
dist
|
||||
package.json
|
||||
.pnpm-lock.yml
|
||||
packages/editor-ui/index.html
|
||||
packages/nodes-base/nodes/**/test
|
||||
cypress/fixtures
|
||||
CHANGELOG.md
|
||||
|
|
1
.vscode/settings.default.json
vendored
1
.vscode/settings.default.json
vendored
|
@ -9,6 +9,7 @@
|
|||
"typescript.format.enable": false,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"workspace-default-settings.runOnActivation": true,
|
||||
"prettier.prettierPath": "node_modules/prettier/index.cjs",
|
||||
"eslint.probe": ["javascript", "typescript", "vue"],
|
||||
"eslint.workingDirectories": [
|
||||
{
|
||||
|
|
|
@ -54,16 +54,22 @@ describe('Resource Locator', () => {
|
|||
|
||||
// unlike RMC and remote options, RLC does not support loadOptionDependsOn
|
||||
it('should retrieve list options when other params throw errors', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {action: 'Resource Locator'});
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', { action: 'Resource Locator' });
|
||||
|
||||
ndv.getters.resourceLocatorInput('rlc').click();
|
||||
getVisiblePopper().should('have.length', 1).findChildByTestId('rlc-item').should('have.length', 5);
|
||||
getVisiblePopper()
|
||||
.should('have.length', 1)
|
||||
.findChildByTestId('rlc-item')
|
||||
.should('have.length', 5);
|
||||
|
||||
ndv.actions.setInvalidExpression('fieldId');
|
||||
|
||||
ndv.getters.container().click(); // remove focus from input, hide expression preview
|
||||
|
||||
ndv.getters.resourceLocatorInput('rlc').click();
|
||||
getVisiblePopper().should('have.length', 1).findChildByTestId('rlc-item').should('have.length', 5);
|
||||
getVisiblePopper()
|
||||
.should('have.length', 1)
|
||||
.findChildByTestId('rlc-item')
|
||||
.should('have.length', 5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ describe('Two-factor authentication', () => {
|
|||
signinPage.actions.loginWithEmailAndPassword(email, password);
|
||||
personalSettingsPage.actions.enableMfa();
|
||||
mainSidebar.actions.signout();
|
||||
const token = generateOTPToken(user.mfaSecret)
|
||||
const token = generateOTPToken(user.mfaSecret);
|
||||
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
|
||||
mainSidebar.actions.signout();
|
||||
});
|
||||
|
@ -61,7 +61,7 @@ describe('Two-factor authentication', () => {
|
|||
signinPage.actions.loginWithEmailAndPassword(email, password);
|
||||
personalSettingsPage.actions.enableMfa();
|
||||
mainSidebar.actions.signout();
|
||||
const token = generateOTPToken(user.mfaSecret)
|
||||
const token = generateOTPToken(user.mfaSecret);
|
||||
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
|
||||
personalSettingsPage.actions.disableMfa();
|
||||
mainSidebar.actions.signout();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
HTTP_REQUEST_NODE_NAME, IF_NODE_NAME,
|
||||
HTTP_REQUEST_NODE_NAME,
|
||||
IF_NODE_NAME,
|
||||
INSTANCE_OWNER,
|
||||
MANUAL_TRIGGER_NODE_NAME,
|
||||
SET_NODE_NAME,
|
||||
|
@ -11,119 +12,121 @@ const ndv = new NDV();
|
|||
const executionsTab = new WorkflowExecutionsTab();
|
||||
|
||||
describe('Debug', () => {
|
||||
it('should be able to debug executions', () => {
|
||||
cy.intercept('GET', '/rest/settings', (req) => {
|
||||
req.on('response', (res) => {
|
||||
res.send({
|
||||
data: { ...res.body.data, enterprise: { debugInEditor: true } },
|
||||
});
|
||||
});
|
||||
}).as('loadSettings');
|
||||
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
|
||||
cy.intercept('GET', '/rest/executions/*').as('getExecution');
|
||||
cy.intercept('GET', '/rest/executions-current?filter=*').as('getCurrentExecutions');
|
||||
cy.intercept('POST', '/rest/workflows/run').as('postWorkflowRun');
|
||||
it('should be able to debug executions', () => {
|
||||
cy.intercept('GET', '/rest/settings', (req) => {
|
||||
req.on('response', (res) => {
|
||||
res.send({
|
||||
data: { ...res.body.data, enterprise: { debugInEditor: true } },
|
||||
});
|
||||
});
|
||||
}).as('loadSettings');
|
||||
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
|
||||
cy.intercept('GET', '/rest/executions/*').as('getExecution');
|
||||
cy.intercept('GET', '/rest/executions-current?filter=*').as('getCurrentExecutions');
|
||||
cy.intercept('POST', '/rest/workflows/run').as('postWorkflowRun');
|
||||
|
||||
cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password });
|
||||
cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password });
|
||||
|
||||
workflowPage.actions.visit();
|
||||
workflowPage.actions.visit();
|
||||
|
||||
workflowPage.actions.addInitialNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
|
||||
workflowPage.actions.addNodeToCanvas(HTTP_REQUEST_NODE_NAME);
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.typeIntoParameterInput('url', 'https://foo.bar');
|
||||
ndv.actions.close();
|
||||
workflowPage.actions.addInitialNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
|
||||
workflowPage.actions.addNodeToCanvas(HTTP_REQUEST_NODE_NAME);
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.typeIntoParameterInput('url', 'https://foo.bar');
|
||||
ndv.actions.close();
|
||||
|
||||
workflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true);
|
||||
workflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true);
|
||||
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
|
||||
cy.wait(['@postWorkflowRun']);
|
||||
cy.wait(['@postWorkflowRun']);
|
||||
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Debug in editor').click();
|
||||
cy.get('.el-notification').contains('Execution data imported').should('be.visible');
|
||||
cy.get('.matching-pinned-nodes-confirmation').should('not.exist');
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Debug in editor').click();
|
||||
cy.get('.el-notification').contains('Execution data imported').should('be.visible');
|
||||
cy.get('.matching-pinned-nodes-confirmation').should('not.exist');
|
||||
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.clearParameterInput('url');
|
||||
ndv.actions.typeIntoParameterInput('url', 'https://postman-echo.com/get?foo1=bar1&foo2=bar2');
|
||||
ndv.actions.close();
|
||||
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.clearParameterInput('url');
|
||||
ndv.actions.typeIntoParameterInput('url', 'https://postman-echo.com/get?foo1=bar1&foo2=bar2');
|
||||
ndv.actions.close();
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
cy.wait(['@postWorkflowRun']);
|
||||
|
||||
cy.wait(['@postWorkflowRun']);
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.pinData();
|
||||
ndv.actions.close();
|
||||
|
||||
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
|
||||
ndv.actions.pinData();
|
||||
ndv.actions.close();
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionListItems().should('have.length', 2).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
|
||||
executionsTab.getters.executionListItems().should('have.length', 2).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
let confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 2);
|
||||
confirmDialog.get('.btn--cancel').click();
|
||||
|
||||
let confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 2);
|
||||
confirmDialog.get('.btn--cancel').click();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionListItems().should('have.length', 2).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
|
||||
executionsTab.getters.executionListItems().should('have.length', 2).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 2);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 2);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
workflowPage.getters.canvasNodes().first().should('have.descendants', '.node-pin-data-icon');
|
||||
workflowPage.getters
|
||||
.canvasNodes()
|
||||
.not(':first')
|
||||
.should('not.have.descendants', '.node-pin-data-icon');
|
||||
|
||||
workflowPage.getters.canvasNodes().first().should('have.descendants', '.node-pin-data-icon');
|
||||
workflowPage.getters.canvasNodes().not(':first').should('not.have.descendants', '.node-pin-data-icon');
|
||||
cy.reload(true);
|
||||
cy.wait(['@getExecution']);
|
||||
|
||||
cy.reload(true);
|
||||
cy.wait(['@getExecution']);
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 1);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 1);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
workflowPage.getters.canvasNodePlusEndpointByName(SET_NODE_NAME).click();
|
||||
workflowPage.actions.addNodeToCanvas(IF_NODE_NAME, false);
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
|
||||
workflowPage.getters.canvasNodePlusEndpointByName(SET_NODE_NAME).click();
|
||||
workflowPage.actions.addNodeToCanvas(IF_NODE_NAME, false);
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 1);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
workflowPage.getters.canvasNodes().last().find('.node-info-icon').should('be.empty');
|
||||
|
||||
confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
|
||||
confirmDialog.find('li').should('have.length', 1);
|
||||
confirmDialog.get('.btn--confirm').click();
|
||||
workflowPage.getters.canvasNodes().last().find('.node-info-icon').should('be.empty');
|
||||
workflowPage.getters.canvasNodes().first().dblclick();
|
||||
ndv.getters.pinDataButton().click();
|
||||
ndv.actions.close();
|
||||
|
||||
workflowPage.getters.canvasNodes().first().dblclick();
|
||||
ndv.getters.pinDataButton().click();
|
||||
ndv.actions.close();
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
workflowPage.actions.deleteNode(IF_NODE_NAME);
|
||||
|
||||
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
workflowPage.actions.deleteNode(IF_NODE_NAME);
|
||||
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionListItems().should('have.length', 3).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
cy.get('.el-notification').contains('Some execution data wasn\'t imported').should('be.visible');
|
||||
});
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
executionsTab.getters.executionListItems().should('have.length', 3).first().click();
|
||||
cy.wait(['@getExecution']);
|
||||
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
|
||||
cy.get('.el-notification').contains("Some execution data wasn't imported").should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,9 +9,15 @@ describe('Resource Mapper', () => {
|
|||
});
|
||||
|
||||
it('should not retrieve list options when required params throw errors', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {action: 'Resource Mapping Component'});
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {
|
||||
action: 'Resource Mapping Component',
|
||||
});
|
||||
|
||||
ndv.getters.resourceMapperFieldsContainer().should('be.visible').findChildByTestId('parameter-input').should('have.length', 2);
|
||||
ndv.getters
|
||||
.resourceMapperFieldsContainer()
|
||||
.should('be.visible')
|
||||
.findChildByTestId('parameter-input')
|
||||
.should('have.length', 2);
|
||||
|
||||
ndv.actions.setInvalidExpression('fieldId');
|
||||
|
||||
|
@ -20,13 +26,23 @@ describe('Resource Mapper', () => {
|
|||
});
|
||||
|
||||
it('should retrieve list options when optional params throw errors', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {action: 'Resource Mapping Component'});
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {
|
||||
action: 'Resource Mapping Component',
|
||||
});
|
||||
|
||||
ndv.getters.resourceMapperFieldsContainer().should('be.visible').findChildByTestId('parameter-input').should('have.length', 2);
|
||||
ndv.getters
|
||||
.resourceMapperFieldsContainer()
|
||||
.should('be.visible')
|
||||
.findChildByTestId('parameter-input')
|
||||
.should('have.length', 2);
|
||||
|
||||
ndv.actions.setInvalidExpression('otherField');
|
||||
|
||||
ndv.actions.refreshResourceMapperColumns();
|
||||
ndv.getters.resourceMapperFieldsContainer().should('be.visible').findChildByTestId('parameter-input').should('have.length', 2);
|
||||
ndv.getters
|
||||
.resourceMapperFieldsContainer()
|
||||
.should('be.visible')
|
||||
.findChildByTestId('parameter-input')
|
||||
.should('have.length', 2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -291,7 +291,7 @@ describe('NDV', () => {
|
|||
});
|
||||
|
||||
it('should not retrieve remote options when required params throw errors', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {action: 'Remote Options'});
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', { action: 'Remote Options' });
|
||||
|
||||
ndv.getters.parameterInput('remoteOptions').click();
|
||||
getVisibleSelect().find('.el-select-dropdown__item').should('have.length', 3);
|
||||
|
@ -308,7 +308,7 @@ describe('NDV', () => {
|
|||
});
|
||||
|
||||
it('should retrieve remote options when non-required params throw errors', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', {action: 'Remote Options'});
|
||||
workflowPage.actions.addInitialNodeToCanvas('E2e Test', { action: 'Remote Options' });
|
||||
|
||||
ndv.getters.parameterInput('remoteOptions').click();
|
||||
getVisibleSelect().find('.el-select-dropdown__item').should('have.length', 3);
|
||||
|
@ -338,7 +338,7 @@ describe('NDV', () => {
|
|||
workflowPage.getters.nodeIssuesByName('Webhook').should('exist');
|
||||
|
||||
workflowPage.getters.canvasNodes().first().dblclick();
|
||||
ndv.getters.parameterInput('path').type('t')
|
||||
ndv.getters.parameterInput('path').type('t');
|
||||
|
||||
ndv.getters.nodeExecuteButton().should('not.be.disabled');
|
||||
ndv.getters.triggerPanelExecuteButton().should('exist');
|
||||
|
|
|
@ -13,7 +13,7 @@ describe('Code node', () => {
|
|||
});
|
||||
|
||||
it('should show correct placeholders switching modes', () => {
|
||||
cy.contains("// Loop over input items and add a new field").should('be.visible');
|
||||
cy.contains('// Loop over input items and add a new field').should('be.visible');
|
||||
|
||||
ndv.getters.parameterInput('mode').click();
|
||||
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item');
|
||||
|
@ -22,8 +22,8 @@ describe('Code node', () => {
|
|||
|
||||
ndv.getters.parameterInput('mode').click();
|
||||
ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for All Items');
|
||||
cy.contains("// Loop over input items and add a new field").should('be.visible');
|
||||
})
|
||||
cy.contains('// Loop over input items and add a new field').should('be.visible');
|
||||
});
|
||||
|
||||
it('should execute the placeholder successfully in both modes', () => {
|
||||
ndv.actions.execute();
|
||||
|
@ -36,7 +36,7 @@ describe('Code node', () => {
|
|||
|
||||
WorkflowPage.getters.successToast().contains('Node executed successfully');
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe('Ask AI', () => {
|
||||
it('tab should display based on experiment', () => {
|
||||
|
@ -53,8 +53,8 @@ describe('Code node', () => {
|
|||
win.featureFlags.override('011_ask_AI', undefined);
|
||||
WorkflowPage.actions.openNode('Code');
|
||||
cy.getByTestId('code-node-tab-ai').should('not.exist');
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('Enabled', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -63,20 +63,19 @@ describe('Code node', () => {
|
|||
win.featureFlags.override('011_ask_AI', 'gpt3');
|
||||
WorkflowPage.actions.addInitialNodeToCanvas('Manual');
|
||||
WorkflowPage.actions.addNodeToCanvas('Code', true, true);
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('tab should exist if experiment selected and be selectable', () => {
|
||||
cy.getByTestId('code-node-tab-ai').should('exist');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
cy.contains('Hey AI, generate JavaScript').should('exist');
|
||||
})
|
||||
cy.getByTestId('code-node-tab-ai').should('exist');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
cy.contains('Hey AI, generate JavaScript').should('exist');
|
||||
});
|
||||
|
||||
it('generate code button should have correct state & tooltips', () => {
|
||||
cy.getByTestId('code-node-tab-ai').should('exist');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
|
||||
|
||||
cy.getByTestId('ask-ai-cta').should('be.disabled');
|
||||
cy.getByTestId('ask-ai-cta').realHover();
|
||||
cy.getByTestId('ask-ai-cta-tooltip-no-input-data').should('exist');
|
||||
|
@ -85,7 +84,7 @@ describe('Code node', () => {
|
|||
cy.getByTestId('ask-ai-cta-tooltip-no-prompt').should('exist');
|
||||
cy.getByTestId('ask-ai-prompt-input')
|
||||
// Type random 14 character string
|
||||
.type([...Array(14)].map(() => (Math.random() * 36 | 0).toString(36)).join(''))
|
||||
.type([...Array(14)].map(() => ((Math.random() * 36) | 0).toString(36)).join(''));
|
||||
|
||||
cy.getByTestId('ask-ai-cta').realHover();
|
||||
cy.getByTestId('ask-ai-cta-tooltip-prompt-too-short').should('exist');
|
||||
|
@ -93,64 +92,66 @@ describe('Code node', () => {
|
|||
cy.getByTestId('ask-ai-prompt-input')
|
||||
.clear()
|
||||
// Type random 15 character string
|
||||
.type([...Array(15)].map(() => (Math.random() * 36 | 0).toString(36)).join(''))
|
||||
.type([...Array(15)].map(() => ((Math.random() * 36) | 0).toString(36)).join(''));
|
||||
cy.getByTestId('ask-ai-cta').should('be.enabled');
|
||||
|
||||
cy.getByTestId('ask-ai-prompt-counter').should('contain.text', '15 / 600');
|
||||
})
|
||||
});
|
||||
|
||||
it('should send correct schema and replace code', () => {
|
||||
const prompt = [...Array(20)].map(() => (Math.random() * 36 | 0).toString(36)).join('');
|
||||
const prompt = [...Array(20)].map(() => ((Math.random() * 36) | 0).toString(36)).join('');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
ndv.actions.executePrevious();
|
||||
|
||||
cy.getByTestId('ask-ai-prompt-input').type(prompt)
|
||||
cy.getByTestId('ask-ai-prompt-input').type(prompt);
|
||||
|
||||
cy.intercept('POST', '/rest/ask-ai', {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
data: {
|
||||
code: 'console.log("Hello World")'
|
||||
code: 'console.log("Hello World")',
|
||||
},
|
||||
}
|
||||
},
|
||||
}).as('ask-ai');
|
||||
|
||||
cy.getByTestId('ask-ai-cta').click();
|
||||
const askAiReq = cy.wait('@ask-ai')
|
||||
const askAiReq = cy.wait('@ask-ai');
|
||||
|
||||
askAiReq.its('request.body').should('have.keys', ['question', 'model', 'context', 'n8nVersion']);
|
||||
askAiReq
|
||||
.its('request.body')
|
||||
.should('have.keys', ['question', 'model', 'context', 'n8nVersion']);
|
||||
|
||||
askAiReq.its('context').should('have.keys', ['schema', 'ndvSessionId', 'sessionId']);
|
||||
|
||||
cy.contains('Code generation completed').should('be.visible')
|
||||
cy.contains('Code generation completed').should('be.visible');
|
||||
cy.getByTestId('code-node-tab-code').should('contain.text', 'console.log("Hello World")');
|
||||
cy.get('#tab-code').should('have.class', 'is-active');
|
||||
})
|
||||
});
|
||||
|
||||
it('should show error based on status code', () => {
|
||||
const prompt = [...Array(20)].map(() => (Math.random() * 36 | 0).toString(36)).join('');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
ndv.actions.executePrevious();
|
||||
const prompt = [...Array(20)].map(() => ((Math.random() * 36) | 0).toString(36)).join('');
|
||||
cy.get('#tab-ask-ai').click();
|
||||
ndv.actions.executePrevious();
|
||||
|
||||
cy.getByTestId('ask-ai-prompt-input').type(prompt)
|
||||
cy.getByTestId('ask-ai-prompt-input').type(prompt);
|
||||
|
||||
const handledCodes = [
|
||||
{ code: 400, message: 'Code generation failed due to an unknown reason' },
|
||||
{ code: 413, message: 'Your workflow data is too large for AI to process' },
|
||||
{ code: 429, message: 'We\'ve hit our rate limit with our AI partner' },
|
||||
{ code: 500, message: 'Code generation failed due to an unknown reason' },
|
||||
]
|
||||
const handledCodes = [
|
||||
{ code: 400, message: 'Code generation failed due to an unknown reason' },
|
||||
{ code: 413, message: 'Your workflow data is too large for AI to process' },
|
||||
{ code: 429, message: "We've hit our rate limit with our AI partner" },
|
||||
{ code: 500, message: 'Code generation failed due to an unknown reason' },
|
||||
];
|
||||
|
||||
handledCodes.forEach(({ code, message }) => {
|
||||
cy.intercept('POST', '/rest/ask-ai', {
|
||||
statusCode: code,
|
||||
status: code,
|
||||
}).as('ask-ai');
|
||||
handledCodes.forEach(({ code, message }) => {
|
||||
cy.intercept('POST', '/rest/ask-ai', {
|
||||
statusCode: code,
|
||||
status: code,
|
||||
}).as('ask-ai');
|
||||
|
||||
cy.getByTestId('ask-ai-cta').click();
|
||||
cy.contains(message).should('be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
cy.getByTestId('ask-ai-cta').click();
|
||||
cy.contains(message).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,7 +39,11 @@ export class NDV extends BasePage {
|
|||
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
||||
nodeParameters: () => cy.getByTestId('node-parameters'),
|
||||
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
|
||||
parameterInputIssues: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`).should('have.length', 1).findChildByTestId('parameter-issues'),
|
||||
parameterInputIssues: (parameterName: string) =>
|
||||
cy
|
||||
.getByTestId(`parameter-input-${parameterName}`)
|
||||
.should('have.length', 1)
|
||||
.findChildByTestId('parameter-issues'),
|
||||
parameterExpressionPreview: (parameterName: string) =>
|
||||
this.getters
|
||||
.nodeParameters()
|
||||
|
@ -102,7 +106,11 @@ export class NDV extends BasePage {
|
|||
clearParameterInput: (parameterName: string) => {
|
||||
this.getters.parameterInput(parameterName).type(`{selectall}{backspace}`);
|
||||
},
|
||||
typeIntoParameterInput: (parameterName: string, content: string, opts?: { parseSpecialCharSequences: boolean }) => {
|
||||
typeIntoParameterInput: (
|
||||
parameterName: string,
|
||||
content: string,
|
||||
opts?: { parseSpecialCharSequences: boolean },
|
||||
) => {
|
||||
this.getters.parameterInput(parameterName).type(content, opts);
|
||||
},
|
||||
selectOptionInParameterDropdown: (parameterName: string, content: string) => {
|
||||
|
@ -177,16 +185,22 @@ export class NDV extends BasePage {
|
|||
|
||||
refreshResourceMapperColumns: () => {
|
||||
this.getters.resourceMapperSelectColumn().realHover();
|
||||
this.getters.resourceMapperSelectColumn().findChildByTestId('action-toggle').should('have.length', 1).click();
|
||||
this.getters
|
||||
.resourceMapperSelectColumn()
|
||||
.findChildByTestId('action-toggle')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
getVisiblePopper().find('li').last().click();
|
||||
},
|
||||
|
||||
setInvalidExpression: (fieldName: string, invalidExpression?: string) => {
|
||||
this.actions.typeIntoParameterInput(fieldName, "=");
|
||||
this.actions.typeIntoParameterInput(fieldName, invalidExpression ?? "{{ $('unknown')", { parseSpecialCharSequences: false });
|
||||
this.actions.typeIntoParameterInput(fieldName, '=');
|
||||
this.actions.typeIntoParameterInput(fieldName, invalidExpression ?? "{{ $('unknown')", {
|
||||
parseSpecialCharSequences: false,
|
||||
});
|
||||
this.actions.validateExpressionPreview(fieldName, `node doesn't exist`);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ export class PersonalSettingsPage extends BasePage {
|
|||
this.getters.enableMfaButton().click();
|
||||
mfaSetupModal.getters.copySecretToClipboardButton().realClick();
|
||||
cy.readClipboard().then((secret) => {
|
||||
const token = generateOTPToken(secret)
|
||||
const token = generateOTPToken(secret);
|
||||
|
||||
mfaSetupModal.getters.tokenInput().type(token);
|
||||
mfaSetupModal.getters.downloadRecoveryCodesButton().click();
|
||||
|
|
|
@ -29,9 +29,11 @@ export class WorkflowPage extends BasePage {
|
|||
canvasNodeByName: (nodeName: string) =>
|
||||
this.getters.canvasNodes().filter(`:contains(${nodeName})`),
|
||||
nodeIssuesByName: (nodeName: string) =>
|
||||
this.getters.canvasNodes().filter(`:contains(${nodeName})`)
|
||||
.should('have.length.greaterThan', 0)
|
||||
.findChildByTestId('node-issues'),
|
||||
this.getters
|
||||
.canvasNodes()
|
||||
.filter(`:contains(${nodeName})`)
|
||||
.should('have.length.greaterThan', 0)
|
||||
.findChildByTestId('node-issues'),
|
||||
getEndpointSelector: (type: 'input' | 'output' | 'plus', nodeName: string, index = 0) => {
|
||||
return `[data-endpoint-name='${nodeName}'][data-endpoint-type='${type}'][data-input-index='${index}']`;
|
||||
},
|
||||
|
@ -132,14 +134,16 @@ export class WorkflowPage extends BasePage {
|
|||
win.preventNodeViewBeforeUnload = preventNodeViewUnload;
|
||||
});
|
||||
},
|
||||
addInitialNodeToCanvas: (nodeDisplayName: string, opts?: { keepNdvOpen?: boolean, action?: string }) => {
|
||||
addInitialNodeToCanvas: (
|
||||
nodeDisplayName: string,
|
||||
opts?: { keepNdvOpen?: boolean; action?: string },
|
||||
) => {
|
||||
this.getters.canvasPlusButton().click();
|
||||
this.getters.nodeCreatorSearchBar().type(nodeDisplayName);
|
||||
this.getters.nodeCreatorSearchBar().type('{enter}');
|
||||
if (opts?.action) {
|
||||
nodeCreator.getters.getCreatorItem(opts.action).click();
|
||||
}
|
||||
else if (!opts?.keepNdvOpen) {
|
||||
} else if (!opts?.keepNdvOpen) {
|
||||
cy.get('body').type('{esc}');
|
||||
}
|
||||
},
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
"@types/node": "^18.16.16",
|
||||
"chokidar": "3.5.2",
|
||||
"jsonwebtoken": "9.0.0",
|
||||
"prettier": "^3.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"semver": "^7.5.4",
|
||||
"tough-cookie": "^4.1.3",
|
||||
"tslib": "^2.6.1",
|
||||
|
|
|
@ -6,7 +6,7 @@ This list shows all the versions which include breaking changes and how to upgra
|
|||
|
||||
### What changed?
|
||||
|
||||
In the Code node, `console.log` does not output to stdout by default.
|
||||
In the Code node, `console.log` does not output to stdout by default.
|
||||
|
||||
### When is action necessary?
|
||||
|
||||
|
|
|
@ -56,9 +56,8 @@ export class ActiveExecutions {
|
|||
fullExecutionData.workflowId = workflowId;
|
||||
}
|
||||
|
||||
const executionResult = await Container.get(ExecutionRepository).createNewExecution(
|
||||
fullExecutionData,
|
||||
);
|
||||
const executionResult =
|
||||
await Container.get(ExecutionRepository).createNewExecution(fullExecutionData);
|
||||
executionId = executionResult.id;
|
||||
if (executionId === undefined) {
|
||||
throw new Error('There was an issue assigning an execution id to the execution');
|
||||
|
|
|
@ -1251,9 +1251,8 @@ export class Server extends AbstractServer {
|
|||
Object.assign(findOptions.where, { workflowId: In(sharedWorkflowIds) });
|
||||
}
|
||||
|
||||
const executions = await Container.get(ExecutionRepository).findMultipleExecutions(
|
||||
findOptions,
|
||||
);
|
||||
const executions =
|
||||
await Container.get(ExecutionRepository).findMultipleExecutions(findOptions);
|
||||
|
||||
if (!executions.length) return [];
|
||||
|
||||
|
|
|
@ -54,9 +54,8 @@ export class SourceControlController {
|
|||
await this.sourceControlPreferencesService.validateSourceControlPreferences(
|
||||
sanitizedPreferences,
|
||||
);
|
||||
const updatedPreferences = await this.sourceControlPreferencesService.setPreferences(
|
||||
sanitizedPreferences,
|
||||
);
|
||||
const updatedPreferences =
|
||||
await this.sourceControlPreferencesService.setPreferences(sanitizedPreferences);
|
||||
if (sanitizedPreferences.initRepo === true) {
|
||||
try {
|
||||
await this.sourceControlService.initializeRepository(
|
||||
|
|
|
@ -317,9 +317,8 @@ export class ExecutionsService {
|
|||
const workflowRunner = new WorkflowRunner();
|
||||
const retriedExecutionId = await workflowRunner.run(data);
|
||||
|
||||
const executionData = await Container.get(ActiveExecutions).getPostExecutePromise(
|
||||
retriedExecutionId,
|
||||
);
|
||||
const executionData =
|
||||
await Container.get(ActiveExecutions).getPostExecutePromise(retriedExecutionId);
|
||||
|
||||
if (!executionData) {
|
||||
throw new Error('The retry did not start for an unknown reason.');
|
||||
|
|
|
@ -3,7 +3,7 @@ import { createEventBus } from '../event-bus';
|
|||
// @TODO: Remove when conflicting vitest and jest globals are reconciled
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||
const vi: typeof import('vitest')['vitest'];
|
||||
const vi: (typeof import('vitest'))['vitest'];
|
||||
}
|
||||
|
||||
describe('createEventBus()', () => {
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"n8n-workflow": "workspace:*",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"pinia": "^2.1.6",
|
||||
"prettier": "^3.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"qrcode.vue": "^3.3.4",
|
||||
"timeago.js": "^4.0.2",
|
||||
|
|
|
@ -3891,9 +3891,8 @@ export default defineComponent({
|
|||
await Promise.all([this.loadCredentials(), this.loadVariables(), this.tagsStore.fetchAll()]);
|
||||
|
||||
if (workflowId !== null && !this.uiStore.stateIsDirty) {
|
||||
const workflow: IWorkflowDb | undefined = await this.workflowsStore.fetchWorkflow(
|
||||
workflowId,
|
||||
);
|
||||
const workflow: IWorkflowDb | undefined =
|
||||
await this.workflowsStore.fetchWorkflow(workflowId);
|
||||
if (workflow) {
|
||||
this.titleSet(workflow.name, 'IDLE');
|
||||
await this.openWorkflow(workflow);
|
||||
|
|
|
@ -11,7 +11,7 @@ overrides:
|
|||
'@types/node': ^18.16.16
|
||||
chokidar: 3.5.2
|
||||
jsonwebtoken: 9.0.0
|
||||
prettier: ^3.0.0
|
||||
prettier: ^3.0.3
|
||||
semver: ^7.5.4
|
||||
tough-cookie: ^4.1.3
|
||||
tslib: ^2.6.1
|
||||
|
@ -178,7 +178,7 @@ importers:
|
|||
version: 1.0.0
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(@types/eslint@8.44.1)(eslint-config-prettier@8.9.0)(eslint@8.45.0)(prettier@3.0.0)
|
||||
version: 5.0.0(@types/eslint@8.44.1)(eslint-config-prettier@8.9.0)(eslint@8.45.0)(prettier@3.0.3)
|
||||
eslint-plugin-unicorn:
|
||||
specifier: ^48.0.1
|
||||
version: 48.0.1(eslint@8.45.0)
|
||||
|
@ -894,8 +894,8 @@ importers:
|
|||
specifier: ^2.1.6
|
||||
version: 2.1.6(typescript@5.2.2)(vue@3.3.4)
|
||||
prettier:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
qrcode.vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4(vue@3.3.4)
|
||||
|
@ -5885,7 +5885,7 @@ packages:
|
|||
less-loader: 11.1.3(less@4.1.3)(webpack@5.75.0)
|
||||
postcss: 8.4.27
|
||||
postcss-loader: 7.3.3(postcss@8.4.27)(webpack@5.75.0)
|
||||
prettier: 3.0.0
|
||||
prettier: 3.0.3
|
||||
react: 17.0.2
|
||||
react-dom: 18.2.0(react@17.0.2)
|
||||
resolve-url-loader: 5.0.0
|
||||
|
@ -6199,7 +6199,7 @@ packages:
|
|||
jscodeshift: 0.14.0(@babel/preset-env@7.22.9)
|
||||
leven: 3.1.0
|
||||
ora: 5.4.1
|
||||
prettier: 3.0.0
|
||||
prettier: 3.0.3
|
||||
prompts: 2.4.2
|
||||
puppeteer-core: 2.1.1
|
||||
read-pkg-up: 7.0.1
|
||||
|
@ -6250,7 +6250,7 @@ packages:
|
|||
globby: 11.1.0
|
||||
jscodeshift: 0.14.0(@babel/preset-env@7.22.9)
|
||||
lodash: 4.17.21
|
||||
prettier: 3.0.0
|
||||
prettier: 3.0.3
|
||||
recast: 0.23.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -10620,7 +10620,7 @@ packages:
|
|||
cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x || ^12.x
|
||||
dependencies:
|
||||
cypress: 12.17.2
|
||||
prettier: 3.0.0
|
||||
prettier: 3.0.3
|
||||
dev: true
|
||||
|
||||
/cypress@12.17.2:
|
||||
|
@ -11810,14 +11810,14 @@ packages:
|
|||
- typescript
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-prettier@5.0.0(@types/eslint@8.44.1)(eslint-config-prettier@8.9.0)(eslint@8.45.0)(prettier@3.0.0):
|
||||
/eslint-plugin-prettier@5.0.0(@types/eslint@8.44.1)(eslint-config-prettier@8.9.0)(eslint@8.45.0)(prettier@3.0.3):
|
||||
resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
'@types/eslint': '>=8.0.0'
|
||||
eslint: '>=8.0.0'
|
||||
eslint-config-prettier: '*'
|
||||
prettier: ^3.0.0
|
||||
prettier: ^3.0.3
|
||||
peerDependenciesMeta:
|
||||
'@types/eslint':
|
||||
optional: true
|
||||
|
@ -11827,7 +11827,7 @@ packages:
|
|||
'@types/eslint': 8.44.1
|
||||
eslint: 8.45.0
|
||||
eslint-config-prettier: 8.9.0(eslint@8.45.0)
|
||||
prettier: 3.0.0
|
||||
prettier: 3.0.3
|
||||
prettier-linter-helpers: 1.0.0
|
||||
synckit: 0.8.5
|
||||
dev: true
|
||||
|
@ -18035,8 +18035,8 @@ packages:
|
|||
fast-diff: 1.2.0
|
||||
dev: true
|
||||
|
||||
/prettier@3.0.0:
|
||||
resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==}
|
||||
/prettier@3.0.3:
|
||||
resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
|
|
Loading…
Reference in a new issue