Move CredentialSchema code to workflow package

This commit is contained in:
Elias Meire 2024-09-25 11:30:18 +02:00
parent 28e36e002d
commit df27da07dd
No known key found for this signature in database
6 changed files with 643 additions and 416 deletions

View file

@ -1,40 +1,49 @@
import type { ICredentialType } from 'n8n-workflow'; import type { ICredentialType } from "n8n-workflow";
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema'; import {
CredentialSchema,
type InferCredentialSchema,
} from "../utils/CredentialSchema";
export const strapiApiCredentialSchema = CredentialSchema.create({ export const strapiApiCredentialSchema = CredentialSchema.create({
notice: CredentialSchema.notice('Make sure you are using a user account not an admin account'), notice: CredentialSchema.notice(
email: CredentialSchema.email({ placeholder: 'name@email.com' }), "Make sure you are using a user account not an admin account",
),
email: CredentialSchema.email({ placeholder: "name@email.com" }),
password: CredentialSchema.password(), password: CredentialSchema.password(),
url: CredentialSchema.url({ url: CredentialSchema.url({
placeholder: 'https://api.example.com', placeholder: "https://api.example.com",
}), }),
apiVersion: CredentialSchema.options({ apiVersion: CredentialSchema.options({
label: 'API Version', label: "API Version",
description: 'The version of api to be used', description: "The version of api to be used",
options: [ options: [
{ {
label: 'Version 4', label: "Version 4",
value: 'v4', value: "v4",
description: 'API version supported by Strapi 4', description: "API version supported by Strapi 4",
}, },
{ {
label: 'Version 3', label: "Version 3",
value: 'v3', value: "v3",
default: true, default: true,
description: 'API version supported by Strapi 3', description: "API version supported by Strapi 3",
}, },
], ],
}), }),
}); });
export type StrapiApiCredential = InferCredentialSchema<typeof strapiApiCredentialSchema>; export type StrapiApiCredential = InferCredentialSchema<
typeof strapiApiCredentialSchema
>;
export class StrapiApi implements ICredentialType { export class StrapiApi implements ICredentialType {
name = 'strapiApi'; name = "strapiApi";
displayName = 'Strapi API'; displayName = "Strapi API";
documentationUrl = 'strapi'; documentationUrl = "strapi";
properties = strapiApiCredentialSchema.toNodeProperties(); properties = strapiApiCredentialSchema.toNodeProperties();
schema = strapiApiCredentialSchema;
} }

View file

@ -1,61 +1,60 @@
{ {
"name": "n8n-workflow", "name": "n8n-workflow",
"version": "1.56.0", "version": "1.56.0",
"description": "Workflow base code of n8n", "description": "Workflow base code of n8n",
"main": "dist/index.js", "main": "dist/index.js",
"module": "src/index.ts", "module": "src/index.ts",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"exports": { "exports": {
".": { ".": {
"require": "./dist/index.js", "require": "./dist/index.js",
"import": "./src/index.ts", "import": "./src/index.ts",
"types": "./dist/index.d.ts" "types": "./dist/index.d.ts"
}, },
"./*": "./*" "./*": "./*"
}, },
"scripts": { "scripts": {
"clean": "rimraf dist .turbo", "clean": "rimraf dist .turbo",
"dev": "pnpm watch", "dev": "pnpm watch",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"build": "tsc -p tsconfig.build.json", "build": "tsc -p tsconfig.build.json",
"format": "prettier --write . --ignore-path ../../.prettierignore", "format": "prettier --write . --ignore-path ../../.prettierignore",
"lint": "eslint . --quiet", "lint": "eslint . --quiet",
"lintfix": "eslint . --fix", "lintfix": "eslint . --fix",
"watch": "tsc -p tsconfig.build.json --watch", "watch": "tsc -p tsconfig.build.json --watch",
"test": "jest", "test": "jest",
"test:dev": "jest --watch" "test:dev": "jest --watch"
}, },
"files": [ "files": ["dist/**/*"],
"dist/**/*" "devDependencies": {
], "@langchain/core": "^0.2.18",
"devDependencies": { "@types/deep-equal": "^1.0.1",
"@langchain/core": "^0.2.18", "@types/express": "catalog:",
"@types/deep-equal": "^1.0.1", "@types/jmespath": "^0.15.0",
"@types/express": "catalog:", "@types/lodash": "catalog:",
"@types/jmespath": "^0.15.0", "@types/luxon": "^3.2.0",
"@types/lodash": "catalog:", "@types/md5": "^2.3.5",
"@types/luxon": "^3.2.0", "@types/xml2js": "catalog:"
"@types/md5": "^2.3.5", },
"@types/xml2js": "catalog:" "dependencies": {
}, "@n8n/tournament": "1.0.5",
"dependencies": { "@n8n_io/riot-tmpl": "4.0.0",
"@n8n/tournament": "1.0.5", "ast-types": "0.15.2",
"@n8n_io/riot-tmpl": "4.0.0", "axios": "catalog:",
"ast-types": "0.15.2", "callsites": "3.1.0",
"axios": "catalog:", "deep-equal": "2.2.0",
"callsites": "3.1.0", "esprima-next": "5.8.4",
"deep-equal": "2.2.0", "form-data": "catalog:",
"esprima-next": "5.8.4", "jmespath": "0.16.0",
"form-data": "catalog:", "js-base64": "3.7.2",
"jmespath": "0.16.0", "jssha": "3.3.1",
"js-base64": "3.7.2", "lodash": "catalog:",
"jssha": "3.3.1", "luxon": "catalog:",
"lodash": "catalog:", "md5": "2.3.0",
"luxon": "catalog:", "recast": "0.21.5",
"md5": "2.3.0", "title-case": "3.0.3",
"recast": "0.21.5", "transliteration": "2.3.5",
"title-case": "3.0.3", "xml2js": "catalog:",
"transliteration": "2.3.5", "zod": "catalog:"
"xml2js": "catalog:" }
}
} }

