;
+ if (!metadata) {
+ // Special case: Allow undefined returns for non-decorated constructor params
+ // when resolving a dependency chain (i.e., resolutionStack not empty)
+ if (resolutionStack.length) return undefined as T;
+ throw new DIError(`${type.name} is not decorated with ${Service.name}`);
+ }
+
+ if (metadata?.instance) return metadata.instance as T;
+
+ // Add current type to resolution stack before resolving dependencies
+ resolutionStack.push(type);
+
+ try {
+ let instance: T;
+
+ const paramTypes = (Reflect.getMetadata('design:paramtypes', type) ?? []) as Constructable[];
+
+ const dependencies = paramTypes.map((paramType: Constructable
, index: number) => {
+ if (paramType === undefined) {
+ throw new DIError(
+ `Circular dependency detected in ${type.name} at index ${index}.\n${resolutionStack.map((t) => t.name).join(' -> ')}\n`,
+ );
+ }
+ return this.get(paramType);
+ });
+
+ if (metadata?.factory) {
+ instance = metadata.factory(...dependencies);
+ } else {
+ // Create new instance with resolved dependencies
+ instance = new (type as Constructable)(...dependencies) as T;
+ }
+
+ instances.set(type, { ...metadata, instance });
+ return instance;
+ } catch (error) {
+ if (error instanceof TypeError && error.message.toLowerCase().includes('abstract')) {
+ throw new DIError(`${type.name} is an abstract class, and cannot be instantiated`);
+ }
+ throw error;
+ } finally {
+ resolutionStack.pop();
+ }
+ }
+
+ /**
+ * Manually sets an instance for a specific type in the container
+ * @template T The type of instance being set
+ * @param type The constructor of the type to set. This can also be an abstract class
+ * @param instance The instance to store in the container
+ */
+ set(type: ServiceIdentifier, instance: T): void {
+ // Preserve any existing metadata (like factory) when setting new instance
+ const metadata = instances.get(type) ?? {};
+ instances.set(type, { ...metadata, instance });
+ }
+
+ /** Clears all instantiated instances from the container while preserving type registrations */
+ reset(): void {
+ for (const metadata of instances.values()) {
+ delete metadata.instance;
+ }
+ }
+}
+
+/**
+ * Global dependency injection container instance
+ * Used to retrieve and manage class instances and their dependencies
+ */
+export const Container = new ContainerClass();
diff --git a/n8n-n8n-1.109.2/packages/@n8n/errors/src/application.error 2.ts b/n8n-n8n-1.109.2/packages/@n8n/errors/src/application.error 2.ts
new file mode 100755
index 00000000..c33cda55
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/errors/src/application.error 2.ts
@@ -0,0 +1,36 @@
+import type { Event } from '@sentry/node';
+import callsites from 'callsites';
+
+import type { ErrorLevel, ReportingOptions } from './types';
+
+/**
+ * @deprecated Use `UserError`, `OperationalError` or `UnexpectedError` instead.
+ */
+export class ApplicationError extends Error {
+ level: ErrorLevel;
+
+ readonly tags: NonNullable;
+
+ readonly extra?: Event['extra'];
+
+ readonly packageName?: string;
+
+ constructor(
+ message: string,
+ { level, tags = {}, extra, ...rest }: ErrorOptions & ReportingOptions = {},
+ ) {
+ super(message, rest);
+ this.level = level ?? 'error';
+ this.tags = tags;
+ this.extra = extra;
+
+ try {
+ const filePath = callsites()[2].getFileName() ?? '';
+ // eslint-disable-next-line no-useless-escape
+ const match = /packages\/([^\/]+)\//.exec(filePath)?.[1];
+
+ if (match) this.tags.packageName = match;
+ // eslint-disable-next-line no-empty
+ } catch {}
+ }
+}
diff --git a/n8n-n8n-1.109.2/packages/@n8n/errors/src/index 2.ts b/n8n-n8n-1.109.2/packages/@n8n/errors/src/index 2.ts
new file mode 100755
index 00000000..8de63e4d
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/errors/src/index 2.ts
@@ -0,0 +1,2 @@
+export { ApplicationError } from './application.error';
+export * from './types';
diff --git a/n8n-n8n-1.109.2/packages/@n8n/errors/src/types 2.ts b/n8n-n8n-1.109.2/packages/@n8n/errors/src/types 2.ts
new file mode 100755
index 00000000..7cbcc4cc
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/errors/src/types 2.ts
@@ -0,0 +1,16 @@
+import type { Event } from '@sentry/node';
+
+export type ErrorLevel = 'fatal' | 'error' | 'warning' | 'info';
+
+export type ErrorTags = NonNullable;
+
+export type ReportingOptions = {
+ /** Whether the error should be reported to Sentry */
+ shouldReport?: boolean;
+ /** Whether the error log should be logged (default to true) */
+ shouldBeLogged?: boolean;
+ level?: ErrorLevel;
+ tags?: ErrorTags;
+ extra?: Event['extra'];
+ executionId?: string;
+};
diff --git a/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugin 2.ts b/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugin 2.ts
new file mode 100755
index 00000000..da810921
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugin 2.ts
@@ -0,0 +1,30 @@
+import type { ESLint } from 'eslint';
+import { rules } from './rules/index.js';
+
+const plugin = {
+ meta: {
+ name: 'n8n-local-rules',
+ },
+ configs: {},
+ // @ts-expect-error Rules type does not match for typescript-eslint and eslint
+ rules: rules as ESLint.Plugin['rules'],
+} satisfies ESLint.Plugin;
+
+export const localRulesPlugin = {
+ ...plugin,
+ configs: {
+ recommended: {
+ plugins: {
+ 'n8n-local-rules': plugin,
+ },
+ rules: {
+ 'n8n-local-rules/no-uncaught-json-parse': 'error',
+ 'n8n-local-rules/no-json-parse-json-stringify': 'error',
+ 'n8n-local-rules/no-unneeded-backticks': 'error',
+ 'n8n-local-rules/no-interpolation-in-regular-string': 'error',
+ 'n8n-local-rules/no-unused-param-in-catch-clause': 'error',
+ 'n8n-local-rules/no-useless-catch-throw': 'error',
+ },
+ },
+ },
+} satisfies ESLint.Plugin;
diff --git a/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugins.d 2.ts b/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugins.d 2.ts
new file mode 100755
index 00000000..8335ec10
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/eslint-config/src/plugins.d 2.ts
@@ -0,0 +1 @@
+declare module 'eslint-plugin-lodash';
diff --git a/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/scripts/create-json-schema 2.ts b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/scripts/create-json-schema 2.ts
new file mode 100755
index 00000000..990b25aa
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/scripts/create-json-schema 2.ts
@@ -0,0 +1,22 @@
+import { extensionManifestSchema } from '../src/schema';
+import { zodToJsonSchema } from 'zod-to-json-schema';
+import { writeFile } from 'fs/promises';
+import { dirname, resolve } from 'path';
+import { fileURLToPath } from 'url';
+import { format, resolveConfig } from 'prettier';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const rootDir = resolve(__dirname, '..');
+
+const jsonSchema = zodToJsonSchema(extensionManifestSchema, {
+ name: 'N8nExtensionSchema',
+ nameStrategy: 'title',
+});
+
+(async () => {
+ const filepath = 'schema.json';
+ const schema = JSON.stringify(jsonSchema);
+ const config = await resolveConfig(filepath);
+ const formattedSchema = await format(schema, { ...config, filepath });
+ await writeFile(resolve(rootDir, filepath), formattedSchema);
+})();
diff --git a/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/index 2.ts b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/index 2.ts
new file mode 100755
index 00000000..e27a6e2f
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/index 2.ts
@@ -0,0 +1 @@
+export * from './schema';
diff --git a/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/schema 2.ts b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/schema 2.ts
new file mode 100755
index 00000000..0b6d47b3
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/schema 2.ts
@@ -0,0 +1,96 @@
+import { z } from 'zod';
+
+/**
+ * Schema for the extension configuration.
+ */
+export const extensionManifestSchema = z.object({
+ /**
+ * Name of the extension package.
+ */
+ name: z.string(),
+
+ /**
+ * The display name of the extension.
+ */
+ displayName: z.string(),
+
+ /**
+ * Description of the extension package.
+ */
+ description: z.string(),
+
+ /**
+ * Publisher of the extension.
+ */
+ publisher: z.string(),
+
+ /**
+ * Version of the extension package.
+ */
+ version: z.string(),
+
+ /**
+ * Category the extension belongs to.
+ */
+ categories: z.array(z.string()),
+
+ /**
+ * Setup paths for backend and frontend code entry points.
+ */
+ entry: z.object({
+ /**
+ * Path to the backend entry file.
+ */
+ backend: z.string(),
+ /**
+ * Path to the frontend entry file.
+ */
+ frontend: z.string(),
+ }),
+
+ /**
+ * Minimum SDK version required to run the extension.
+ */
+ minSDKVersion: z.string(),
+
+ /**
+ * Permissions object specifying allowed access for frontend and backend.
+ */
+ permissions: z.object({
+ /**
+ * List of frontend permissions (array of strings).
+ */
+ frontend: z.array(z.string()),
+ /**
+ * List of backend permissions (array of strings).
+ */
+ backend: z.array(z.string()),
+ }),
+
+ /**
+ * List of events that the extension listens to.
+ */
+ events: z.array(z.string()),
+
+ /**
+ * Define extension points for existing functionalities.
+ */
+ extends: z.object({
+ /**
+ * Extends the views configuration.
+ */
+ views: z.object({
+ /**
+ * Extends the workflows view configuration.
+ */
+ workflows: z.object({
+ /**
+ * Header component for the workflows view.
+ */
+ header: z.string(),
+ }),
+ }),
+ }),
+});
+
+export type ExtensionManifest = z.infer;
diff --git a/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/shims.d 2.ts b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/shims.d 2.ts
new file mode 100755
index 00000000..11f02fe2
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/extension-sdk/src/shims.d 2.ts
@@ -0,0 +1 @@
+///
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/errors 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/errors 2.ts
new file mode 100755
index 00000000..ec36a0b1
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/errors 2.ts
@@ -0,0 +1,27 @@
+export abstract class ImapError extends Error {}
+
+/** Error thrown when a connection attempt has timed out */
+export class ConnectionTimeoutError extends ImapError {
+ constructor(
+ /** timeout in milliseconds that the connection waited before timing out */
+ readonly timeout?: number,
+ ) {
+ let message = 'connection timed out';
+ if (timeout) {
+ message += `. timeout = ${timeout} ms`;
+ }
+ super(message);
+ }
+}
+
+export class ConnectionClosedError extends ImapError {
+ constructor() {
+ super('Connection closed unexpectedly');
+ }
+}
+
+export class ConnectionEndedError extends ImapError {
+ constructor() {
+ super('Connection ended unexpectedly');
+ }
+}
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple 2.ts
new file mode 100755
index 00000000..93bb9e05
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple 2.ts
@@ -0,0 +1,203 @@
+import { EventEmitter } from 'events';
+import type Imap from 'imap';
+import { type ImapMessage } from 'imap';
+
+import { getMessage } from './helpers/get-message';
+import { PartData } from './part-data';
+import type { Message, MessagePart, SearchCriteria } from './types';
+
+const IMAP_EVENTS = ['alert', 'mail', 'expunge', 'uidvalidity', 'update', 'close', 'end'] as const;
+
+export class ImapSimple extends EventEmitter {
+ /** flag to determine whether we should suppress ECONNRESET from bubbling up to listener */
+ private ending = false;
+
+ constructor(private readonly imap: Imap) {
+ super();
+
+ // pass most node-imap `Connection` events through 1:1
+ IMAP_EVENTS.forEach((event) => {
+ this.imap.on(event, this.emit.bind(this, event));
+ });
+
+ // special handling for `error` event
+ this.imap.on('error', (e: Error & { code?: string }) => {
+ // if .end() has been called and an 'ECONNRESET' error is received, don't bubble
+ if (e && this.ending && e.code?.toUpperCase() === 'ECONNRESET') {
+ return;
+ }
+ this.emit('error', e);
+ });
+ }
+
+ /** disconnect from the imap server */
+ end(): void {
+ // set state flag to suppress 'ECONNRESET' errors that are triggered when .end() is called.
+ // it is a known issue that has no known fix. This just temporarily ignores that error.
+ // https://github.com/mscdex/node-imap/issues/391
+ // https://github.com/mscdex/node-imap/issues/395
+ this.ending = true;
+
+ // using 'close' event to unbind ECONNRESET error handler, because the node-imap
+ // maintainer claims it is the more reliable event between 'end' and 'close'.
+ // https://github.com/mscdex/node-imap/issues/394
+ this.imap.once('close', () => {
+ this.ending = false;
+ });
+
+ this.imap.end();
+ }
+
+ /**
+ * Search the currently open mailbox, and retrieve the results
+ *
+ * Results are in the form:
+ *
+ * [{
+ * attributes: object,
+ * parts: [ { which: string, size: number, body: string }, ... ]
+ * }, ...]
+ *
+ * See node-imap's ImapMessage signature for information about `attributes`, `which`, `size`, and `body`.
+ * For any message part that is a `HEADER`, the body is automatically parsed into an object.
+ */
+ async search(
+ /** Criteria to use to search. Passed to node-imap's .search() 1:1 */
+ searchCriteria: SearchCriteria[],
+ /** Criteria to use to fetch the search results. Passed to node-imap's .fetch() 1:1 */
+ fetchOptions: Imap.FetchOptions,
+ /** Optional limit to restrict the number of messages fetched */
+ limit?: number,
+ ) {
+ return await new Promise((resolve, reject) => {
+ this.imap.search(searchCriteria, (e, uids) => {
+ if (e) {
+ reject(e);
+ return;
+ }
+
+ if (uids.length === 0) {
+ resolve([]);
+ return;
+ }
+
+ // If limit is specified, take only the first N UIDs
+ let uidsToFetch = uids;
+ if (limit && limit > 0 && uids.length > limit) {
+ uidsToFetch = uids.slice(0, limit);
+ }
+
+ const fetch = this.imap.fetch(uidsToFetch, fetchOptions);
+ let messagesRetrieved = 0;
+ const messages: Message[] = [];
+
+ const fetchOnMessage = async (message: Imap.ImapMessage, seqNo: number) => {
+ const msg: Message = await getMessage(message);
+ msg.seqNo = seqNo;
+ messages.push(msg);
+
+ messagesRetrieved++;
+ if (messagesRetrieved === uidsToFetch.length) {
+ resolve(messages.filter((m) => !!m));
+ }
+ };
+
+ const fetchOnError = (error: Error) => {
+ fetch.removeListener('message', fetchOnMessage);
+ fetch.removeListener('end', fetchOnEnd);
+ reject(error);
+ };
+
+ const fetchOnEnd = () => {
+ fetch.removeListener('message', fetchOnMessage);
+ fetch.removeListener('error', fetchOnError);
+ };
+
+ fetch.on('message', fetchOnMessage);
+ fetch.once('error', fetchOnError);
+ fetch.once('end', fetchOnEnd);
+ });
+ });
+ }
+
+ /** Download a "part" (either a portion of the message body, or an attachment) */
+ async getPartData(
+ /** The message returned from `search()` */
+ message: Message,
+ /** The message part to be downloaded, from the `message.attributes.struct` Array */
+ part: MessagePart,
+ ) {
+ return await new Promise((resolve, reject) => {
+ const fetch = this.imap.fetch(message.attributes.uid, {
+ bodies: [part.partID],
+ struct: true,
+ });
+
+ const fetchOnMessage = async (msg: ImapMessage) => {
+ const result = await getMessage(msg);
+ if (result.parts.length !== 1) {
+ reject(new Error('Got ' + result.parts.length + ' parts, should get 1'));
+ return;
+ }
+
+ const data = result.parts[0].body as string;
+ const encoding = part.encoding.toUpperCase();
+ resolve(PartData.fromData(data, encoding));
+ };
+
+ const fetchOnError = (error: Error) => {
+ fetch.removeListener('message', fetchOnMessage);
+ fetch.removeListener('end', fetchOnEnd);
+ reject(error);
+ };
+
+ const fetchOnEnd = () => {
+ fetch.removeListener('message', fetchOnMessage);
+ fetch.removeListener('error', fetchOnError);
+ };
+
+ fetch.once('message', fetchOnMessage);
+ fetch.once('error', fetchOnError);
+ fetch.once('end', fetchOnEnd);
+ });
+ }
+
+ /** Adds the provided flag(s) to the specified message(s). */
+ async addFlags(
+ /** The messages uid */
+ uid: number[],
+ /** The flags to add to the message(s). */
+ flags: string | string[],
+ ) {
+ return await new Promise((resolve, reject) => {
+ this.imap.addFlags(uid, flags, (e) => (e ? reject(e) : resolve()));
+ });
+ }
+
+ /** Returns a list of mailboxes (folders). */
+ async getBoxes() {
+ return await new Promise((resolve, reject) => {
+ this.imap.getBoxes((e, boxes) => (e ? reject(e) : resolve(boxes)));
+ });
+ }
+
+ /** Open a mailbox */
+ async openBox(
+ /** The name of the box to open */
+ boxName: string,
+ ): Promise {
+ return await new Promise((resolve, reject) => {
+ this.imap.openBox(boxName, (e, result) => (e ? reject(e) : resolve(result)));
+ });
+ }
+
+ /** Close a mailbox */
+ async closeBox(
+ /** If autoExpunge is true, any messages marked as Deleted in the currently open mailbox will be removed @default true */
+ autoExpunge = true,
+ ) {
+ return await new Promise((resolve, reject) => {
+ this.imap.closeBox(autoExpunge, (e) => (e ? reject(e) : resolve()));
+ });
+ }
+}
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple.test 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple.test 2.ts
new file mode 100755
index 00000000..896c0956
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/imap-simple.test 2.ts
@@ -0,0 +1,266 @@
+import { EventEmitter } from 'events';
+import Imap, { type Box, type MailBoxes } from 'imap';
+import { Readable } from 'stream';
+import type { Mocked } from 'vitest';
+import { mock } from 'vitest-mock-extended';
+
+import { ImapSimple } from './imap-simple';
+import { PartData } from './part-data';
+
+type MockImap = EventEmitter & {
+ connect: Mocked<() => unknown>;
+ fetch: Mocked<() => unknown>;
+ end: Mocked<() => unknown>;
+ search: Mocked<(...args: Parameters) => unknown>;
+ sort: Mocked<(...args: Parameters) => unknown>;
+ openBox: Mocked<
+ (boxName: string, onOpen: (error: Error | null, box?: Box) => unknown) => unknown
+ >;
+ closeBox: Mocked<(...args: Parameters) => unknown>;
+ getBoxes: Mocked<(onBoxes: (error: Error | null, boxes?: MailBoxes) => unknown) => unknown>;
+ addFlags: Mocked<(...args: Parameters) => unknown>;
+};
+
+vi.mock('imap', () => {
+ return {
+ default: class InlineMockImap extends EventEmitter implements MockImap {
+ connect = vi.fn();
+ fetch = vi.fn();
+ end = vi.fn();
+ search = vi.fn();
+ sort = vi.fn();
+ openBox = vi.fn();
+ closeBox = vi.fn();
+ addFlags = vi.fn();
+ getBoxes = vi.fn();
+ },
+ };
+});
+
+vi.mock('./part-data', () => ({
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ PartData: { fromData: vi.fn(() => 'decoded') },
+}));
+
+describe('ImapSimple', () => {
+ function createImap() {
+ const imap = new Imap({ user: 'testuser', password: 'testpass' });
+ return { imapSimple: new ImapSimple(imap), mockImap: imap as unknown as MockImap };
+ }
+
+ describe('constructor', () => {
+ it('should forward nonerror events', () => {
+ const { imapSimple, mockImap } = createImap();
+ const onMail = vi.fn();
+ imapSimple.on('mail', onMail);
+ mockImap.emit('mail', 3);
+ expect(onMail).toHaveBeenCalledWith(3);
+ });
+
+ it('should suppress ECONNRESET errors if ending', () => {
+ const { imapSimple, mockImap } = createImap();
+ const onError = vi.fn();
+ imapSimple.on('error', onError);
+ imapSimple.end();
+
+ mockImap.emit('error', { message: 'reset', code: 'ECONNRESET' });
+ expect(onError).not.toHaveBeenCalled();
+ });
+
+ it('should forward ECONNRESET errors if not ending', () => {
+ const { imapSimple, mockImap } = createImap();
+ const onError = vi.fn();
+ imapSimple.on('error', onError);
+
+ const error = { message: 'reset', code: 'ECONNRESET' };
+ mockImap.emit('error', error);
+ expect(onError).toHaveBeenCalledWith(error);
+ });
+ });
+
+ describe('search', () => {
+ it('should resolve with messages returned from fetch', async () => {
+ const { imapSimple, mockImap } = createImap();
+
+ const fetchEmitter = new EventEmitter();
+ const mockMessages = [{ uid: 1 }, { uid: 2 }, { uid: 3 }];
+ vi.mocked(mockImap.search).mockImplementation((_criteria, onResult) =>
+ onResult(
+ null as unknown as Error,
+ mockMessages.map((m) => m.uid),
+ ),
+ );
+ mockImap.fetch = vi.fn(() => fetchEmitter);
+
+ const searchPromise = imapSimple.search(['UNSEEN', ['FROM', 'test@n8n.io']], {
+ bodies: ['BODY'],
+ });
+ expect(mockImap.search).toHaveBeenCalledWith(
+ ['UNSEEN', ['FROM', 'test@n8n.io']],
+ expect.any(Function),
+ );
+
+ for (const message of mockMessages) {
+ const messageEmitter = new EventEmitter();
+ const body = 'body' + message.uid;
+ const bodyStream = Readable.from(body);
+ fetchEmitter.emit('message', messageEmitter, message.uid);
+ messageEmitter.emit('body', bodyStream, { which: 'TEXT', size: Buffer.byteLength(body) });
+ messageEmitter.emit('attributes', { uid: message.uid });
+ await new Promise((resolve) => {
+ bodyStream.on('end', resolve);
+ });
+ messageEmitter.emit('end');
+ }
+
+ fetchEmitter.emit('end');
+
+ const messages = await searchPromise;
+
+ expect(messages).toEqual([
+ {
+ attributes: { uid: 1 },
+ parts: [{ body: 'body1', size: 5, which: 'TEXT' }],
+ seqNo: 1,
+ },
+ {
+ attributes: { uid: 2 },
+ parts: [{ body: 'body2', size: 5, which: 'TEXT' }],
+ seqNo: 2,
+ },
+ {
+ attributes: { uid: 3 },
+ parts: [{ body: 'body3', size: 5, which: 'TEXT' }],
+ seqNo: 3,
+ },
+ ]);
+ });
+ });
+
+ describe('getPartData', () => {
+ it('should return decoded part data', async () => {
+ const { imapSimple, mockImap } = createImap();
+
+ const fetchEmitter = new EventEmitter();
+ mockImap.fetch = vi.fn(() => fetchEmitter);
+
+ const message = { attributes: { uid: 123 } };
+ const part = { partID: '1.2', encoding: 'BASE64' };
+
+ const partDataPromise = imapSimple.getPartData(mock(message), mock(part));
+
+ const body = 'encoded-body';
+ const messageEmitter = new EventEmitter();
+ const bodyStream = Readable.from(body);
+
+ fetchEmitter.emit('message', messageEmitter);
+
+ messageEmitter.emit('body', bodyStream, {
+ which: part.partID,
+ size: Buffer.byteLength(body),
+ });
+ messageEmitter.emit('attributes', {});
+ await new Promise((resolve) => bodyStream.on('end', resolve));
+ messageEmitter.emit('end');
+
+ fetchEmitter.emit('end');
+
+ const result = await partDataPromise;
+ expect(PartData.fromData).toHaveBeenCalledWith('encoded-body', 'BASE64');
+ expect(result).toBe('decoded');
+ });
+ });
+
+ describe('openBox', () => {
+ it('should open the mailbox', async () => {
+ const { imapSimple, mockImap } = createImap();
+ const box = mock({ name: 'INBOX' });
+ vi.mocked(mockImap.openBox).mockImplementation((_boxName, onOpen) =>
+ onOpen(null as unknown as Error, box),
+ );
+ await expect(imapSimple.openBox('INBOX')).resolves.toEqual(box);
+ });
+
+ it('should reject on error', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.openBox).mockImplementation((_boxName, onOpen) =>
+ onOpen(new Error('nope')),
+ );
+ await expect(imapSimple.openBox('INBOX')).rejects.toThrow('nope');
+ });
+ });
+
+ describe('closeBox', () => {
+ it('should close the mailbox with default autoExpunge=true', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.closeBox).mockImplementation((_expunge, onClose) =>
+ onClose(null as unknown as Error),
+ );
+ await expect(imapSimple.closeBox()).resolves.toBeUndefined();
+ expect(mockImap.closeBox).toHaveBeenCalledWith(true, expect.any(Function));
+ });
+
+ it('should close the mailbox with autoExpunge=false', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.closeBox).mockImplementation((_expunge, onClose) =>
+ onClose(null as unknown as Error),
+ );
+ await expect(imapSimple.closeBox(false)).resolves.toBeUndefined();
+ expect(mockImap.closeBox).toHaveBeenCalledWith(false, expect.any(Function));
+ });
+
+ it('should reject on error', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.closeBox).mockImplementation((_expunge, onClose) =>
+ onClose(new Error('fail')),
+ );
+ await expect(imapSimple.closeBox()).rejects.toThrow('fail');
+ });
+ });
+
+ describe('addFlags', () => {
+ it('should add flags to messages and resolve', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.addFlags).mockImplementation((_uids, _flags, onAdd) =>
+ onAdd(null as unknown as Error),
+ );
+
+ await expect(imapSimple.addFlags([1, 2], ['\\Seen'])).resolves.toBeUndefined();
+ expect(mockImap.addFlags).toHaveBeenCalledWith([1, 2], ['\\Seen'], expect.any(Function));
+ });
+
+ it('should reject on error', async () => {
+ const { imapSimple, mockImap } = createImap();
+ vi.mocked(mockImap.addFlags).mockImplementation((_uids, _flags, onAdd) =>
+ onAdd(new Error('add flags failed')),
+ );
+
+ await expect(imapSimple.addFlags([1], '\\Seen')).rejects.toThrow('add flags failed');
+ });
+ });
+
+ describe('getBoxes', () => {
+ it('should resolve with list of mailboxes', async () => {
+ const { imapSimple, mockImap } = createImap();
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ const boxes = mock({ INBOX: {}, Archive: {} });
+
+ vi.mocked(mockImap.getBoxes).mockImplementation((onBoxes) =>
+ onBoxes(null as unknown as Error, boxes),
+ );
+
+ await expect(imapSimple.getBoxes()).resolves.toEqual(boxes);
+ expect(mockImap.getBoxes).toHaveBeenCalledWith(expect.any(Function));
+ });
+
+ it('should reject on error', async () => {
+ const { imapSimple, mockImap } = createImap();
+
+ vi.mocked(mockImap.getBoxes).mockImplementation((onBoxes) =>
+ onBoxes(new Error('getBoxes failed')),
+ );
+
+ await expect(imapSimple.getBoxes()).rejects.toThrow('getBoxes failed');
+ });
+ });
+});
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/index 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/index 2.ts
new file mode 100755
index 00000000..2e766bf7
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/index 2.ts
@@ -0,0 +1,100 @@
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+
+import Imap from 'imap';
+
+import { ConnectionClosedError, ConnectionEndedError, ConnectionTimeoutError } from './errors';
+import { ImapSimple } from './imap-simple';
+import type { ImapSimpleOptions, MessagePart } from './types';
+
+/**
+ * Connect to an Imap server, returning an ImapSimple instance, which is a wrapper over node-imap to simplify it's api for common use cases.
+ */
+export async function connect(options: ImapSimpleOptions): Promise {
+ const authTimeout = options.imap.authTimeout ?? 2000;
+ options.imap.authTimeout = authTimeout;
+
+ const imap = new Imap(options.imap);
+
+ return await new Promise((resolve, reject) => {
+ const cleanUp = () => {
+ imap.removeListener('ready', imapOnReady);
+ imap.removeListener('error', imapOnError);
+ imap.removeListener('close', imapOnClose);
+ imap.removeListener('end', imapOnEnd);
+ };
+
+ const imapOnReady = () => {
+ cleanUp();
+ resolve(new ImapSimple(imap));
+ };
+
+ const imapOnError = (e: Error & { source?: string }) => {
+ if (e.source === 'timeout-auth') {
+ e = new ConnectionTimeoutError(authTimeout);
+ }
+
+ cleanUp();
+ reject(e);
+ };
+
+ const imapOnEnd = () => {
+ cleanUp();
+ reject(new ConnectionEndedError());
+ };
+
+ const imapOnClose = () => {
+ cleanUp();
+ reject(new ConnectionClosedError());
+ };
+
+ imap.once('ready', imapOnReady);
+ imap.once('error', imapOnError);
+ imap.once('close', imapOnClose);
+ imap.once('end', imapOnEnd);
+
+ if (options.onMail) {
+ imap.on('mail', options.onMail);
+ }
+
+ if (options.onExpunge) {
+ imap.on('expunge', options.onExpunge);
+ }
+
+ if (options.onUpdate) {
+ imap.on('update', options.onUpdate);
+ }
+
+ imap.connect();
+ });
+}
+
+/**
+ * Given the `message.attributes.struct`, retrieve a flattened array of `parts` objects that describe the structure of
+ * the different parts of the message's body. Useful for getting a simple list to iterate for the purposes of,
+ * for example, finding all attachments.
+ *
+ * Code taken from http://stackoverflow.com/questions/25247207/how-to-read-and-save-attachments-using-node-imap
+ *
+ * @returns {Array} a flattened array of `parts` objects that describe the structure of the different parts of the
+ * message's body
+ */
+export function getParts(
+ /** The `message.attributes.struct` value from the message you wish to retrieve parts for. */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ struct: any,
+ /** The list of parts to push to. */
+ parts: MessagePart[] = [],
+): MessagePart[] {
+ for (let i = 0; i < struct.length; i++) {
+ if (Array.isArray(struct[i])) {
+ getParts(struct[i], parts);
+ } else if (struct[i].partID) {
+ parts.push(struct[i] as MessagePart);
+ }
+ }
+ return parts;
+}
+
+export * from './imap-simple';
+export * from './errors';
+export * from './types';
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data 2.ts
new file mode 100755
index 00000000..77ff09a2
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data 2.ts
@@ -0,0 +1,83 @@
+import * as iconvlite from 'iconv-lite';
+import * as qp from 'quoted-printable';
+import * as utf8 from 'utf8';
+import * as uuencode from 'uuencode';
+
+export abstract class PartData {
+ constructor(readonly buffer: Buffer) {}
+
+ toString() {
+ return this.buffer.toString();
+ }
+
+ static fromData(data: string, encoding: string, charset?: string): PartData {
+ if (encoding === 'BASE64') {
+ return new Base64PartData(data);
+ }
+
+ if (encoding === 'QUOTED-PRINTABLE') {
+ return new QuotedPrintablePartData(data, charset);
+ }
+
+ if (encoding === '7BIT') {
+ return new SevenBitPartData(data);
+ }
+
+ if (encoding === '8BIT' || encoding === 'BINARY') {
+ return new BinaryPartData(data, charset);
+ }
+
+ if (encoding === 'UUENCODE') {
+ return new UuencodedPartData(data);
+ }
+
+ // if it gets here, the encoding is not currently supported
+ throw new Error('Unknown encoding ' + encoding);
+ }
+}
+
+export class Base64PartData extends PartData {
+ constructor(data: string) {
+ super(Buffer.from(data, 'base64'));
+ }
+}
+
+export class QuotedPrintablePartData extends PartData {
+ constructor(data: string, charset?: string) {
+ const decoded =
+ charset?.toUpperCase() === 'UTF-8' ? utf8.decode(qp.decode(data)) : qp.decode(data);
+ super(Buffer.from(decoded));
+ }
+}
+
+export class SevenBitPartData extends PartData {
+ constructor(data: string) {
+ super(Buffer.from(data));
+ }
+
+ toString() {
+ return this.buffer.toString('ascii');
+ }
+}
+
+export class BinaryPartData extends PartData {
+ constructor(
+ data: string,
+ readonly charset: string = 'utf-8',
+ ) {
+ super(Buffer.from(data));
+ }
+
+ toString() {
+ return iconvlite.decode(this.buffer, this.charset);
+ }
+}
+
+export class UuencodedPartData extends PartData {
+ constructor(data: string) {
+ const parts = data.split('\n'); // remove newline characters
+ const merged = parts.splice(1, parts.length - 4).join(''); // remove excess lines and join lines with empty string
+ const decoded = uuencode.decode(merged);
+ super(decoded);
+ }
+}
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data.test 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data.test 2.ts
new file mode 100755
index 00000000..8299b417
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/part-data.test 2.ts
@@ -0,0 +1,88 @@
+import {
+ PartData,
+ Base64PartData,
+ QuotedPrintablePartData,
+ SevenBitPartData,
+ BinaryPartData,
+ UuencodedPartData,
+} from '../src/part-data';
+
+describe('PartData', () => {
+ describe('fromData', () => {
+ it('should return an instance of Base64PartData when encoding is BASE64', () => {
+ const result = PartData.fromData('data', 'BASE64');
+ expect(result).toBeInstanceOf(Base64PartData);
+ });
+
+ it('should return an instance of QuotedPrintablePartData when encoding is QUOTED-PRINTABLE', () => {
+ const result = PartData.fromData('data', 'QUOTED-PRINTABLE');
+ expect(result).toBeInstanceOf(QuotedPrintablePartData);
+ });
+
+ it('should return an instance of SevenBitPartData when encoding is 7BIT', () => {
+ const result = PartData.fromData('data', '7BIT');
+ expect(result).toBeInstanceOf(SevenBitPartData);
+ });
+
+ it('should return an instance of BinaryPartData when encoding is 8BIT or BINARY', () => {
+ let result = PartData.fromData('data', '8BIT');
+ expect(result).toBeInstanceOf(BinaryPartData);
+ result = PartData.fromData('data', 'BINARY');
+ expect(result).toBeInstanceOf(BinaryPartData);
+ });
+
+ it('should return an instance of UuencodedPartData when encoding is UUENCODE', () => {
+ const result = PartData.fromData('data', 'UUENCODE');
+ expect(result).toBeInstanceOf(UuencodedPartData);
+ });
+
+ it('should throw an error when encoding is not supported', () => {
+ expect(() => PartData.fromData('data', 'UNSUPPORTED')).toThrow(
+ 'Unknown encoding UNSUPPORTED',
+ );
+ });
+ });
+});
+
+describe('Base64PartData', () => {
+ it('should correctly decode base64 data', () => {
+ const data = Buffer.from('Hello, world!', 'utf-8').toString('base64');
+ const partData = new Base64PartData(data);
+ expect(partData.toString()).toBe('Hello, world!');
+ });
+});
+
+describe('QuotedPrintablePartData', () => {
+ it('should correctly decode quoted-printable data', () => {
+ const data = '=48=65=6C=6C=6F=2C=20=77=6F=72=6C=64=21'; // 'Hello, world!' in quoted-printable
+ const partData = new QuotedPrintablePartData(data);
+ expect(partData.toString()).toBe('Hello, world!');
+ });
+});
+
+describe('SevenBitPartData', () => {
+ it('should correctly decode 7bit data', () => {
+ const data = 'Hello, world!';
+ const partData = new SevenBitPartData(data);
+ expect(partData.toString()).toBe('Hello, world!');
+ });
+});
+
+describe('BinaryPartData', () => {
+ it('should correctly decode binary data', () => {
+ const data = Buffer.from('Hello, world!', 'utf-8').toString();
+ const partData = new BinaryPartData(data);
+ expect(partData.toString()).toBe('Hello, world!');
+ });
+});
+
+describe('UuencodedPartData', () => {
+ it('should correctly decode uuencoded data', () => {
+ const data = Buffer.from(
+ 'YmVnaW4gNjQ0IGRhdGEKLTImNUw7JlxMKCc9TzxGUUQoMGBgCmAKZW5kCg==',
+ 'base64',
+ ).toString('binary');
+ const partData = new UuencodedPartData(data);
+ expect(partData.toString()).toBe('Hello, world!');
+ });
+});
diff --git a/n8n-n8n-1.109.2/packages/@n8n/imap/src/types 2.ts b/n8n-n8n-1.109.2/packages/@n8n/imap/src/types 2.ts
new file mode 100755
index 00000000..de0964de
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/imap/src/types 2.ts
@@ -0,0 +1,43 @@
+import type { Config, ImapMessageBodyInfo, ImapMessageAttributes } from 'imap';
+
+export interface ImapSimpleOptions {
+ /** Options to pass to node-imap constructor. */
+ imap: Config;
+
+ /** Server event emitted when new mail arrives in the currently open mailbox. */
+ onMail?: ((numNewMail: number) => void) | undefined;
+
+ /** Server event emitted when a message was expunged externally. seqNo is the sequence number (instead of the unique UID) of the message that was expunged. If you are caching sequence numbers, all sequence numbers higher than this value MUST be decremented by 1 in order to stay synchronized with the server and to keep correct continuity. */
+ onExpunge?: ((seqNo: number) => void) | undefined;
+
+ /** Server event emitted when message metadata (e.g. flags) changes externally. */
+ onUpdate?:
+ | ((seqNo: number, info: { num: number | undefined; text: unknown }) => void)
+ | undefined;
+}
+
+export interface MessagePart {
+ partID: string;
+ encoding: 'BASE64' | 'QUOTED-PRINTABLE' | '7BIT' | '8BIT' | 'BINARY' | 'UUENCODE';
+ type: 'TEXT';
+ subtype: string;
+ params?: {
+ charset?: string;
+ };
+ disposition?: {
+ type: string;
+ };
+}
+
+export interface MessageBodyPart extends ImapMessageBodyInfo {
+ /** string type where which=='TEXT', complex Object where which=='HEADER' */
+ body: string | object;
+}
+
+export interface Message {
+ attributes: ImapMessageAttributes;
+ parts: MessageBodyPart[];
+ seqNo?: number;
+}
+
+export type SearchCriteria = string | [string, string];
diff --git a/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/index 2.ts b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/index 2.ts
new file mode 100755
index 00000000..8de0516a
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/index 2.ts
@@ -0,0 +1,2 @@
+export type * from './types';
+export { jsonSchemaToZod } from './json-schema-to-zod';
diff --git a/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/json-schema-to-zod 2.ts b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/json-schema-to-zod 2.ts
new file mode 100755
index 00000000..6f1c6a13
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/json-schema-to-zod 2.ts
@@ -0,0 +1,15 @@
+import type { z } from 'zod';
+
+import { parseSchema } from './parsers/parse-schema';
+import type { JsonSchemaToZodOptions, JsonSchema } from './types';
+
+export const jsonSchemaToZod = (
+ schema: JsonSchema,
+ options: JsonSchemaToZodOptions = {},
+): T => {
+ return parseSchema(schema, {
+ path: [],
+ seen: new Map(),
+ ...options,
+ }) as T;
+};
diff --git a/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/types 2.ts b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/types 2.ts
new file mode 100755
index 00000000..bb342af2
--- /dev/null
+++ b/n8n-n8n-1.109.2/packages/@n8n/json-schema-to-zod/src/types 2.ts
@@ -0,0 +1,82 @@
+import type { ZodTypeAny } from 'zod';
+
+export type Serializable =
+ | { [key: string]: Serializable }
+ | Serializable[]
+ | string
+ | number
+ | boolean
+ | null;
+
+export type JsonSchema = JsonSchemaObject | boolean;
+export type JsonSchemaObject = {
+ // left permissive by design
+ type?: string | string[];
+
+ // object
+ properties?: { [key: string]: JsonSchema };
+ additionalProperties?: JsonSchema;
+ unevaluatedProperties?: JsonSchema;
+ patternProperties?: { [key: string]: JsonSchema };
+ minProperties?: number;
+ maxProperties?: number;
+ required?: string[] | boolean;
+ propertyNames?: JsonSchema;
+
+ // array
+ items?: JsonSchema | JsonSchema[];
+ additionalItems?: JsonSchema;
+ minItems?: number;
+ maxItems?: number;
+ uniqueItems?: boolean;
+
+ // string
+ minLength?: number;
+ maxLength?: number;
+ pattern?: string;
+ format?: string;
+
+ // number
+ minimum?: number;
+ maximum?: number;
+ exclusiveMinimum?: number | boolean;
+ exclusiveMaximum?: number | boolean;
+ multipleOf?: number;
+
+ // unions
+ anyOf?: JsonSchema[];
+ allOf?: JsonSchema[];
+ oneOf?: JsonSchema[];
+
+ if?: JsonSchema;
+ then?: JsonSchema;
+ else?: JsonSchema;
+
+ // shared
+ const?: Serializable;
+ enum?: Serializable[];
+
+ errorMessage?: { [key: string]: string | undefined };
+
+ description?: string;
+ default?: Serializable;
+ readOnly?: boolean;
+ not?: JsonSchema;
+ contentEncoding?: string;
+ nullable?: boolean;
+};
+
+export type ParserSelector = (schema: JsonSchemaObject, refs: Refs) => ZodTypeAny;
+export type ParserOverride = (schema: JsonSchemaObject, refs: Refs) => ZodTypeAny | undefined;
+
+export type JsonSchemaToZodOptions = {
+ withoutDefaults?: boolean;
+ withoutDescribes?: boolean;
+ parserOverride?: ParserOverride;
+ depth?: number;
+};
+
+export type Refs = JsonSchemaToZodOptions & {
+ path: Array;
+ seen: Map