n8n/packages/cli/src/requests.ts
Val 1bb987140a
feat: Add variables feature (#5602)
* feat: add variables db models and migrations

* feat: variables api endpoints

* feat: add $variables to expressions

* test: fix ActiveWorkflowRunner tests failing

* test: a different fix for the tests broken by $variables

* feat: variables licensing

* fix: could create one extra variable than licensed for

* feat: Add Variables UI page and $vars global property (#5750)

* feat: add support for row slot to datatable

* feat: add variables create, read, update, delete

* feat: add vars autocomplete

* chore: remove alert

* feat: add variables autocomplete for code and expressions

* feat: add tests for variable components

* feat: add variables search and sort

* test: update tests for variables view

* chore: fix test and linting issue

* refactor: review changes

* feat: add variable creation telemetry

* fix: Improve variables listing and disabled case, fix resource sorting (no-changelog) (#5903)

* fix: Improve variables disabled experience and fix sorting

* fix: update action box margin

* test: update tests for variables row and datatable

* fix: Add ee controller to base controller

* fix: variables.ee routes not being added

* feat: add variables validation

* fix: fix vue-fragment bug that breaks everything

* chore: Update lock

* feat: Add variables input validation and permissions (no-changelog) (#5910)

* feat: add input validation

* feat: handle variables view for non-instance-owner users

* test: update variables tests

* fix: fix data-testid pattern

* feat: improve overflow styles

* test: fix variables row snapshot

* feat: update sorting to take newly created variables into account

* fix: fix list layout overflow

* fix: fix adding variables on page other than 1. fix validation

* feat: add docs link

* fix: fix default displayName function for resource-list-layout

* feat: improve vars expressions ux, cm-tooltip

* test: fix datatable test

* feat: add MATCH_REGEX validation rule

* fix: overhaul how datatable pagination selector works

* feat: update  completer description

* fix: conditionally update usage syntax based on key validation

* test: update datatable snapshot

* fix: fix variables-row button margins

* fix: fix pagination overflow

* test: Fix broken test

* test: Update snapshot

* fix: Remove duplicate declaration

* feat: add custom variables icon

---------

Co-authored-by: Alex Grozav <alex@grozav.com>
Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-04-18 12:41:55 +02:00

404 lines
10 KiB
TypeScript

import type express from 'express';
import type {
IConnections,
ICredentialDataDecryptedObject,
ICredentialNodeAccess,
INode,
INodeCredentialTestRequest,
IPinData,
IRunData,
IWorkflowSettings,
} from 'n8n-workflow';
import { IsBoolean, IsEmail, IsOptional, IsString, Length } from 'class-validator';
import { NoXss } from '@db/utils/customValidators';
import type { PublicUser, IExecutionDeleteFilter, IWorkflowDb } from '@/Interfaces';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import type { UserManagementMailer } from '@/UserManagement/email';
import type { Variables } from '@db/entities/Variables';
export class UserUpdatePayload implements Pick<User, 'email' | 'firstName' | 'lastName'> {
@IsEmail()
email: string;
@NoXss()
@IsString({ message: 'First name must be of type string.' })
@Length(1, 32, { message: 'First name must be $constraint1 to $constraint2 characters long.' })
firstName: string;
@NoXss()
@IsString({ message: 'Last name must be of type string.' })
@Length(1, 32, { message: 'Last name must be $constraint1 to $constraint2 characters long.' })
lastName: string;
}
export class UserSettingsUpdatePayload {
@IsBoolean({ message: 'showUserActivationSurvey should be a boolean' })
@IsOptional()
showUserActivationSurvey: boolean;
@IsBoolean({ message: 'userActivated should be a boolean' })
@IsOptional()
userActivated: boolean;
}
export type AuthlessRequest<
RouteParams = {},
ResponseBody = {},
RequestBody = {},
RequestQuery = {},
> = express.Request<RouteParams, ResponseBody, RequestBody, RequestQuery>;
export type AuthenticatedRequest<
RouteParams = {},
ResponseBody = {},
RequestBody = {},
RequestQuery = {},
> = Omit<express.Request<RouteParams, ResponseBody, RequestBody, RequestQuery>, 'user'> & {
user: User;
mailer?: UserManagementMailer;
globalMemberRole?: Role;
};
// ----------------------------------
// /workflows
// ----------------------------------
export declare namespace WorkflowRequest {
type CreateUpdatePayload = Partial<{
id: string; // delete if sent
name: string;
nodes: INode[];
connections: IConnections;
settings: IWorkflowSettings;
active: boolean;
tags: string[];
hash: string;
}>;
type ManualRunPayload = {
workflowData: IWorkflowDb;
runData: IRunData;
pinData: IPinData;
startNodes?: string[];
destinationNode?: string;
};
type Create = AuthenticatedRequest<{}, {}, CreateUpdatePayload>;
type Get = AuthenticatedRequest<{ id: string }>;
type Delete = Get;
type Update = AuthenticatedRequest<
{ id: string },
{},
CreateUpdatePayload,
{ forceSave?: string }
>;
type NewName = AuthenticatedRequest<{}, {}, {}, { name?: string }>;
type GetAll = AuthenticatedRequest<{}, {}, {}, { filter: string }>;
type GetAllActive = AuthenticatedRequest;
type GetAllActivationErrors = Get;
type ManualRun = AuthenticatedRequest<{}, {}, ManualRunPayload>;
type Share = AuthenticatedRequest<{ workflowId: string }, {}, { shareWithIds: string[] }>;
}
// ----------------------------------
// /credentials
// ----------------------------------
export declare namespace CredentialRequest {
type CredentialProperties = Partial<{
id: string; // delete if sent
name: string;
type: string;
nodesAccess: ICredentialNodeAccess[];
data: ICredentialDataDecryptedObject;
}>;
type Create = AuthenticatedRequest<{}, {}, CredentialProperties>;
type Get = AuthenticatedRequest<{ id: string }, {}, {}, Record<string, string>>;
type Delete = Get;
type GetAll = AuthenticatedRequest<{}, {}, {}, { filter: string }>;
type Update = AuthenticatedRequest<{ id: string }, {}, CredentialProperties>;
type NewName = WorkflowRequest.NewName;
type Test = AuthenticatedRequest<{}, {}, INodeCredentialTestRequest>;
type Share = AuthenticatedRequest<{ credentialId: string }, {}, { shareWithIds: string[] }>;
}
// ----------------------------------
// /executions
// ----------------------------------
export declare namespace ExecutionRequest {
namespace QueryParam {
type GetAll = {
filter: string; // '{ waitTill: string; finished: boolean, [other: string]: string }'
limit: string;
lastId: string;
firstId: string;
};
type GetAllCurrent = {
filter: string; // '{ workflowId: string }'
};
}
type GetAll = AuthenticatedRequest<{}, {}, {}, QueryParam.GetAll>;
type Get = AuthenticatedRequest<{ id: string }, {}, {}, { unflattedResponse: 'true' | 'false' }>;
type Delete = AuthenticatedRequest<{}, {}, IExecutionDeleteFilter>;
type Retry = AuthenticatedRequest<{ id: string }, {}, { loadWorkflow: boolean }, {}>;
type Stop = AuthenticatedRequest<{ id: string }>;
type GetAllCurrent = AuthenticatedRequest<{}, {}, {}, QueryParam.GetAllCurrent>;
}
// ----------------------------------
// /me
// ----------------------------------
export declare namespace MeRequest {
export type UserSettingsUpdate = AuthenticatedRequest<{}, {}, UserSettingsUpdatePayload>;
export type UserUpdate = AuthenticatedRequest<{}, {}, UserUpdatePayload>;
export type Password = AuthenticatedRequest<
{},
{},
{ currentPassword: string; newPassword: string }
>;
export type SurveyAnswers = AuthenticatedRequest<{}, {}, Record<string, string> | {}>;
}
// ----------------------------------
// /owner
// ----------------------------------
export declare namespace OwnerRequest {
type Post = AuthenticatedRequest<
{},
{},
Partial<{
email: string;
password: string;
firstName: string;
lastName: string;
}>,
{}
>;
}
// ----------------------------------
// password reset endpoints
// ----------------------------------
export declare namespace PasswordResetRequest {
export type Email = AuthlessRequest<{}, {}, Pick<PublicUser, 'email'>>;
export type Credentials = AuthlessRequest<{}, {}, {}, { userId?: string; token?: string }>;
export type NewPassword = AuthlessRequest<
{},
{},
Pick<PublicUser, 'password'> & { token?: string; userId?: string }
>;
}
// ----------------------------------
// /users
// ----------------------------------
export declare namespace UserRequest {
export type List = AuthenticatedRequest;
export type Invite = AuthenticatedRequest<{}, {}, Array<{ email: string }>>;
export type ResolveSignUp = AuthlessRequest<
{},
{},
{},
{ inviterId?: string; inviteeId?: string }
>;
export type SignUp = AuthenticatedRequest<
{ id: string },
{ inviterId?: string; inviteeId?: string }
>;
export type Delete = AuthenticatedRequest<
{ id: string; email: string; identifier: string },
{},
{},
{ transferId?: string; includeRole: boolean }
>;
export type Get = AuthenticatedRequest<
{ id: string; email: string; identifier: string },
{},
{},
{ limit?: number; offset?: number; cursor?: string; includeRole?: boolean }
>;
export type Reinvite = AuthenticatedRequest<{ id: string }>;
export type Update = AuthlessRequest<
{ id: string },
{},
{
inviterId: string;
firstName: string;
lastName: string;
password: string;
}
>;
}
// ----------------------------------
// /login
// ----------------------------------
export type LoginRequest = AuthlessRequest<
{},
{},
{
email: string;
password: string;
}
>;
// ----------------------------------
// oauth endpoints
// ----------------------------------
export declare namespace OAuthRequest {
namespace OAuth1Credential {
type Auth = AuthenticatedRequest<{}, {}, {}, { id: string }>;
type Callback = AuthenticatedRequest<
{},
{},
{},
{ oauth_verifier: string; oauth_token: string; cid: string }
> & {
user?: User;
};
}
namespace OAuth2Credential {
type Auth = OAuth1Credential.Auth;
type Callback = AuthenticatedRequest<{}, {}, {}, { code: string; state: string }>;
}
}
// ----------------------------------
// /node-parameter-options
// ----------------------------------
export type NodeParameterOptionsRequest = AuthenticatedRequest<
{},
{},
{},
{
nodeTypeAndVersion: string;
methodName: string;
path: string;
currentNodeParameters: string;
credentials: string;
}
>;
// ----------------------------------
// /node-list-search
// ----------------------------------
export type NodeListSearchRequest = AuthenticatedRequest<
{},
{},
{},
{
nodeTypeAndVersion: string;
methodName: string;
path: string;
currentNodeParameters: string;
credentials: string;
filter?: string;
paginationToken?: string;
}
>;
// ----------------------------------
// /tags
// ----------------------------------
export declare namespace TagsRequest {
type GetAll = AuthenticatedRequest<{}, {}, {}, { withUsageCount: string }>;
type Create = AuthenticatedRequest<{}, {}, { name: string }>;
type Update = AuthenticatedRequest<{ id: string }, {}, { name: string }>;
type Delete = AuthenticatedRequest<{ id: string }>;
}
// ----------------------------------
// /nodes
// ----------------------------------
export declare namespace NodeRequest {
type GetAll = AuthenticatedRequest;
type Post = AuthenticatedRequest<{}, {}, { name?: string }>;
type Delete = AuthenticatedRequest<{}, {}, {}, { name: string }>;
type Update = Post;
}
// ----------------------------------
// /curl-to-json
// ----------------------------------
export declare namespace CurlHelper {
type ToJson = AuthenticatedRequest<{}, {}, { curlCommand?: string }>;
}
// ----------------------------------
// /license
// ----------------------------------
export declare namespace LicenseRequest {
type Activate = AuthenticatedRequest<{}, {}, { activationKey: string }, {}>;
}
export type BinaryDataRequest = AuthenticatedRequest<
{ path: string },
{},
{},
{
mode: 'view' | 'download';
fileName?: string;
mimeType?: string;
}
>;
// ----------------------------------
// /variables
// ----------------------------------
//
export declare namespace VariablesRequest {
type CreateUpdatePayload = Omit<Variables, 'id'> & { id?: unknown };
type GetAll = AuthenticatedRequest;
type Get = AuthenticatedRequest<{ id: string }, {}, {}, {}>;
type Create = AuthenticatedRequest<{}, {}, CreateUpdatePayload, {}>;
type Update = AuthenticatedRequest<{ id: string }, {}, CreateUpdatePayload, {}>;
type Delete = Get;
}