View file

@ -1,8 +1,8 @@
import type { INodeProperties } from 'n8n-workflow'; import z, { type ZodOptional, type ZodType } from "zod";
import z, { type ZodOptional, type ZodType } from 'zod'; import type { INodeProperties } from "@/Interfaces";
function isObject(value: unknown): value is object { function isObject(value: unknown): value is object {
return typeof value === 'object' && value !== null && !Array.isArray(value); return typeof value === "object" && value !== null && !Array.isArray(value);
} }
function removeUndefinedProperties<T extends object>(obj: T): T { function removeUndefinedProperties<T extends object>(obj: T): T {
@ -40,19 +40,25 @@ class CredentialSchemaRootObject<
); );
} }
getProperty<K extends keyof T>(key: K): T[K]['metadata'] { getProperty<K extends keyof T>(key: K): T[K]["metadata"] {
return this.shape[key].metadata; return this.shape[key].metadata;
} }
toNodeProperties() { toNodeProperties() {
return Object.entries(this.shape).map(([key, schema]) => schema.toNodeProperties(key)); return Object.entries(this.shape).map(([key, schema]) =>
schema.toNodeProperties(key),
);
} }
} }
type ToZodSchemaReturnType< type ToZodSchemaReturnType<
M extends BaseMetadata = BaseMetadata, M extends BaseMetadata = BaseMetadata,
S extends ZodType | null = ZodType, S extends ZodType | null = ZodType,
> = M['optional'] extends true ? (S extends null ? null : ZodOptional<NonNullable<S>>) : S; > = M["optional"] extends true
? S extends null
? null
: ZodOptional<NonNullable<S>>
: S;
abstract class CredentialSchemaProperty< abstract class CredentialSchemaProperty<
M extends BaseMetadata = BaseMetadata, M extends BaseMetadata = BaseMetadata,
@ -76,8 +82,8 @@ abstract class CredentialSchemaProperty<
name, name,
displayName: this.metadata.label, displayName: this.metadata.label,
description: this.metadata.description, description: this.metadata.description,
default: '', default: "",
type: 'string', type: "string",
}); });
} }
} }
@ -96,7 +102,7 @@ class CredentialSchemaString<
toNodeProperties(name: string): INodeProperties { toNodeProperties(name: string): INodeProperties {
return removeUndefinedProperties({ return removeUndefinedProperties({
...super.toNodeProperties(name), ...super.toNodeProperties(name),
type: 'string', type: "string",
placeholder: this.metadata.placeholder, placeholder: this.metadata.placeholder,
typeOptions: { password: this.metadata.password }, typeOptions: { password: this.metadata.password },
}); });
@ -117,7 +123,7 @@ class CredentialSchemaNumber<
toNodeProperties(name: string): INodeProperties { toNodeProperties(name: string): INodeProperties {
return removeUndefinedProperties({ return removeUndefinedProperties({
...super.toNodeProperties(name), ...super.toNodeProperties(name),
type: 'number', type: "number",
default: this.metadata.default, default: this.metadata.default,
}); });
} }
@ -139,18 +145,22 @@ class CredentialSchemaOptions<
const { options } = this.metadata; const { options } = this.metadata;
return removeUndefinedProperties({ return removeUndefinedProperties({
...super.toNodeProperties(name), ...super.toNodeProperties(name),
type: 'options', type: "options",
options: options.map((option) => ({ options: options.map((option) => ({
name: option.label, name: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
})), })),
default: options.find((option) => option.default)?.value ?? options[0].value, default:
options.find((option) => option.default)?.value ?? options[0].value,
}); });
} }
} }
class CredentialSchemaNotice extends CredentialSchemaProperty<BaseMetadata, null> { class CredentialSchemaNotice extends CredentialSchemaProperty<
BaseMetadata,
null
> {
constructor(public notice: string) { constructor(public notice: string) {
super({ label: notice }, null); super({ label: notice }, null);
} }
@ -158,7 +168,7 @@ class CredentialSchemaNotice extends CredentialSchemaProperty<BaseMetadata, null
toNodeProperties(name: string): INodeProperties { toNodeProperties(name: string): INodeProperties {
return { return {
...super.toNodeProperties(name), ...super.toNodeProperties(name),
type: 'notice', type: "notice",
}; };
} }
} }
@ -190,24 +200,26 @@ type Option<V extends string> = {
}; };
type NonEmptyArray<T> = [T, ...T[]]; type NonEmptyArray<T> = [T, ...T[]];
type OptionsMetadata<V extends string> = BaseMetadata & { options: NonEmptyArray<Option<V>> }; type OptionsMetadata<V extends string> = BaseMetadata & {
options: NonEmptyArray<Option<V>>;
};
type Zodify< type Zodify<
M extends BaseMetadata, M extends BaseMetadata,
S extends ZodType | null, S extends ZodType | null,
T extends CredentialSchemaProperty<M, S>, T extends CredentialSchemaProperty<M, S>,
> = ReturnType<T['toZodSchema']> extends z.ZodType ? ReturnType<T['toZodSchema']> : never; > = ReturnType<T["toZodSchema"]> extends z.ZodType
? ReturnType<T["toZodSchema"]>
: never;
type ZodifyObject< type ZodifyObject<
M extends BaseMetadata, M extends BaseMetadata,
S extends ZodType | null, S extends ZodType | null,
T extends { [k: string]: CredentialSchemaProperty<M, S> }, T extends { [k: string]: CredentialSchemaProperty<M, S> },
> = { > = {
[K in keyof T as ReturnType<T[K]['toZodSchema']> extends z.ZodType ? K : never]: Zodify< [K in keyof T as ReturnType<T[K]["toZodSchema"]> extends z.ZodType
M, ? K
S, : never]: Zodify<M, S, T[K]>;
T[K]
>;
}; };
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
@ -221,11 +233,11 @@ export const CredentialSchema = {
return new CredentialSchemaRootObject(shape); return new CredentialSchemaRootObject(shape);
}, },
password(options: Omit<Optional<StringMetadata, 'label'>, 'password'> = {}) { password(options: Omit<Optional<StringMetadata, "label">, "password"> = {}) {
return new CredentialSchemaString( return new CredentialSchemaString(
{ {
password: true, password: true,
label: 'Password', label: "Password",
...options, ...options,
}, },
z.string(), z.string(),
@ -239,18 +251,24 @@ export const CredentialSchema = {
number<M extends NumberMetadata>(options: M) { number<M extends NumberMetadata>(options: M) {
return new CredentialSchemaNumber(options, z.number()); return new CredentialSchemaNumber(options, z.number());
}, },
url(options: Optional<StringMetadata, 'label'> = {}) { url(options: Optional<StringMetadata, "label"> = {}) {
return new CredentialSchemaString({ label: 'URL', ...options }, z.string().url()); return new CredentialSchemaString(
{ label: "URL", ...options },
z.string().url(),
);
}, },
email(options: Optional<StringMetadata, 'label'> = {}) { email(options: Optional<StringMetadata, "label"> = {}) {
return new CredentialSchemaString({ label: 'Email', ...options }, z.string().email()); return new CredentialSchemaString(
{ label: "Email", ...options },
z.string().email(),
);
}, },
options<V extends string, M extends OptionsMetadata<V>>(options: M) { options<V extends string, M extends OptionsMetadata<V>>(options: M) {
return new CredentialSchemaOptions( return new CredentialSchemaOptions(
options, options,
z.enum( z.enum(
options.options.map((option) => option.value) as NonEmptyArray< options.options.map((option) => option.value) as NonEmptyArray<
M['options'][number]['value'] M["options"][number]["value"]
>, >,
), ),
); );
@ -260,6 +278,11 @@ export const CredentialSchema = {
}, },
}; };
export type InferCredentialSchema< export type TCredentialSchema = CredentialSchemaRootObject<
T extends CredentialSchemaRootObject<BaseMetadata, ZodType | null>, BaseMetadata,
> = z.infer<ReturnType<T['toZodSchema']>>; ZodType | null
>;
export type InferCredentialSchema<T extends TCredentialSchema> = z.infer<
ReturnType<T["toZodSchema"]>
>;

File diff suppressed because it is too large Load diff

View file

@ -1,27 +1,27 @@
import * as LoggerProxy from './LoggerProxy'; import * as LoggerProxy from "./LoggerProxy";
export * as ErrorReporterProxy from './ErrorReporterProxy'; export * as ErrorReporterProxy from "./ErrorReporterProxy";
export * as ExpressionEvaluatorProxy from './ExpressionEvaluatorProxy'; export * as ExpressionEvaluatorProxy from "./ExpressionEvaluatorProxy";
import * as NodeHelpers from './NodeHelpers'; import * as NodeHelpers from "./NodeHelpers";
import * as ObservableObject from './ObservableObject'; import * as ObservableObject from "./ObservableObject";
import * as TelemetryHelpers from './TelemetryHelpers'; import * as TelemetryHelpers from "./TelemetryHelpers";
export * from './errors'; export * from "./errors";
export * from './Authentication'; export * from "./Authentication";
export * from './Constants'; export * from "./Constants";
export * from './Cron'; export * from "./Cron";
export * from './DeferredPromise'; export * from "./DeferredPromise";
export * from './GlobalState'; export * from "./GlobalState";
export * from './Interfaces'; export * from "./Interfaces";
export * from './MessageEventBus'; export * from "./MessageEventBus";
export * from './ExecutionStatus'; export * from "./ExecutionStatus";
export * from './Expression'; export * from "./Expression";
export * from './NodeHelpers'; export * from "./NodeHelpers";
export * from './RoutingNode'; export * from "./RoutingNode";
export * from './Workflow'; export * from "./Workflow";
export * from './WorkflowDataProxy'; export * from "./WorkflowDataProxy";
export * from './WorkflowHooks'; export * from "./WorkflowHooks";
export * from './VersionedNodeType'; export * from "./VersionedNodeType";
export * from './TypeValidation'; export * from "./TypeValidation";
export { LoggerProxy, NodeHelpers, ObservableObject, TelemetryHelpers }; export { LoggerProxy, NodeHelpers, ObservableObject, TelemetryHelpers };
export { export {
isObjectEmpty, isObjectEmpty,
@ -36,7 +36,7 @@ export {
updateDisplayOptions, updateDisplayOptions,
randomInt, randomInt,
randomString, randomString,
} from './utils'; } from "./utils";
export { export {
isINodeProperties, isINodeProperties,
isINodePropertyOptions, isINodePropertyOptions,
@ -46,12 +46,16 @@ export {
isINodePropertyOptionsList, isINodePropertyOptionsList,
isResourceMapperValue, isResourceMapperValue,
isFilterValue, isFilterValue,
} from './type-guards'; } from "./type-guards";
export { ExpressionExtensions } from './Extensions'; export { ExpressionExtensions } from "./Extensions";
export * as ExpressionParser from './Extensions/ExpressionParser'; export * as ExpressionParser from "./Extensions/ExpressionParser";
export { NativeMethods } from './NativeMethods'; export { NativeMethods } from "./NativeMethods";
export * from './NodeParameters/FilterParameter'; export * from "./NodeParameters/FilterParameter";
export {
CredentialSchema,
InferCredentialSchema,
} from "./CredentialSchema/CredentialSchema";
export type { export type {
DocMetadata, DocMetadata,
@ -59,9 +63,9 @@ export type {
DocMetadataArgument, DocMetadataArgument,
DocMetadataExample, DocMetadataExample,
Extension, Extension,
} from './Extensions'; } from "./Extensions";
declare module 'http' { declare module "http" {
export interface IncomingMessage { export interface IncomingMessage {
contentType?: string; contentType?: string;
encoding: BufferEncoding; encoding: BufferEncoding;