From b905a8bedbefd82473a668ace898c2d281a42ce1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 10:31:39 +0100 Subject: [PATCH 1/4] docs: add samtgarson as a contributor (#113) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0922be2..a97defe 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -104,6 +104,15 @@ "code", "ideas" ] + }, + { + "login": "samtgarson", + "name": "Sam Garson", + "avatar_url": "https://avatars.githubusercontent.com/u/6242344?v=4", + "profile": "https://www.samgarson.com", + "contributions": [ + "bug" + ] } ], "badgeTemplate": "-orange.svg?style=flat-square\" alt=\"All Contributors\"/>", diff --git a/README.md b/README.md index 0a52d0e..de11812 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

-All Contributors +All Contributors npm @@ -237,6 +237,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Piotr Monwid-Olechnowicz

🤔
Alex Johansson

💻 ⚠️
Simon Edelmann

🐛 💻 🤔 +
Sam Garson

🐛 From 753cc5d053f95c3fbc1502688d663e504d4849c7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 10:33:09 +0100 Subject: [PATCH 2/4] docs: add markhughes as a contributor (#114) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a97defe..8461c17 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -113,6 +113,15 @@ "contributions": [ "bug" ] + }, + { + "login": "markhughes", + "name": "Mark Hughes", + "avatar_url": "https://avatars.githubusercontent.com/u/1357323?v=4", + "profile": "http://twitter.com/_markeh", + "contributions": [ + "bug" + ] } ], "badgeTemplate": "-orange.svg?style=flat-square\" alt=\"All Contributors\"/>", diff --git a/README.md b/README.md index de11812..e291427 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

-All Contributors +All Contributors npm @@ -238,6 +238,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Alex Johansson

💻 ⚠️
Simon Edelmann

🐛 💻 🤔
Sam Garson

🐛 +
Mark Hughes

🐛 From c80ccba1e243c06b30271163446989d38b6943c4 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 3 Feb 2021 08:50:36 +0100 Subject: [PATCH 3/4] Implement "allowProps" (#115) --- src/class-registry.ts | 31 ++++++++++++++++++++++++++++++- src/index.test.ts | 27 ++++++++++++++++++++++++++- src/index.ts | 6 +++--- src/transformer.ts | 13 ++++++++++++- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/class-registry.ts b/src/class-registry.ts index 1f12fd0..211a757 100644 --- a/src/class-registry.ts +++ b/src/class-registry.ts @@ -1,4 +1,33 @@ import { Registry } from './registry'; import { Class } from './types'; -export const ClassRegistry = new Registry(c => c.name); +export interface RegisterOptions { + identifier?: string; + allowProps?: string[]; +} + +class _ClassRegistry extends Registry { + constructor() { + super(c => c.name); + } + + private classToAllowedProps = new Map(); + + register(value: Class, options?: string | RegisterOptions): void { + if (typeof options === 'object') { + if (options.allowProps) { + this.classToAllowedProps.set(value, options.allowProps); + } + + super.register(value, options.identifier); + } else { + super.register(value, options); + } + } + + getAllowedProps(value: Class): string[] | undefined { + return this.classToAllowedProps.get(value); + } +} + +export const ClassRegistry = new _ClassRegistry(); diff --git a/src/index.test.ts b/src/index.test.ts index 0a33c9c..3cc5d27 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -16,6 +16,7 @@ describe('stringify & parse', () => { output: JSONValue | ((v: JSONValue) => void); outputAnnotations?: Annotations; customExpectations?: (value: any) => void; + dontExpectEquality?: boolean; } > = { 'works for objects': { @@ -514,6 +515,27 @@ describe('stringify & parse', () => { }, }, + 'works with custom allowedProps': { + input: () => { + class User { + constructor(public username: string, public password: string) {} + } + SuperJSON.registerClass(User, { allowProps: ['username'] }); + return new User('bongocat', 'supersecurepassword'); + }, + output: { + username: 'bongocat', + }, + outputAnnotations: { + values: [['class', 'User']], + }, + customExpectations(value) { + expect(value.password).toBeUndefined(); + expect(value.username).toBe('bongocat'); + }, + dontExpectEquality: true, + }, + 'works for undefined, issue #48': { input: undefined, output: null, @@ -561,6 +583,7 @@ describe('stringify & parse', () => { output: expectedOutput, outputAnnotations: expectedOutputAnnotations, customExpectations, + dontExpectEquality, }, ] of Object.entries(cases)) { test(testName, () => { @@ -578,7 +601,9 @@ describe('stringify & parse', () => { expect(meta).toEqual(expectedOutputAnnotations); const untransformed = SuperJSON.deserialize({ json, meta }); - expect(untransformed).toEqual(inputValue); + if (!dontExpectEquality) { + expect(untransformed).toEqual(inputValue); + } customExpectations?.(untransformed); }); } diff --git a/src/index.ts b/src/index.ts index 52caaac..ab3fe24 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { Class, JSONValue, } from './types'; -import { ClassRegistry } from './class-registry'; +import { ClassRegistry, RegisterOptions } from './class-registry'; import { SymbolRegistry } from './symbol-registry'; import { CustomTransfomer, @@ -52,8 +52,8 @@ const stringify = (object: SuperJSONValue): string => export const parse = (string: string): T => deserialize(JSON.parse(string)); -const registerClass = (v: Class, identifier?: string) => - ClassRegistry.register(v, identifier); +const registerClass = (v: Class, options?: RegisterOptions) => + ClassRegistry.register(v, options); const registerSymbol = (v: Symbol, identifier?: string) => SymbolRegistry.register(v, identifier); diff --git a/src/transformer.ts b/src/transformer.ts index aee8956..0b8d26a 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -232,7 +232,18 @@ const classRule = compositeTransformation( const identifier = ClassRegistry.getIdentifier(clazz.constructor); return ['class', identifier!]; }, - v => v, + clazz => { + const allowedProps = ClassRegistry.getAllowedProps(clazz.constructor); + if (!allowedProps) { + return clazz; + } + + const result: any = {}; + allowedProps.forEach(prop => { + result[prop] = clazz[prop]; + }); + return result; + }, (v, a) => { const clazz = ClassRegistry.getValue(a[1]); From e97fd0034ab74bda969b0b1d32519bdb9f5687a3 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 3 Feb 2021 08:50:49 +0100 Subject: [PATCH 4/4] Fix #108 (#111) * Error.stack should not be included by default * Add regression test --- src/index.test.ts | 19 ++++++++++++++++--- src/transformer.ts | 1 - 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index 3cc5d27..dad287d 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -189,9 +189,6 @@ describe('stringify & parse', () => { output: ({ e }: any) => { expect(e.name).toBe('Error'); expect(e.message).toBe('epic fail'); - expect(e.stack.startsWith('Error: epic fail\n at Suite.')).toBe( - true - ); }, outputAnnotations: { values: { @@ -868,3 +865,19 @@ test('regression #95: no undefined', () => { expect(parsed).toEqual(input); }); + +test('regression #108: Error#stack should not be included by default', () => { + const input = new Error("Beep boop, you don't wanna see me. I'm an error!"); + expect(input).toHaveProperty('stack'); + + const { stack: thatShouldBeUndefined } = SuperJSON.parse( + SuperJSON.stringify(input) + ) as any; + expect(thatShouldBeUndefined).toBeUndefined(); + + SuperJSON.allowErrorProps('stack'); + const { stack: thatShouldExist } = SuperJSON.parse( + SuperJSON.stringify(input) + ) as any; + expect(thatShouldExist).toEqual(input.stack); +}); diff --git a/src/transformer.ts b/src/transformer.ts index 0b8d26a..ad2735e 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -107,7 +107,6 @@ const simpleRules = [ const baseError: any = { name: v.name, message: v.message, - stack: v.stack, }; allowedErrorProps.forEach(prop => {