Skip to content

Commit

Permalink
remove circular refs from code items (and lint fixes)
Browse files Browse the repository at this point in the history
  • Loading branch information
flipswitchingmonkey committed Mar 21, 2023
1 parent 469ce32 commit 6c4a154
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/CommunityNodes/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export function hasPackageLoaded(packageName: string): boolean {

export function removePackageFromMissingList(packageName: string): void {
try {
const failedPackages = (config.get('nodes.packagesMissing') as string).split(' ');
const failedPackages = config.get('nodes.packagesMissing').split(' ');

const packageFailedToLoad = failedPackages.filter(
(packageNameAndVersion) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ export class MessageEventBusLogWriter {
unfinishedExecutions: {},
};
const logCount = logHistory
? Math.min(config.get('eventBus.logWriter.keepLogCount') as number, logHistory)
: (config.get('eventBus.logWriter.keepLogCount') as number);
? Math.min(config.get('eventBus.logWriter.keepLogCount'), logHistory)
: config.get('eventBus.logWriter.keepLogCount');
for (let i = logCount; i >= 0; i--) {
const logFileName = this.getLogFileName(i);
if (logFileName) {
Expand Down Expand Up @@ -256,8 +256,8 @@ export class MessageEventBusLogWriter {
): Promise<EventMessageTypes[]> {
const result: EventMessageTypes[] = [];
const logCount = logHistory
? Math.min(config.get('eventBus.logWriter.keepLogCount') as number, logHistory)
: (config.get('eventBus.logWriter.keepLogCount') as number);
? Math.min(config.get('eventBus.logWriter.keepLogCount'), logHistory)
: config.get('eventBus.logWriter.keepLogCount');
for (let i = 0; i < logCount; i++) {
const logFileName = this.getLogFileName(i);
if (logFileName) {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/push/abstract.push.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoggerProxy as Logger } from 'n8n-workflow';
import { jsonStringify, LoggerProxy as Logger } from 'n8n-workflow';
import type { IPushDataType } from '@/Interfaces';
import { eventBus } from '../eventbus';

Expand Down Expand Up @@ -38,7 +38,7 @@ export abstract class AbstractPush<T> {

Logger.debug(`Send data of type "${type}" to editor-UI`, { dataType: type, sessionId });

const sendData = JSON.stringify({ type, data });
const sendData = jsonStringify({ type, data }, { replaceCircularRefs: true });

if (sessionId === undefined) {
// Send to all connected clients
Expand Down
4 changes: 0 additions & 4 deletions packages/cli/src/sso/saml/routes/saml.controller.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { SamlService } from '../saml.service.ee';
import { SamlConfiguration } from '../types/requests';
import { AuthError, BadRequestError } from '../../../ResponseHelper';
import { getInitSSOFormView } from '../views/initSsoPost';
import { getInitSSOPostView } from '../views/initSsoRedirect';
import { issueCookie } from '../../../auth/jwt';
import { validate } from 'class-validator';
import type { PostBindingContext } from 'samlify/types/src/entity';
Expand Down Expand Up @@ -136,9 +135,6 @@ export class SamlController {
private async handleInitSSO(res: express.Response) {
const result = this.samlService.getLoginRequestUrl();
if (result?.binding === 'redirect') {
// forced client side redirect through the use of a javascript redirect
// return res.send(getInitSSOPostView(result.context));
// Return the redirect URL directly
return res.send(result.context.context);
} else if (result?.binding === 'post') {
return res.send(getInitSSOFormView(result.context as PostBindingContext));
Expand Down
28 changes: 21 additions & 7 deletions packages/nodes-base/nodes/Code/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IDataObject } from 'n8n-workflow';
import { jsonStringify } from 'n8n-workflow';

export function isObject(maybe: unknown): maybe is { [key: string]: unknown } {
return typeof maybe === 'object' && maybe !== null && !Array.isArray(maybe);
Expand All @@ -12,15 +13,28 @@ function isTraversable(maybe: unknown): maybe is IDataObject {
* Stringify any non-standard JS objects (e.g. `Date`, `RegExp`) inside output items at any depth.
*/
export function standardizeOutput(output: IDataObject) {
for (const [key, value] of Object.entries(output)) {
if (!isTraversable(value)) continue;
const knownObjects = new WeakSet();

output[key] =
value.constructor.name !== 'Object'
? JSON.stringify(value) // Date, RegExp, etc.
: standardizeOutput(value);
}
function standardizeOutputRecursive(obj: IDataObject): IDataObject {
for (const [key, value] of Object.entries(obj)) {
if (!isTraversable(value)) continue;

if (typeof value === 'object' && value !== null) {
if (knownObjects.has(value)) {
// Found circular reference
continue;
}
knownObjects.add(value);
}

obj[key] =
value.constructor.name !== 'Object'
? JSON.stringify(value) // Date, RegExp, etc.
: standardizeOutputRecursive(value);
}
return obj;
}
standardizeOutputRecursive(output);
return output;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/workflow/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export * from './WorkflowErrors';
export * from './WorkflowHooks';
export * from './VersionedNodeType';
export { LoggerProxy, NodeHelpers, ObservableObject, TelemetryHelpers };
export { deepCopy, jsonParse, sleep, fileTypeFromMimeType, assert } from './utils';
export { deepCopy, jsonParse, jsonStringify, sleep, fileTypeFromMimeType, assert } from './utils';
export {
isINodeProperties,
isINodePropertyOptions,
Expand Down
30 changes: 30 additions & 0 deletions packages/workflow/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,36 @@ export const jsonParse = <T>(jsonString: string, options?: JSONParseOptions<T>):
}
};

type JSONStringifyOptions = {
replaceCircularRefs?: boolean;
circularRefReplacement?: string;
};

const getReplaceCircularReferencesFn = (options: JSONStringifyOptions) => {
const knownObjects = new WeakSet();
return (key: any, value: any) => {
if (typeof value === 'object' && value !== null) {
if (knownObjects.has(value)) {
return options?.circularRefReplacement ?? '[Circular Reference]';
}
knownObjects.add(value);
}
return value;
};
};

export const jsonStringify = (obj: unknown, options?: JSONStringifyOptions): string => {
try {
if (options?.replaceCircularRefs === true) {
return JSON.stringify(obj, getReplaceCircularReferencesFn(options));
}
return JSON.stringify(obj);
} catch (error) {
// TOOD: handle stringify errors?
throw error;
}
};

export const sleep = async (ms: number): Promise<void> =>
new Promise((resolve) => {
setTimeout(resolve, ms);
Expand Down

0 comments on commit 6c4a154

Please sign in to comment.