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

@ -25,9 +25,7 @@
"test": "jest", "test": "jest",
"test:dev": "jest --watch" "test:dev": "jest --watch"
}, },
"files": [ "files": ["dist/**/*"],
"dist/**/*"
],
"devDependencies": { "devDependencies": {
"@langchain/core": "^0.2.18", "@langchain/core": "^0.2.18",
"@types/deep-equal": "^1.0.1", "@types/deep-equal": "^1.0.1",
@ -56,6 +54,7 @@
"recast": "0.21.5", "recast": "0.21.5",
"title-case": "3.0.3", "title-case": "3.0.3",
"transliteration": "2.3.5", "transliteration": "2.3.5",
"xml2js": "catalog:" "xml2js": "catalog:",
"zod": "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;