diff --git a/packages/api-client-core/spec/GadgetRecord.spec.ts b/packages/api-client-core/spec/GadgetRecord.spec.ts index 2b4c118f3..54a58557f 100644 --- a/packages/api-client-core/spec/GadgetRecord.spec.ts +++ b/packages/api-client-core/spec/GadgetRecord.spec.ts @@ -48,6 +48,19 @@ describe("GadgetRecord", () => { }; }); + it("can be constructed with base data", () => { + const product = new GadgetRecord(productBaseRecord); + expect(product).toBeTruthy(); + }); + + it("can be constructed with null or undefined to create a new instance", () => { + let product = new GadgetRecord(null); + expect(product).toBeTruthy(); + + product = new GadgetRecord(); + expect(product).toBeTruthy(); + }); + it("should respond toJSON, which returns the inner __gadget.fields properties", () => { const product = new GadgetRecord(productBaseRecord); expect(product.toJSON()).toEqual({ diff --git a/packages/api-client-core/spec/Select-type.spec.ts b/packages/api-client-core/spec/Select-type.spec.ts new file mode 100644 index 000000000..8a58b7d3f --- /dev/null +++ b/packages/api-client-core/spec/Select-type.spec.ts @@ -0,0 +1,49 @@ +import type { AssertTrue, IsExact } from "conditional-type-checks"; +import type { Select } from "../src/types"; +import type { TestSchema } from "./TestSchema"; + +describe("Select<>", () => { + type _SelectingProperties = AssertTrue, { num: number }>>; + + type _ConditionallySelectingProperties = AssertTrue< + IsExact, { num: number }> + >; + + type _SelectingNestedProperties = AssertTrue< + IsExact< + Select, + { num: number; obj: { test: "test"; deep: { property: string } } } + > + >; + + type _optionalNestedPropertySelection = Select; + type _TestSelectingOptionalNestedProperties = AssertTrue< + IsExact<_optionalNestedPropertySelection, { optionalObj: { test: "test" } | null }> + >; + + type _listSelection = Select; + type _TestSelectingLists = AssertTrue>; + + type _optionalListSelection = Select; + type _TestSelectingOptionalLists = AssertTrue< + IsExact<_optionalListSelection, { optionalList: { title: "listy"; stuff: number[] | null }[] | null }> + >; + + type _connectionSelection = Select< + TestSchema, + { someConnection: { pageInfo: { hasNextPage: true }; edges: { node: { id: true; state: true } } } } + >; + type _TestSelectingConnection = AssertTrue< + IsExact< + _connectionSelection, + { + someConnection: { + pageInfo: { hasNextPage: boolean }; + edges: ({ node: { id: string; state: string } | null } | null)[] | null; + }; + } + > + >; + + test("true", () => undefined); +}); diff --git a/packages/api-client-core/src/GadgetRecord.ts b/packages/api-client-core/src/GadgetRecord.ts index 2d618986c..5a51c4983 100644 --- a/packages/api-client-core/src/GadgetRecord.ts +++ b/packages/api-client-core/src/GadgetRecord.ts @@ -8,7 +8,10 @@ export enum ChangeTracking { SinceLastPersisted, } -export type RecordShape = Record | null | undefined | void; +export interface RecordShape { + __typename?: string; + [key: string]: any; +} /** Represents one record returned from a high level Gadget API call */ export class GadgetRecordImplementation { @@ -23,10 +26,12 @@ 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); + constructor(data?: Shape | null) { + if (data) { + this.__gadget.instantiatedFields = cloneDeep(data); + this.__gadget.persistedFields = cloneDeep(data); + Object.assign(this.__gadget.fields, data); + } if (!data || Object.keys(data).length === 0) { this.empty = true; @@ -193,6 +198,6 @@ export class GadgetRecordImplementation { */ /** Instantiate a `GadgetRecord` with the attributes of your model. A `GadgetRecord` can be used to track changes to your model and persist those changes via Gadget actions. */ -export const GadgetRecord: new (data: Shape) => GadgetRecordImplementation & Shape = +export const GadgetRecord: new (data?: Shape | null) => GadgetRecordImplementation & Shape = GadgetRecordImplementation as any; export type GadgetRecord = GadgetRecordImplementation & Shape;