Change getCredentials type inference

This commit is contained in:
Elias Meire 2024-09-25 12:01:38 +02:00
parent 2d8b62f316
commit 14752bbf1c
No known key found for this signature in database
14 changed files with 263 additions and 319 deletions

View file

@ -0,0 +1,54 @@
// vite.config.mts
import { defineConfig } from "file:///Users/elias/projects/github/n8n-io/n8n/node_modules/.pnpm/vite@5.4.6_@types+node@18.16.16_sass@1.64.1_terser@5.16.1/node_modules/vite/dist/node/index.js";
import { resolve } from "path";
import vue from "file:///Users/elias/projects/github/n8n-io/n8n/node_modules/.pnpm/@vitejs+plugin-vue@5.1.4_vite@5.4.6_@types+node@18.16.16_sass@1.64.1_terser@5.16.1__vue@3.4.21_typescript@5.6.2_/node_modules/@vitejs/plugin-vue/dist/index.mjs";
import icons from "file:///Users/elias/projects/github/n8n-io/n8n/node_modules/.pnpm/unplugin-icons@0.19.0_@vue+compiler-sfc@3.4.21_vue-template-compiler@2.7.14/node_modules/unplugin-icons/dist/vite.js";
import dts from "file:///Users/elias/projects/github/n8n-io/n8n/node_modules/.pnpm/vite-plugin-dts@3.9.1_@types+node@18.16.16_rollup@4.22.2_typescript@5.6.2_vite@5.4.6_@types+n_rcaikbew5ptk64olpe4bf2iruu/node_modules/vite-plugin-dts/dist/index.mjs";
var __vite_injected_original_dirname = "/Users/elias/projects/github/n8n-io/n8n/packages/@n8n/chat";
var includeVue = process.env.INCLUDE_VUE === "true";
var srcPath = resolve(__vite_injected_original_dirname, "src");
var vite_config_default = defineConfig({
plugins: [
vue(),
icons({
compiler: "vue3",
autoInstall: true
}),
dts()
],
resolve: {
alias: {
"@": srcPath,
"@n8n/chat": srcPath,
lodash: "lodash-es"
}
},
define: {
"process.env.NODE_ENV": process.env.NODE_ENV ? `"${process.env.NODE_ENV}"` : '"development"'
},
build: {
emptyOutDir: !includeVue,
lib: {
entry: resolve(__vite_injected_original_dirname, "src", "index.ts"),
name: "N8nChat",
fileName: (format) => includeVue ? `chat.bundle.${format}.js` : `chat.${format}.js`
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: includeVue ? [] : ["vue"],
output: {
exports: "named",
// Provide global variables to use in the UMD build
// for externalized deps
globals: includeVue ? {} : {
vue: "Vue"
}
}
}
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcubXRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL2VsaWFzL3Byb2plY3RzL2dpdGh1Yi9uOG4taW8vbjhuL3BhY2thZ2VzL0BuOG4vY2hhdFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL2VsaWFzL3Byb2plY3RzL2dpdGh1Yi9uOG4taW8vbjhuL3BhY2thZ2VzL0BuOG4vY2hhdC92aXRlLmNvbmZpZy5tdHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL1VzZXJzL2VsaWFzL3Byb2plY3RzL2dpdGh1Yi9uOG4taW8vbjhuL3BhY2thZ2VzL0BuOG4vY2hhdC92aXRlLmNvbmZpZy5tdHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJztcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB2dWUgZnJvbSAnQHZpdGVqcy9wbHVnaW4tdnVlJztcbmltcG9ydCBpY29ucyBmcm9tICd1bnBsdWdpbi1pY29ucy92aXRlJztcbmltcG9ydCBkdHMgZnJvbSAndml0ZS1wbHVnaW4tZHRzJztcblxuY29uc3QgaW5jbHVkZVZ1ZSA9IHByb2Nlc3MuZW52LklOQ0xVREVfVlVFID09PSAndHJ1ZSc7XG5jb25zdCBzcmNQYXRoID0gcmVzb2x2ZShfX2Rpcm5hbWUsICdzcmMnKTtcblxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG5cdHBsdWdpbnM6IFtcblx0XHR2dWUoKSxcblx0XHRpY29ucyh7XG5cdFx0XHRjb21waWxlcjogJ3Z1ZTMnLFxuXHRcdFx0YXV0b0luc3RhbGw6IHRydWUsXG5cdFx0fSksXG5cdFx0ZHRzKCksXG5cdF0sXG5cdHJlc29sdmU6IHtcblx0XHRhbGlhczoge1xuXHRcdFx0J0AnOiBzcmNQYXRoLFxuXHRcdFx0J0BuOG4vY2hhdCc6IHNyY1BhdGgsXG5cdFx0XHRsb2Rhc2g6ICdsb2Rhc2gtZXMnLFxuXHRcdH0sXG5cdH0sXG5cdGRlZmluZToge1xuXHRcdCdwcm9jZXNzLmVudi5OT0RFX0VOVic6IHByb2Nlc3MuZW52Lk5PREVfRU5WID8gYFwiJHtwcm9jZXNzLmVudi5OT0RFX0VOVn1cImAgOiAnXCJkZXZlbG9wbWVudFwiJyxcblx0fSxcblx0YnVpbGQ6IHtcblx0XHRlbXB0eU91dERpcjogIWluY2x1ZGVWdWUsXG5cdFx0bGliOiB7XG5cdFx0XHRlbnRyeTogcmVzb2x2ZShfX2Rpcm5hbWUsICdzcmMnLCAnaW5kZXgudHMnKSxcblx0XHRcdG5hbWU6ICdOOG5DaGF0Jyxcblx0XHRcdGZpbGVOYW1lOiAoZm9ybWF0KSA9PiAoaW5jbHVkZVZ1ZSA/IGBjaGF0LmJ1bmRsZS4ke2Zvcm1hdH0uanNgIDogYGNoYXQuJHtmb3JtYXR9LmpzYCksXG5cdFx0fSxcblx0XHRyb2xsdXBPcHRpb25zOiB7XG5cdFx0XHQvLyBtYWtlIHN1cmUgdG8gZXh0ZXJuYWxpemUgZGVwcyB0aGF0IHNob3VsZG4ndCBiZSBidW5kbGVkXG5cdFx0XHQvLyBpbnRvIHlvdXIgbGlicmFyeVxuXHRcdFx0ZXh0ZXJuYWw6IGluY2x1ZGVWdWUgPyBbXSA6IFsndnVlJ10sXG5cdFx0XHRvdXRwdXQ6IHtcblx0XHRcdFx0ZXhwb3J0czogJ25hbWVkJyxcblx0XHRcdFx0Ly8gUHJvdmlkZSBnbG9iYWwgdmFyaWFibGVzIHRvIHVzZSBpbiB0aGUgVU1EIGJ1aWxkXG5cdFx0XHRcdC8vIGZvciBleHRlcm5hbGl6ZWQgZGVwc1xuXHRcdFx0XHRnbG9iYWxzOiBpbmNsdWRlVnVlXG5cdFx0XHRcdFx0PyB7fVxuXHRcdFx0XHRcdDoge1xuXHRcdFx0XHRcdFx0XHR2dWU6ICdWdWUnLFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdH0sXG5cdFx0fSxcblx0fSxcbn0pO1xuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFrVyxTQUFTLG9CQUFvQjtBQUMvWCxTQUFTLGVBQWU7QUFDeEIsT0FBTyxTQUFTO0FBQ2hCLE9BQU8sV0FBVztBQUNsQixPQUFPLFNBQVM7QUFKaEIsSUFBTSxtQ0FBbUM7QUFNekMsSUFBTSxhQUFhLFFBQVEsSUFBSSxnQkFBZ0I7QUFDL0MsSUFBTSxVQUFVLFFBQVEsa0NBQVcsS0FBSztBQUd4QyxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMzQixTQUFTO0FBQUEsSUFDUixJQUFJO0FBQUEsSUFDSixNQUFNO0FBQUEsTUFDTCxVQUFVO0FBQUEsTUFDVixhQUFhO0FBQUEsSUFDZCxDQUFDO0FBQUEsSUFDRCxJQUFJO0FBQUEsRUFDTDtBQUFBLEVBQ0EsU0FBUztBQUFBLElBQ1IsT0FBTztBQUFBLE1BQ04sS0FBSztBQUFBLE1BQ0wsYUFBYTtBQUFBLE1BQ2IsUUFBUTtBQUFBLElBQ1Q7QUFBQSxFQUNEO0FBQUEsRUFDQSxRQUFRO0FBQUEsSUFDUCx3QkFBd0IsUUFBUSxJQUFJLFdBQVcsSUFBSSxRQUFRLElBQUksUUFBUSxNQUFNO0FBQUEsRUFDOUU7QUFBQSxFQUNBLE9BQU87QUFBQSxJQUNOLGFBQWEsQ0FBQztBQUFBLElBQ2QsS0FBSztBQUFBLE1BQ0osT0FBTyxRQUFRLGtDQUFXLE9BQU8sVUFBVTtBQUFBLE1BQzNDLE1BQU07QUFBQSxNQUNOLFVBQVUsQ0FBQyxXQUFZLGFBQWEsZUFBZSxNQUFNLFFBQVEsUUFBUSxNQUFNO0FBQUEsSUFDaEY7QUFBQSxJQUNBLGVBQWU7QUFBQTtBQUFBO0FBQUEsTUFHZCxVQUFVLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSztBQUFBLE1BQ2xDLFFBQVE7QUFBQSxRQUNQLFNBQVM7QUFBQTtBQUFBO0FBQUEsUUFHVCxTQUFTLGFBQ04sQ0FBQyxJQUNEO0FBQUEsVUFDQSxLQUFLO0FBQUEsUUFDTjtBQUFBLE1BQ0g7QUFBQSxJQUNEO0FBQUEsRUFDRDtBQUNELENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==

View file

@ -102,6 +102,7 @@ import type {
SSHTunnelFunctions, SSHTunnelFunctions,
SchedulingFunctions, SchedulingFunctions,
AiEvent, AiEvent,
ICredentialType,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
NodeConnectionType, NodeConnectionType,
@ -1995,7 +1996,7 @@ export function getAdditionalKeys(
export async function getCredentials<T extends object = ICredentialDataDecryptedObject>( export async function getCredentials<T extends object = ICredentialDataDecryptedObject>(
workflow: Workflow, workflow: Workflow,
node: INode, node: INode,
type: string, credType: string | (new () => ICredentialType),
additionalData: IWorkflowExecuteAdditionalData, additionalData: IWorkflowExecuteAdditionalData,
mode: WorkflowExecuteMode, mode: WorkflowExecuteMode,
executeData?: IExecuteData, executeData?: IExecuteData,
@ -2004,6 +2005,7 @@ export async function getCredentials<T extends object = ICredentialDataDecrypted
connectionInputData?: INodeExecutionData[], connectionInputData?: INodeExecutionData[],
itemIndex?: number, itemIndex?: number,
): Promise<T> { ): Promise<T> {
const type = typeof credType === 'string' ? credType : credType.name;
// Get the NodeType as it has the information if the credentials are required // Get the NodeType as it has the information if the credentials are required
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
if (nodeType === undefined) { if (nodeType === undefined) {
@ -3496,8 +3498,10 @@ export function getExecutePollFunctions(
}, },
getMode: () => mode, getMode: () => mode,
getActivationMode: () => activation, getActivationMode: () => activation,
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) => {
await getCredentials(workflow, node, type, additionalData, mode), const typeString = typeof type === 'string' ? type : type.name;
return await getCredentials(workflow, node, typeString, additionalData, mode);
},
getNodeParameter: ( getNodeParameter: (
parameterName: string, parameterName: string,
fallbackValue?: any, fallbackValue?: any,
@ -3560,7 +3564,7 @@ export function getExecuteTriggerFunctions(
}, },
getMode: () => mode, getMode: () => mode,
getActivationMode: () => activation, getActivationMode: () => activation,
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) =>
await getCredentials(workflow, node, type, additionalData, mode), await getCredentials(workflow, node, type, additionalData, mode),
getNodeParameter: ( getNodeParameter: (
parameterName: string, parameterName: string,
@ -3620,7 +3624,7 @@ export function getExecuteFunctions(
...getCommonWorkflowFunctions(workflow, node, additionalData), ...getCommonWorkflowFunctions(workflow, node, additionalData),
...executionCancellationFunctions(abortSignal), ...executionCancellationFunctions(abortSignal),
getMode: () => mode, getMode: () => mode,
getCredentials: async (type, itemIndex) => getCredentials: async (type: string | (new () => ICredentialType), itemIndex: number) =>
await getCredentials( await getCredentials(
workflow, workflow,
node, node,
@ -3948,7 +3952,7 @@ export function getExecuteSingleFunctions(
getContext(type: ContextType): IContextObject { getContext(type: ContextType): IContextObject {
return NodeHelpers.getContext(runExecutionData, type, node); return NodeHelpers.getContext(runExecutionData, type, node);
}, },
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) =>
await getCredentials( await getCredentials(
workflow, workflow,
node, node,
@ -4088,7 +4092,7 @@ export function getLoadOptionsFunctions(
return ((workflow: Workflow, node: INode, path: string) => { return ((workflow: Workflow, node: INode, path: string) => {
return { return {
...getCommonWorkflowFunctions(workflow, node, additionalData), ...getCommonWorkflowFunctions(workflow, node, additionalData),
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) =>
await getCredentials(workflow, node, type, additionalData, 'internal'), await getCredentials(workflow, node, type, additionalData, 'internal'),
getCurrentNodeParameter: ( getCurrentNodeParameter: (
parameterPath: string, parameterPath: string,
@ -4169,7 +4173,7 @@ export function getExecuteHookFunctions(
return ((workflow: Workflow, node: INode) => { return ((workflow: Workflow, node: INode) => {
return { return {
...getCommonWorkflowFunctions(workflow, node, additionalData), ...getCommonWorkflowFunctions(workflow, node, additionalData),
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) =>
await getCredentials(workflow, node, type, additionalData, mode), await getCredentials(workflow, node, type, additionalData, mode),
getMode: () => mode, getMode: () => mode,
getActivationMode: () => activation, getActivationMode: () => activation,
@ -4243,7 +4247,7 @@ export function getExecuteWebhookFunctions(
} }
return additionalData.httpRequest.body; return additionalData.httpRequest.body;
}, },
getCredentials: async (type) => getCredentials: async (type: string | (new () => ICredentialType)) =>
await getCredentials(workflow, node, type, additionalData, mode), await getCredentials(workflow, node, type, additionalData, mode),
getHeaderData(): IncomingHttpHeaders { getHeaderData(): IncomingHttpHeaders {
if (additionalData.httpRequest === undefined) { if (additionalData.httpRequest === undefined) {

View file

@ -1,14 +1,4 @@
import type { ICredentialType } from 'n8n-workflow'; import type { ICredentialType, INodeProperties } from 'n8n-workflow';
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema';
const ftpCredentialSchema = CredentialSchema.create({
host: CredentialSchema.string({ label: 'Host', placeholder: 'localhost' }),
port: CredentialSchema.number({ label: 'Port', default: 21 }),
username: CredentialSchema.string({ label: 'Username', optional: true }),
password: CredentialSchema.password({ optional: true }),
});
export type FtpCredentialSchema = InferCredentialSchema<typeof ftpCredentialSchema>;
export class Ftp implements ICredentialType { export class Ftp implements ICredentialType {
name = 'ftp'; name = 'ftp';
@ -17,5 +7,36 @@ export class Ftp implements ICredentialType {
documentationUrl = 'ftp'; documentationUrl = 'ftp';
properties = ftpCredentialSchema.toNodeProperties(); properties: INodeProperties[] = [
{
displayName: 'Host',
name: 'host',
required: true,
type: 'string',
default: '',
placeholder: 'localhost',
},
{
displayName: 'Port',
name: 'port',
required: true,
type: 'number',
default: 21,
},
{
displayName: 'Username',
name: 'username',
type: 'string',
default: '',
},
{
displayName: 'Password',
name: 'password',
type: 'string',
typeOptions: {
password: true,
},
default: '',
},
];
} }

View file

@ -1,23 +1,4 @@
import type { ICredentialType } from 'n8n-workflow'; import type { ICredentialType, INodeProperties } from 'n8n-workflow';
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema';
const sftpCredentialSchema = CredentialSchema.create({
host: CredentialSchema.string({ label: 'Host', placeholder: 'localhost' }),
port: CredentialSchema.number({ label: 'Port', default: 22 }),
username: CredentialSchema.string({ label: 'Username' }),
password: CredentialSchema.password(),
privateKey: CredentialSchema.password({
label: 'Private Key',
description:
'String that contains a private key for either key-based or hostbased user authentication (OpenSSH format)',
}),
passphrase: CredentialSchema.password({
label: 'Passphrase',
description: 'For an encrypted private key, this is the passphrase used to decrypt it',
}),
});
export type SftpCredentialSchema = InferCredentialSchema<typeof sftpCredentialSchema>;
export class Sftp implements ICredentialType { export class Sftp implements ICredentialType {
name = 'sftp'; name = 'sftp';
@ -26,5 +7,55 @@ export class Sftp implements ICredentialType {
documentationUrl = 'ftp'; documentationUrl = 'ftp';
properties = sftpCredentialSchema.toNodeProperties(); properties: INodeProperties[] = [
{
displayName: 'Host',
name: 'host',
required: true,
type: 'string',
default: '',
},
{
displayName: 'Port',
name: 'port',
required: true,
type: 'number',
default: 22,
},
{
displayName: 'Username',
name: 'username',
required: true,
type: 'string',
default: '',
},
{
displayName: 'Password',
name: 'password',
type: 'string',
typeOptions: {
password: true,
},
default: '',
},
{
displayName: 'Private Key',
name: 'privateKey',
type: 'string',
typeOptions: { password: true },
default: '',
description:
'String that contains a private key for either key-based or hostbased user authentication (OpenSSH format)',
},
{
displayName: 'Passphrase',
name: 'passphrase',
typeOptions: {
password: true,
},
type: 'string',
default: '',
description: 'For an encrypted private key, this is the passphrase used to decrypt it',
},
];
} }

View file

@ -1,47 +1,39 @@
import type { ICredentialType } from "n8n-workflow"; import { type ICredentialType, CredentialSchema, type InferCredentialSchema } from 'n8n-workflow';
import {
CredentialSchema,
type InferCredentialSchema,
} from "../utils/CredentialSchema";
export const strapiApiCredentialSchema = CredentialSchema.create({ export const strapiApiCredentialSchema = CredentialSchema.create({
notice: CredentialSchema.notice( notice: CredentialSchema.notice('Make sure you are using a user account not an admin account'),
"Make sure you are using a user account not an admin account", email: CredentialSchema.email({ placeholder: 'name@email.com' }),
),
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< export type StrapiApiCredential = InferCredentialSchema<typeof strapiApiCredentialSchema>;
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();

View file

@ -1,7 +1,11 @@
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType } from 'n8n-workflow'; import {
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema'; CredentialSchema,
type ICredentialType,
type IAuthenticateGeneric,
type ICredentialTestRequest,
} from 'n8n-workflow';
export const strapiTokenApiCredential = CredentialSchema.create({ const strapiTokenApiCredentialSchema = CredentialSchema.create({
apiToken: CredentialSchema.password({ label: 'API Token' }), apiToken: CredentialSchema.password({ label: 'API Token' }),
url: CredentialSchema.url({ placeholder: 'https://api.example.com' }), url: CredentialSchema.url({ placeholder: 'https://api.example.com' }),
apiVersion: CredentialSchema.options({ apiVersion: CredentialSchema.options({
@ -23,8 +27,6 @@ export const strapiTokenApiCredential = CredentialSchema.create({
}), }),
}); });
export type StrapiTokenApiCredential = InferCredentialSchema<typeof strapiTokenApiCredential>;
export class StrapiTokenApi implements ICredentialType { export class StrapiTokenApi implements ICredentialType {
name = 'strapiTokenApi'; name = 'strapiTokenApi';
@ -32,7 +34,9 @@ export class StrapiTokenApi implements ICredentialType {
documentationUrl = 'strapi'; documentationUrl = 'strapi';
properties = strapiTokenApiCredential.toNodeProperties(); properties = strapiTokenApiCredentialSchema.toNodeProperties();
schema = strapiTokenApiCredentialSchema;
authenticate: IAuthenticateGeneric = { authenticate: IAuthenticateGeneric = {
type: 'generic', type: 'generic',

View file

@ -7,6 +7,7 @@ import ftpClient from 'promise-ftp';
import sftpClient from 'ssh2-sftp-client'; import sftpClient from 'ssh2-sftp-client';
import { BINARY_ENCODING, NodeApiError, NodeConnectionType } from 'n8n-workflow'; import { BINARY_ENCODING, NodeApiError, NodeConnectionType } from 'n8n-workflow';
import type { import type {
ICredentialDataDecryptedObject,
ICredentialsDecrypted, ICredentialsDecrypted,
ICredentialTestFunctions, ICredentialTestFunctions,
IDataObject, IDataObject,
@ -17,8 +18,6 @@ import type {
INodeTypeDescription, INodeTypeDescription,
JsonObject, JsonObject,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { FtpCredentialSchema } from '@credentials/Ftp.credentials';
import type { SftpCredentialSchema } from '@credentials/Sftp.credentials';
import { formatPrivateKey, generatePairedItemData } from '@utils/utilities'; import { formatPrivateKey, generatePairedItemData } from '@utils/utilities';
interface ReturnFtpItem { interface ReturnFtpItem {
@ -440,14 +439,14 @@ export class Ftp implements INodeType {
this: ICredentialTestFunctions, this: ICredentialTestFunctions,
credential: ICredentialsDecrypted, credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> { ): Promise<INodeCredentialTestResult> {
const credentials = credential.data as FtpCredentialSchema; const credentials = credential.data as ICredentialDataDecryptedObject;
const ftp = new ftpClient(); const ftp = new ftpClient();
try { try {
await ftp.connect({ await ftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
user: credentials.username, user: credentials.username as string,
password: credentials.password, password: credentials.password as string,
}); });
} catch (error) { } catch (error) {
await ftp.end(); await ftp.end();
@ -466,24 +465,24 @@ export class Ftp implements INodeType {
this: ICredentialTestFunctions, this: ICredentialTestFunctions,
credential: ICredentialsDecrypted, credential: ICredentialsDecrypted,
): Promise<INodeCredentialTestResult> { ): Promise<INodeCredentialTestResult> {
const credentials = credential.data as SftpCredentialSchema; const credentials = credential.data as ICredentialDataDecryptedObject;
const sftp = new sftpClient(); const sftp = new sftpClient();
try { try {
if (credentials.privateKey) { if (credentials.privateKey) {
await sftp.connect({ await sftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
username: credentials.username, username: credentials.username as string,
password: credentials.password || undefined, password: (credentials.password as string) || undefined,
privateKey: formatPrivateKey(credentials.privateKey), privateKey: formatPrivateKey(credentials.privateKey as string),
passphrase: credentials.passphrase, passphrase: credentials.passphrase as string | undefined,
}); });
} else { } else {
await sftp.connect({ await sftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
username: credentials.username, username: credentials.username as string,
password: credentials.password, password: credentials.password as string,
}); });
} }
} catch (error) { } catch (error) {
@ -507,9 +506,14 @@ export class Ftp implements INodeType {
let returnItems: INodeExecutionData[] = []; let returnItems: INodeExecutionData[] = [];
const operation = this.getNodeParameter('operation', 0); const operation = this.getNodeParameter('operation', 0);
let credentials: ICredentialDataDecryptedObject | undefined = undefined;
const protocol = this.getNodeParameter('protocol', 0) as string; const protocol = this.getNodeParameter('protocol', 0) as string;
const credentials = await this.getCredentials(protocol === 'sftp' ? 'sftp' : 'ftp');
if (protocol === 'sftp') {
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('sftp');
} else {
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('ftp');
}
let ftp: ftpClient; let ftp: ftpClient;
let sftp: sftpClient; let sftp: sftpClient;
@ -517,30 +521,30 @@ export class Ftp implements INodeType {
try { try {
if (protocol === 'sftp') { if (protocol === 'sftp') {
sftp = new sftpClient(); sftp = new sftpClient();
if ('privateKey' in credentials && credentials.privateKey) { if (credentials.privateKey) {
await sftp.connect({ await sftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
username: credentials.username, username: credentials.username as string,
password: credentials.password || undefined, password: (credentials.password as string) || undefined,
privateKey: formatPrivateKey(credentials.privateKey), privateKey: formatPrivateKey(credentials.privateKey as string),
passphrase: credentials.passphrase, passphrase: credentials.passphrase as string | undefined,
}); });
} else { } else {
await sftp.connect({ await sftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
username: credentials.username, username: credentials.username as string,
password: credentials.password, password: credentials.password as string,
}); });
} }
} else { } else {
ftp = new ftpClient(); ftp = new ftpClient();
await ftp.connect({ await ftp.connect({
host: credentials.host, host: credentials.host as string,
port: credentials.port, port: credentials.port as number,
user: credentials.username, user: credentials.username as string,
password: credentials.password, password: credentials.password as string,
}); });
} }
} catch (error) { } catch (error) {

View file

@ -1,8 +1,8 @@
import type { import type {
IExecuteFunctions,
ICredentialsDecrypted, ICredentialsDecrypted,
ICredentialTestFunctions, ICredentialTestFunctions,
IDataObject, IDataObject,
IExecuteFunctions,
INodeCredentialTestResult, INodeCredentialTestResult,
INodeExecutionData, INodeExecutionData,
INodeType, INodeType,
@ -19,8 +19,9 @@ import {
validateJSON, validateJSON,
} from './GenericFunctions'; } from './GenericFunctions';
import { StrapiApi, type StrapiApiCredential } from '@credentials/StrapiApi.credentials';
import { StrapiTokenApi } from '../../credentials/StrapiTokenApi.credentials';
import { entryFields, entryOperations } from './EntryDescription'; import { entryFields, entryOperations } from './EntryDescription';
import type { StrapiApiCredential } from '@credentials/StrapiApi.credentials';
export class Strapi implements INodeType { export class Strapi implements INodeType {
description: INodeTypeDescription = { description: INodeTypeDescription = {
@ -148,10 +149,10 @@ export class Strapi implements INodeType {
if (authenticationMethod === 'password') { if (authenticationMethod === 'password') {
const { jwt } = await getToken.call(this); const { jwt } = await getToken.call(this);
apiVersion = (await this.getCredentials('strapiApi')).apiVersion; apiVersion = (await this.getCredentials(StrapiApi)).apiVersion;
headers.Authorization = `Bearer ${jwt}`; headers.Authorization = `Bearer ${jwt}`;
} else { } else {
apiVersion = (await this.getCredentials('strapiTokenApi')).apiVersion; apiVersion = (await this.getCredentials(StrapiTokenApi)).apiVersion;
} }
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {

View file

@ -1,24 +0,0 @@
import type { FtpCredentialSchema } from './credentials/Ftp.credentials';
import type { SftpCredentialSchema } from './credentials/Sftp.credentials';
import type { StrapiApiCredential } from './credentials/StrapiApi.credentials';
import type { StrapiTokenApiCredential } from './credentials/StrapiTokenApi.credentials';
type CredentialSchemaMap = {
strapiApi: StrapiApiCredential;
strapiTokenApi: StrapiTokenApiCredential;
ftp: FtpCredentialSchema;
sftp: SftpCredentialSchema;
};
declare module 'n8n-workflow' {
interface FunctionsBase {
getCredentials<Type extends keyof CredentialSchemaMap | {}>(
type: Type,
itemIndex?: number,
): Promise<
Type extends keyof CredentialSchemaMap
? CredentialSchemaMap[Type]
: ICredentialDataDecryptedObject
>;
}
}

View file

@ -1,8 +1,9 @@
import z, { type ZodOptional, type ZodType } from "zod"; import z, { type ZodOptional, type ZodType } from 'zod';
import type { INodeProperties } from "@/Interfaces";
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,25 +41,19 @@ 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]) => return Object.entries(this.shape).map(([key, schema]) => schema.toNodeProperties(key));
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 > = M['optional'] extends true ? (S extends null ? null : ZodOptional<NonNullable<S>>) : S;
? S extends null
? null
: ZodOptional<NonNullable<S>>
: S;
abstract class CredentialSchemaProperty< abstract class CredentialSchemaProperty<
M extends BaseMetadata = BaseMetadata, M extends BaseMetadata = BaseMetadata,
@ -82,8 +77,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',
}); });
} }
} }
@ -102,7 +97,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 },
}); });
@ -123,7 +118,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,
}); });
} }
@ -145,22 +140,18 @@ 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: default: options.find((option) => option.default)?.value ?? options[0].value,
options.find((option) => option.default)?.value ?? options[0].value,
}); });
} }
} }
class CredentialSchemaNotice extends CredentialSchemaProperty< class CredentialSchemaNotice extends CredentialSchemaProperty<BaseMetadata, null> {
BaseMetadata,
null
> {
constructor(public notice: string) { constructor(public notice: string) {
super({ label: notice }, null); super({ label: notice }, null);
} }
@ -168,7 +159,7 @@ class CredentialSchemaNotice extends CredentialSchemaProperty<
toNodeProperties(name: string): INodeProperties { toNodeProperties(name: string): INodeProperties {
return { return {
...super.toNodeProperties(name), ...super.toNodeProperties(name),
type: "notice", type: 'notice',
}; };
} }
} }
@ -208,18 +199,18 @@ 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']> extends z.ZodType ? ReturnType<T['toZodSchema']> : never;
? 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 in keyof T as ReturnType<T[K]['toZodSchema']> extends z.ZodType ? K : never]: Zodify<
? K M,
: never]: Zodify<M, S, T[K]>; S,
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>>;
@ -233,11 +224,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(),
@ -251,24 +242,18 @@ 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( return new CredentialSchemaString({ label: 'URL', ...options }, z.string().url());
{ label: "URL", ...options },
z.string().url(),
);
}, },
email(options: Optional<StringMetadata, "label"> = {}) { email(options: Optional<StringMetadata, 'label'> = {}) {
return new CredentialSchemaString( return new CredentialSchemaString({ label: 'Email', ...options }, z.string().email());
{ 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']
>, >,
), ),
); );
@ -278,11 +263,8 @@ export const CredentialSchema = {
}, },
}; };
export type TCredentialSchema = CredentialSchemaRootObject< export type TCredentialSchema = CredentialSchemaRootObject<BaseMetadata, ZodType | null>;
BaseMetadata,
ZodType | null
>;
export type InferCredentialSchema<T extends TCredentialSchema> = z.infer< export type InferCredentialSchema<T extends TCredentialSchema> = z.infer<
ReturnType<T["toZodSchema"]> ReturnType<T['toZodSchema']>
>; >;

View file

@ -13,6 +13,7 @@ import type { SecureContextOptions } from 'tls';
import type { URLSearchParams } from 'url'; import type { URLSearchParams } from 'url';
import type { CODE_EXECUTION_MODES, CODE_LANGUAGES, LOG_LEVELS } from './Constants'; import type { CODE_EXECUTION_MODES, CODE_LANGUAGES, LOG_LEVELS } from './Constants';
import type { InferCredentialSchema, TCredentialSchema } from './CredentialSchema/CredentialSchema';
import type { IDeferredPromise } from './DeferredPromise'; import type { IDeferredPromise } from './DeferredPromise';
import type { ExecutionCancelledError } from './errors'; import type { ExecutionCancelledError } from './errors';
import type { ExpressionError } from './errors/expression.error'; import type { ExpressionError } from './errors/expression.error';
@ -864,12 +865,12 @@ export interface FunctionsBase {
type: string, type: string,
itemIndex?: number, itemIndex?: number,
): Promise<T>; ): Promise<T>;
getCredentials<T extends ICredentialType>( getCredentials<T extends new () => ICredentialType>(
type: T, type: T,
itemIndex?: number, itemIndex?: number,
): Promise< ): Promise<
T['schema'] extends TCredentialSchema InstanceType<T>['schema'] extends TCredentialSchema
? InferCredentialSchema<T['schema']> ? InferCredentialSchema<InstanceType<T>['schema']>
: ICredentialDataDecryptedObject : ICredentialDataDecryptedObject
>; >;
getCredentialsProperties(type: string): INodeProperties[]; getCredentialsProperties(type: string): INodeProperties[];

View file

@ -51,10 +51,7 @@ 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 { export * from './CredentialSchema/CredentialSchema';
CredentialSchema,
InferCredentialSchema,
} from './CredentialSchema/CredentialSchema';
export type { export type {
DocMetadata, DocMetadata,

View file

@ -1,4 +1,4 @@
import { CredentialSchema } from '../CredentialSchema'; import { CredentialSchema } from '../src/CredentialSchema/CredentialSchema';
describe('CredentialSchema', () => { describe('CredentialSchema', () => {
test('should convert Strapi credential to node properties', () => { test('should convert Strapi credential to node properties', () => {

View file

@ -1871,10 +1871,13 @@ importers:
xml2js: xml2js:
specifier: 'catalog:' specifier: 'catalog:'
version: 0.6.2 version: 0.6.2
zod:
specifier: 'catalog:'
version: 3.23.8
devDependencies: devDependencies:
'@langchain/core': '@langchain/core':
specifier: 'catalog:' specifier: 'catalog:'
version: 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0) version: 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8))
'@types/deep-equal': '@types/deep-equal':
specifier: ^1.0.1 specifier: ^1.0.1
version: 1.0.1 version: 1.0.1
@ -15085,41 +15088,6 @@ snapshots:
- langchain - langchain
- openai - openai
'@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8))':
dependencies:
ansi-styles: 5.2.0
camelcase: 6.3.0
decamelize: 1.2.0
js-tiktoken: 1.0.12
langsmith: 0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8))
mustache: 4.2.0
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 10.0.0
zod: 3.23.8
zod-to-json-schema: 3.23.2(zod@3.23.8)
transitivePeerDependencies:
- langchain
- openai
optional: true
'@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)':
dependencies:
ansi-styles: 5.2.0
camelcase: 6.3.0
decamelize: 1.2.0
js-tiktoken: 1.0.12
langsmith: 0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
mustache: 4.2.0
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 10.0.0
zod: 3.23.8
zod-to-json-schema: 3.23.2(zod@3.23.8)
transitivePeerDependencies:
- langchain
- openai
'@langchain/core@0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))': '@langchain/core@0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))':
dependencies: dependencies:
ansi-styles: 5.2.0 ansi-styles: 5.2.0
@ -15230,20 +15198,7 @@ snapshots:
dependencies: dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8)) '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8))
js-tiktoken: 1.0.12 js-tiktoken: 1.0.12
openai: 4.58.0(zod@3.23.8) openai: 4.58.0(encoding@0.1.13)(zod@3.23.8)
zod: 3.23.8
zod-to-json-schema: 3.23.2(zod@3.23.8)
transitivePeerDependencies:
- encoding
- langchain
- supports-color
optional: true
'@langchain/openai@0.2.10(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))':
dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8))
js-tiktoken: 1.0.12
openai: 4.58.0(zod@3.23.8)
zod: 3.23.8 zod: 3.23.8
zod-to-json-schema: 3.23.2(zod@3.23.8) zod-to-json-schema: 3.23.2(zod@3.23.8)
transitivePeerDependencies: transitivePeerDependencies:
@ -15289,15 +15244,6 @@ snapshots:
- openai - openai
optional: true optional: true
'@langchain/textsplitters@0.0.3(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)':
dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
js-tiktoken: 1.0.12
transitivePeerDependencies:
- langchain
- openai
optional: true
'@langchain/textsplitters@0.0.3(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))': '@langchain/textsplitters@0.0.3(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))':
dependencies: dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)) '@langchain/core': 0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))
@ -22087,30 +22033,6 @@ snapshots:
- supports-color - supports-color
optional: true optional: true
langchain@0.2.18(axios@1.7.4)(openai@4.58.0):
dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
'@langchain/openai': 0.2.10(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))
'@langchain/textsplitters': 0.0.3(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
binary-extensions: 2.2.0
js-tiktoken: 1.0.12
js-yaml: 4.1.0
jsonpointer: 5.0.1
langsmith: 0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
openapi-types: 12.1.3
p-retry: 4.6.2
uuid: 10.0.0
yaml: 2.3.4
zod: 3.23.8
zod-to-json-schema: 3.23.2(zod@3.23.8)
optionalDependencies:
axios: 1.7.4(debug@4.3.6)
transitivePeerDependencies:
- encoding
- openai
- supports-color
optional: true
langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a): langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a):
dependencies: dependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)) '@langchain/core': 0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8))
@ -22184,34 +22106,7 @@ snapshots:
optionalDependencies: optionalDependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8)) '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8))
langchain: 0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)) langchain: 0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8))
openai: 4.58.0(zod@3.23.8) openai: 4.58.0(encoding@0.1.13)(zod@3.23.8)
langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)):
dependencies:
'@types/uuid': 10.0.0
commander: 10.0.1
p-queue: 6.6.2
p-retry: 4.6.2
semver: 7.6.0
uuid: 10.0.0
optionalDependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8))
langchain: 0.2.18(axios@1.7.4)(openai@4.58.0)
openai: 4.58.0(zod@3.23.8)
optional: true
langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0):
dependencies:
'@types/uuid': 10.0.0
commander: 10.0.1
p-queue: 6.6.2
p-retry: 4.6.2
semver: 7.6.0
uuid: 10.0.0
optionalDependencies:
'@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0)
langchain: 0.2.18(axios@1.7.4)(openai@4.58.0)
openai: 4.58.0(zod@3.23.8)
langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)))(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)): langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)))(langchain@0.2.18(svs4mugxvnip77thgyjbfeyt2a))(openai@4.58.0(encoding@0.1.13)(zod@3.23.8)):
dependencies: dependencies:
@ -23542,24 +23437,6 @@ snapshots:
- encoding - encoding
- supports-color - supports-color
openai@4.58.0(zod@3.23.8):
dependencies:
'@types/node': 18.16.16
'@types/node-fetch': 2.6.4
'@types/qs': 6.9.15
abort-controller: 3.0.0
agentkeepalive: 4.2.1
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.7.0(encoding@0.1.13)
qs: 6.11.0
optionalDependencies:
zod: 3.23.8
transitivePeerDependencies:
- encoding
- supports-color
optional: true
openapi-sampler@1.4.0: openapi-sampler@1.4.0:
dependencies: dependencies:
'@types/json-schema': 7.0.15 '@types/json-schema': 7.0.15