From 6f4f422cbdf62f905fbca1c19276a9a1b7f25924 Mon Sep 17 00:00:00 2001 From: Harry Brundage Date: Thu, 20 Apr 2023 14:05:26 -0400 Subject: [PATCH] Exclude the __typename attribute from the .toJSON on records --- .../api-client-core/spec/GadgetRecord.spec.ts | 22 ++++++++++++++++++- packages/api-client-core/src/GadgetRecord.ts | 19 +++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/api-client-core/spec/GadgetRecord.spec.ts b/packages/api-client-core/spec/GadgetRecord.spec.ts index 2b4c118f3..50714fd1f 100644 --- a/packages/api-client-core/spec/GadgetRecord.spec.ts +++ b/packages/api-client-core/spec/GadgetRecord.spec.ts @@ -1,3 +1,4 @@ +import { omit } from "lodash"; import { ChangeTracking, GadgetRecord } from "../src/GadgetRecord"; interface SampleBaseRecord { id?: string; @@ -42,6 +43,7 @@ describe("GadgetRecord", () => { let productBaseRecord: SampleBaseRecord; beforeAll(() => { productBaseRecord = { + __typename: "Product", id: "123", name: "A cool product", body: "A description of why it's cool", @@ -51,7 +53,7 @@ describe("GadgetRecord", () => { it("should respond toJSON, which returns the inner __gadget.fields properties", () => { const product = new GadgetRecord(productBaseRecord); expect(product.toJSON()).toEqual({ - ...productBaseRecord, + ...omit(productBaseRecord, "__typename"), }); }); @@ -403,4 +405,22 @@ describe("GadgetRecord", () => { product.setField("changed", true); expect(product.getField("changed")).toEqual(true); }); + + test("the typename should be accessible on the object if passed when constructing", () => { + const product = new GadgetRecord(productBaseRecord); + expect(product.typename).toEqual("Product"); + }); + + test("the typename should be undefined on the object if not passed when constructing", () => { + const product = new GadgetRecord({}); + expect(product.typename).toBeUndefined(); + }); + + test("the typename should not be included in the toJSON output", () => { + let instance = new GadgetRecord<{ __typename: "foo" }>({ __typename: "foo" }); + expect(instance.toJSON()).toEqual({}); + + instance = new GadgetRecord<{ __typename: "foo"; bar: number }>({ __typename: "foo", bar: 1 }); + expect(instance.toJSON()).toEqual({ bar: 1 }); + }); }); diff --git a/packages/api-client-core/src/GadgetRecord.ts b/packages/api-client-core/src/GadgetRecord.ts index 2d618986c..fdbbd6b92 100644 --- a/packages/api-client-core/src/GadgetRecord.ts +++ b/packages/api-client-core/src/GadgetRecord.ts @@ -22,11 +22,16 @@ export class GadgetRecordImplementation { }; private empty = false; - - constructor(data: Shape) { - this.__gadget.instantiatedFields = cloneDeep(data); - this.__gadget.persistedFields = cloneDeep(data); - Object.assign(this.__gadget.fields, data); + __typename?: string; + + constructor(data?: Shape | null) { + if (data) { + const { __typename, ...fields } = data; + this.__typename = __typename; + this.__gadget.instantiatedFields = cloneDeep(fields); + this.__gadget.persistedFields = cloneDeep(fields); + Object.assign(this.__gadget.fields, fields); + } if (!data || Object.keys(data).length === 0) { this.empty = true; @@ -77,6 +82,10 @@ export class GadgetRecordImplementation { return this.empty; } + get typename(): string | undefined { + return this.__typename; + } + /** Returns the value of the field for the given `apiIdentifier`. These properties may also be accessed on this record directly. This method can be used if your model field `apiIdentifier` conflicts with the `GadgetRecord` helper functions. */ getField(apiIdentifier: string) { return this.__gadget.fields[apiIdentifier];