From b8b18512e2d403e69f66ff6673d106bf5ff68c6a Mon Sep 17 00:00:00 2001 From: ssanjay1 <67482244+ssanjay1@users.noreply.github.com> Date: Wed, 1 May 2024 11:58:38 -0400 Subject: [PATCH] Add fetchOneWithErrors (#250) * add fetchOneWithErrors * add changeset * Add fetchOne (#253) * add fetchpage without errors * add changeset --- .changeset/angry-trees-carry.md | 6 ++ .changeset/slow-kids-hide.md | 6 ++ .../src/__e2e_tests__/actions.test.ts | 15 +++ .../src/__e2e_tests__/loadObjects.test.ts | 93 ++++++++++++++++++ .../src/client/actions/actions.test.ts | 4 + .../src/client/baseTypes/ActionType.ts | 13 ++- .../src/client/baseTypes/links.ts | 26 +++++ .../FilteredPropertiesTerminalOperations.ts | 20 ++++ .../src/client/interfaces/baseObjectSet.ts | 9 ++ .../src/client/net/getLinkedObject.ts | 41 +++++--- .../legacy-client/src/client/net/getObject.ts | 46 ++++++--- .../src/client/net/getOnlyLinkedObject.ts | 30 +++++- .../src/client/net/listLinkedObjects.ts | 55 +++++++---- .../client/objectSets/OsdkObjectSet.test.ts | 95 +++++++++++++++++++ .../src/client/objectSets/OsdkObjectSet.ts | 11 ++- ...sObjectSetWithGetTerminalOperationsStep.ts | 13 ++- .../src/client/objects/createMultiLinkStep.ts | 28 +++++- .../client/objects/createSingleLinkStep.ts | 21 +++- 18 files changed, 475 insertions(+), 57 deletions(-) create mode 100644 .changeset/angry-trees-carry.md create mode 100644 .changeset/slow-kids-hide.md diff --git a/.changeset/angry-trees-carry.md b/.changeset/angry-trees-carry.md new file mode 100644 index 000000000..af21859a7 --- /dev/null +++ b/.changeset/angry-trees-carry.md @@ -0,0 +1,6 @@ +--- +"@osdk/foundry-sdk-generator": patch +"@osdk/legacy-client": patch +--- + +Add fetchone, that is get replacement without result wrapper diff --git a/.changeset/slow-kids-hide.md b/.changeset/slow-kids-hide.md new file mode 100644 index 000000000..bbb5cd849 --- /dev/null +++ b/.changeset/slow-kids-hide.md @@ -0,0 +1,6 @@ +--- +"@osdk/foundry-sdk-generator": patch +"@osdk/legacy-client": patch +--- + +Deprecate get and add fetchonewitherrors, which functionally is the same diff --git a/packages/foundry-sdk-generator/src/__e2e_tests__/actions.test.ts b/packages/foundry-sdk-generator/src/__e2e_tests__/actions.test.ts index 36c9bf19c..1aaa0e49e 100644 --- a/packages/foundry-sdk-generator/src/__e2e_tests__/actions.test.ts +++ b/packages/foundry-sdk-generator/src/__e2e_tests__/actions.test.ts @@ -100,6 +100,21 @@ describe("test", () => { expect(officeImpl.__rid).toBe( "ri.phonograph2-objects.main.object.c0c0c0c0-c0c0-c0c0-c0c0-c0c0c0c0c0c0", ); + const officeResult2: Result = await objectEdit + .fetchOneWithErrors(); + const officeImpl2: Office = assertOkOrThrow(officeResult2); + expect(officeImpl2.__apiName).toBe("Office"); + expect(officeImpl2.__primaryKey).toBe("NYC"); + expect(officeImpl2.__rid).toBe( + "ri.phonograph2-objects.main.object.c0c0c0c0-c0c0-c0c0-c0c0-c0c0c0c0c0c0", + ); + + const officeNoErrors: Office = await objectEdit.fetchOne(); + expect(officeNoErrors.__apiName).toBe("Office"); + expect(officeNoErrors.__primaryKey).toBe("NYC"); + expect(officeNoErrors.__rid).toBe( + "ri.phonograph2-objects.main.object.c0c0c0c0-c0c0-c0c0-c0c0-c0c0c0c0c0c0", + ); } }); diff --git a/packages/foundry-sdk-generator/src/__e2e_tests__/loadObjects.test.ts b/packages/foundry-sdk-generator/src/__e2e_tests__/loadObjects.test.ts index a8815bfce..1b2a7d6c8 100644 --- a/packages/foundry-sdk-generator/src/__e2e_tests__/loadObjects.test.ts +++ b/packages/foundry-sdk-generator/src/__e2e_tests__/loadObjects.test.ts @@ -84,6 +84,39 @@ describe("LoadObjects", () => { expect(destructured.office).toEqual("SF"); }); + it("Loads object which can be destructured with fetchOneWithErrors", async () => { + const result: Result = await client.ontology + .objects.Employee.fetchOneWithErrors( + stubData.employee1.__primaryKey, + ); + + const emp = assertOkOrThrow(result); + expect(emp.employeeId).toEqual(50030); + expect(emp.fullName).toEqual("John Doe"); + expect(emp.office).toEqual("NYC"); + expect(emp.startDate).toEqual(LocalDate.fromISOString("2019-01-01")); + + const destructured: Employee = { ...emp, office: "SF" }; + expect(destructured.fullName).toEqual("John Doe"); + expect(destructured.office).toEqual("SF"); + }); + + it("Loads object which can be destructured with fetchOne", async () => { + const emp: Employee = await client.ontology + .objects.Employee.fetchOne( + stubData.employee1.__primaryKey, + ); + + expect(emp.employeeId).toEqual(50030); + expect(emp.fullName).toEqual("John Doe"); + expect(emp.office).toEqual("NYC"); + expect(emp.startDate).toEqual(LocalDate.fromISOString("2019-01-01")); + + const destructured: Employee = { ...emp, office: "SF" }; + expect(destructured.fullName).toEqual("John Doe"); + expect(destructured.office).toEqual("SF"); + }); + it("Loads object with specified properties", async () => { const result = await client.ontology.objects.Employee.select(["fullName"]) .get(stubData.employee1.__primaryKey); @@ -102,6 +135,40 @@ describe("LoadObjects", () => { expect((emp as any).office).toBeUndefined(); }); + it("Loads object with specified properties - fetchOneWithErrors", async () => { + const result = await client.ontology.objects.Employee.select(["fullName"]) + .fetchOneWithErrors(stubData.employee1.__primaryKey); + + const emp = assertOkOrThrow(result); + + expectTypeOf(emp).toEqualTypeOf<{ + readonly fullName: string | undefined; + readonly __primaryKey: number; + readonly __apiName: "Employee"; + readonly $primaryKey: number; + readonly $apiName: "Employee"; + }>(); + + expect(emp.fullName).toEqual("John Doe"); + expect((emp as any).office).toBeUndefined(); + }); + + it("Loads object with specified properties - fetchOne", async () => { + const emp = await client.ontology.objects.Employee.select(["fullName"]) + .fetchOne(stubData.employee1.__primaryKey); + + expectTypeOf(emp).toEqualTypeOf<{ + readonly fullName: string | undefined; + readonly __primaryKey: number; + readonly __apiName: "Employee"; + readonly $primaryKey: number; + readonly $apiName: "Employee"; + }>(); + + expect(emp.fullName).toEqual("John Doe"); + expect((emp as any).office).toBeUndefined(); + }); + it("Failure to load object", async () => { const result: Result = await client.ontology .objects.Employee.get(1234); @@ -128,6 +195,32 @@ describe("LoadObjects", () => { visitError(err, visitor); }); + it("Failure to load object - fetchOneWithErrors", async () => { + const result: Result = await client.ontology + .objects.Employee.fetchOneWithErrors(1234); + const err = assertErrOrThrow(result); + + const visitor: ErrorVisitor = { + ObjectNotFound: error => { + expect(error).toMatchObject({ + name: "ObjectNotFound", + errorType: "NOT_FOUND", + errorInstanceId: "errorInstanceId", + statusCode: 404, + primaryKey: { + employeeId: "1234", + }, + objectType: "Employee", + }); + }, + default: error => { + throw new Error(`Unexpected error: ${error.errorName as string}`); + }, + }; + + visitError(err, visitor); + }); + it("Load TimeSeries firstPoint and lastPoint", async () => { const result: Result = await client.ontology .objects.Employee.get( diff --git a/packages/legacy-client/src/client/actions/actions.test.ts b/packages/legacy-client/src/client/actions/actions.test.ts index 1337170d2..9f46445bb 100644 --- a/packages/legacy-client/src/client/actions/actions.test.ts +++ b/packages/legacy-client/src/client/actions/actions.test.ts @@ -501,11 +501,15 @@ describe("Actions", () => { "modified": [ { "apiName": "Office", + "fetchOne": [Function], + "fetchOneWithErrors": [Function], "get": [Function], "primaryKey": "SEA", }, { "apiName": "Office", + "fetchOne": [Function], + "fetchOneWithErrors": [Function], "get": [Function], "primaryKey": "NYC", }, diff --git a/packages/legacy-client/src/client/baseTypes/ActionType.ts b/packages/legacy-client/src/client/baseTypes/ActionType.ts index 845919f38..50f3c5531 100644 --- a/packages/legacy-client/src/client/baseTypes/ActionType.ts +++ b/packages/legacy-client/src/client/baseTypes/ActionType.ts @@ -21,7 +21,7 @@ import type { SyncApplyActionResponseV2, } from "@osdk/gateway/types"; import type { ClientContext } from "@osdk/shared.net"; -import { getObject } from "../../client/net/getObject"; +import { getObject, getObjectWithoutErrors } from "../../client/net/getObject"; import type { GetObjectError } from "../errors"; import type { Result } from "../Result"; import type { OntologyObject } from "./OntologyObject"; @@ -66,7 +66,10 @@ export declare type ObjectEdit = { primaryKey: Extract["__primaryKey"]; + /** @deprecated use fetchOneWithErrors instead */ get: () => Promise>; + fetchOneWithErrors: () => Promise>; + fetchOne: () => Promise; }; }[T["$apiName"]]; @@ -228,6 +231,10 @@ function getEdits( apiName: edit.objectType, primaryKey: edit.primaryKey, get: () => getObject(client, edit.objectType, edit.primaryKey), + fetchOneWithErrors: () => + getObject(client, edit.objectType, edit.primaryKey), + fetchOne: () => + getObjectWithoutErrors(client, edit.objectType, edit.primaryKey), }); } if (edit.type === "modifyObject") { @@ -235,6 +242,10 @@ function getEdits( apiName: edit.objectType, primaryKey: edit.primaryKey, get: () => getObject(client, edit.objectType, edit.primaryKey), + fetchOneWithErrors: () => + getObject(client, edit.objectType, edit.primaryKey), + fetchOne: () => + getObjectWithoutErrors(client, edit.objectType, edit.primaryKey), }); } } diff --git a/packages/legacy-client/src/client/baseTypes/links.ts b/packages/legacy-client/src/client/baseTypes/links.ts index a4be30945..b4480b4e0 100644 --- a/packages/legacy-client/src/client/baseTypes/links.ts +++ b/packages/legacy-client/src/client/baseTypes/links.ts @@ -22,8 +22,17 @@ import type { OntologyObject } from "./OntologyObject"; export interface SingleLink { /** * Loads the linked object + * @deprecated use fetchOneWithErrors instead */ get(): Promise>; + /** + * Loads the linked object + */ + fetchOneWithErrors(): Promise>; + /** + * Loads the linked object, without a result wrapper + */ + fetchOne(): Promise; } export interface MultiLink { @@ -31,8 +40,25 @@ export interface MultiLink { * Loads the linked object with the given primary key * * @param primaryKey + * @deprecated use fetchOneWithErrors instead */ get(primaryKey: T["__primaryKey"]): Promise>; + /** + * Loads the linked object with the given primary key + * + * @param primaryKey + */ + fetchOneWithErrors( + primaryKey: T["__primaryKey"], + ): Promise>; + /** + * Loads the linked object with the given primary key, without a result wrapper + * + * @param primaryKey + */ + fetchOne( + primaryKey: T["__primaryKey"], + ): Promise; /** * Gets all the linked objects * @deprecated use asyncIter instead diff --git a/packages/legacy-client/src/client/baseTypes/objectset/FilteredPropertiesTerminalOperations.ts b/packages/legacy-client/src/client/baseTypes/objectset/FilteredPropertiesTerminalOperations.ts index 10508d041..cf3bb5a29 100644 --- a/packages/legacy-client/src/client/baseTypes/objectset/FilteredPropertiesTerminalOperations.ts +++ b/packages/legacy-client/src/client/baseTypes/objectset/FilteredPropertiesTerminalOperations.ts @@ -93,6 +93,7 @@ export type FilteredPropertiesTerminalOperationsWithGet< T extends OntologyObject, V extends Array, > = FilteredPropertiesTerminalOperations & { + /** @deprecated use fetchOneWithErrors */ get( primaryKey: T["$primaryKey"], ): Promise< @@ -104,4 +105,23 @@ export type FilteredPropertiesTerminalOperationsWithGet< GetObjectError > >; + fetchOneWithErrors( + primaryKey: T["$primaryKey"], + ): Promise< + Result< + Pick< + T, + V[number] | "$apiName" | "$primaryKey" | "__apiName" | "__primaryKey" + >, + GetObjectError + > + >; + fetchOne( + primaryKey: T["$primaryKey"], + ): Promise< + Pick< + T, + V[number] | "$apiName" | "$primaryKey" | "__apiName" | "__primaryKey" + > + >; }; diff --git a/packages/legacy-client/src/client/interfaces/baseObjectSet.ts b/packages/legacy-client/src/client/interfaces/baseObjectSet.ts index 2ec6af3f9..1b9bdcf98 100644 --- a/packages/legacy-client/src/client/interfaces/baseObjectSet.ts +++ b/packages/legacy-client/src/client/interfaces/baseObjectSet.ts @@ -35,8 +35,17 @@ export type BaseObjectSetOperations = { properties: Properties; + /** @deprecated use fetchOneWithErrors instead */ get(primaryKey: O["$primaryKey"]): Promise>; + fetchOneWithErrors( + primaryKey: O["$primaryKey"], + ): Promise>; + + fetchOne( + primaryKey: O["$primaryKey"], + ): Promise; + select>( properties: readonly T[], ): FilteredPropertiesTerminalOperationsWithGet; diff --git a/packages/legacy-client/src/client/net/getLinkedObject.ts b/packages/legacy-client/src/client/net/getLinkedObject.ts index e14d38ebc..b83e9a4e1 100644 --- a/packages/legacy-client/src/client/net/getLinkedObject.ts +++ b/packages/legacy-client/src/client/net/getLinkedObject.ts @@ -37,23 +37,14 @@ export function getLinkedObject( linkedObjectPrimaryKey: string, ): Promise> { return wrapResult( - async () => { - const object = await getLinkedObjectV2( - createOpenApiRequest(client.stack, client.fetch), - client.ontology.metadata.ontologyApiName, + async () => + getLinkedObjectNoErrors( + client, sourceApiName, primaryKey, linkTypeApiName, linkedObjectPrimaryKey, - { - select: [], - }, - ); - return convertWireToOsdkObject( - client, - object as WireOntologyObjectV2, - ) as unknown as T; - }, + ), e => handleGetLinkedObjectError( new GetLinkedObjectErrorHandler(), @@ -62,3 +53,27 @@ export function getLinkedObject( ), ); } + +export async function getLinkedObjectNoErrors( + client: ClientContext>, + sourceApiName: string, + primaryKey: any, + linkTypeApiName: string, + linkedObjectPrimaryKey: string, +): Promise { + const object = await getLinkedObjectV2( + createOpenApiRequest(client.stack, client.fetch), + client.ontology.metadata.ontologyApiName, + sourceApiName, + primaryKey, + linkTypeApiName, + linkedObjectPrimaryKey, + { + select: [], + }, + ); + return convertWireToOsdkObject( + client, + object as WireOntologyObjectV2, + ) as unknown as T; +} diff --git a/packages/legacy-client/src/client/net/getObject.ts b/packages/legacy-client/src/client/net/getObject.ts index 0d2fc8f13..fce3e77c1 100644 --- a/packages/legacy-client/src/client/net/getObject.ts +++ b/packages/legacy-client/src/client/net/getObject.ts @@ -32,20 +32,36 @@ export async function getObject( primaryKey: T["$primaryKey"], selectedProperties: ReadonlyArray = [], ): Promise> { - return wrapResult(async () => { - const object = await getObjectV2( - createOpenApiRequest(client.stack, client.fetch), - client.ontology.metadata.ontologyApiName, - objectApiName, - primaryKey.toString(), - { - select: selectedProperties.map(x => x.toString()), - }, - ) as WireOntologyObjectV2; + return wrapResult( + async () => + getObjectWithoutErrors( + client, + objectApiName, + primaryKey, + selectedProperties, + ), + e => handleGetObjectError(new GetObjectErrorHandler(), e, e.parameters), + ); +} + +export async function getObjectWithoutErrors( + client: ClientContext>, + objectApiName: string, + primaryKey: T["$primaryKey"], + selectedProperties: ReadonlyArray = [], +): Promise { + const object = await getObjectV2( + createOpenApiRequest(client.stack, client.fetch), + client.ontology.metadata.ontologyApiName, + objectApiName, + primaryKey.toString(), + { + select: selectedProperties.map(x => x.toString()), + }, + ) as WireOntologyObjectV2; - return convertWireToOsdkObject( - client, - object, - ) as unknown as T; - }, e => handleGetObjectError(new GetObjectErrorHandler(), e, e.parameters)); + return convertWireToOsdkObject( + client, + object, + ) as unknown as T; } diff --git a/packages/legacy-client/src/client/net/getOnlyLinkedObject.ts b/packages/legacy-client/src/client/net/getOnlyLinkedObject.ts index 863eea5d6..f0948805b 100644 --- a/packages/legacy-client/src/client/net/getOnlyLinkedObject.ts +++ b/packages/legacy-client/src/client/net/getOnlyLinkedObject.ts @@ -15,11 +15,14 @@ */ import type { OntologyDefinition } from "@osdk/api"; -import type { ClientContext } from "@osdk/shared.net"; +import { type ClientContext, PalantirApiError } from "@osdk/shared.net"; import type { OntologyObject, ParameterValue } from "../baseTypes"; import type { GetLinkedObjectError, LinkedObjectNotFound } from "../errors"; import { isErr, type Result } from "../Result"; -import { listLinkedObjects } from "./listLinkedObjects"; +import { + listLinkedObjects, + listLinkedObjectsWithoutErrors, +} from "./listLinkedObjects"; import { createErrorResponse } from "./util/ResponseCreators"; /** @@ -79,3 +82,26 @@ export async function getOnlyLinkedObject< return { type: "ok", value: result.value[0] }; } + +export async function getOnlyLinkedObjectNoErrors< + T extends OntologyObject = OntologyObject, +>( + client: ClientContext>, + sourceObjectType: string, + sourcePrimaryKey: NonNullable, + targetLinkType: string, +): Promise { + const result = await listLinkedObjectsWithoutErrors( + client, + sourceObjectType, + sourcePrimaryKey, + targetLinkType, + ); + if (result.length !== 1) { + throw new PalantirApiError( + `Expected a single result but got ${result.length} instead`, + ); + } + + return result[0]; +} diff --git a/packages/legacy-client/src/client/net/listLinkedObjects.ts b/packages/legacy-client/src/client/net/listLinkedObjects.ts index d596093f3..a2784e50f 100644 --- a/packages/legacy-client/src/client/net/listLinkedObjects.ts +++ b/packages/legacy-client/src/client/net/listLinkedObjects.ts @@ -34,27 +34,13 @@ export function listLinkedObjects( linkTypeApiName: T["__apiName"], ): Promise> { return wrapResult( - async () => { - const allObjects: T[] = []; - - let page: Page | undefined; - do { - page = await getLinkedObjectsPage( - client, - sourceApiName, - primaryKey, - linkTypeApiName, - { - pageToken: page?.nextPageToken, - }, - ); - for (const object of page.data) { - allObjects.push(object); - } - } while (page.nextPageToken); - - return allObjects; - }, + async () => + listLinkedObjectsWithoutErrors( + client, + sourceApiName, + primaryKey, + linkTypeApiName, + ), e => handleListLinkedObjectsError( new ListLinkedObjectsErrorHandler(), @@ -64,6 +50,33 @@ export function listLinkedObjects( ); } +export async function listLinkedObjectsWithoutErrors( + client: ClientContext>, + sourceApiName: string, + primaryKey: any, + linkTypeApiName: T["__apiName"], +): Promise { + const allObjects: T[] = []; + + let page: Page | undefined; + do { + page = await getLinkedObjectsPage( + client, + sourceApiName, + primaryKey, + linkTypeApiName, + { + pageToken: page?.nextPageToken, + }, + ); + for (const object of page.data) { + allObjects.push(object); + } + } while (page.nextPageToken); + + return allObjects; +} + export async function* loadLinkedObjects( client: ClientContext>, sourceApiName: string, diff --git a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts index e77f3c8fd..d15da815b 100644 --- a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts +++ b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts @@ -305,6 +305,39 @@ describe("OsdkObjectSet", () => { expect(result.type).toEqual("ok"); }); + it("supports select methods - fetchOneWithErrors", async () => { + const os = createBaseObjectSet(client, "Todo"); + mockFetchResponse(fetch, getMockTodoObject()); + const result = await os.select(["id", "body", "complete"]) + .fetchOneWithErrors("123"); + expect(fetch).toHaveBeenCalledOnce(); + expect(fetch).toHaveBeenCalledWith( + `${baseUrl}Ontology/objects/Todo/123?select=id&select=body&select=complete`, + { + method: "GET", + body: undefined, + headers: expect.anything(), + }, + ); + expect(result.type).toEqual("ok"); + }); + + it("supports select methods - fetchOne", async () => { + const os = createBaseObjectSet(client, "Todo"); + mockFetchResponse(fetch, getMockTodoObject()); + const result = await os.select(["id", "body", "complete"]) + .fetchOne("123"); + expect(fetch).toHaveBeenCalledOnce(); + expect(fetch).toHaveBeenCalledWith( + `${baseUrl}Ontology/objects/Todo/123?select=id&select=body&select=complete`, + { + method: "GET", + body: undefined, + headers: expect.anything(), + }, + ); + }); + it("supports round-trip of circular links", async () => { const os = createBaseObjectSet(client, "Todo"); mockFetchResponse(fetch, getMockTodoObject()); @@ -331,6 +364,52 @@ describe("OsdkObjectSet", () => { expect(linkedTodosResponse.value.length).toEqual(1); }); + it("supports round-trip of circular links -fetchOneWithErrors", async () => { + const os = createBaseObjectSet(client, "Todo"); + mockFetchResponse(fetch, getMockTodoObject()); + const todoResponse = await os.fetchOneWithErrors("1"); + + if (!isOk(todoResponse)) { + expect.fail("todo response was not ok"); + } + + mockObjectPage([getMockTaskObject()]); + const taskResponse = await todoResponse.value.linkedTask + .fetchOneWithErrors(); + + if (!isOk(taskResponse)) { + expect.fail("task response was not ok"); + } + + mockObjectPage([getMockTodoObject()]); + const linkedTodosResponse = await taskResponse.value.linkedTodos.all(); + + if (!isOk(linkedTodosResponse)) { + expect.fail("linked todos response was not ok"); + } + + expect(linkedTodosResponse.value.length).toEqual(1); + }); + + it("supports round-trip of circular links -fetchOne", async () => { + const os = createBaseObjectSet(client, "Todo"); + mockFetchResponse(fetch, getMockTodoObject()); + const todoResponse = await os.fetchOne("1"); + + mockObjectPage([getMockTaskObject()]); + const taskResponse = await todoResponse.linkedTask + .fetchOne(); + + mockObjectPage([getMockTodoObject()]); + const linkedTodosResponse = await taskResponse.linkedTodos.all(); + + if (!isOk(linkedTodosResponse)) { + expect.fail("linked todos response was not ok"); + } + + expect(linkedTodosResponse.value.length).toEqual(1); + }); + it("supports round-trip of circular links with asynciter", async () => { const os = createBaseObjectSet(client, "Todo"); mockFetchResponse(fetch, getMockTodoObject()); @@ -502,6 +581,22 @@ describe("OsdkObjectSet", () => { await todo2.linkedTask.get(); expect(fetch1).toHaveBeenCalledOnce(); expect(fetch2).toHaveBeenCalledOnce(); + + await todo1.linkedTask.fetchOneWithErrors(); + expect(fetch1).toHaveBeenCalledTimes(2); + expect(fetch2).toHaveBeenCalledTimes(1); + + await todo2.linkedTask.fetchOneWithErrors(); + expect(fetch1).toHaveBeenCalledTimes(2); + expect(fetch2).toHaveBeenCalledTimes(2); + + await todo1.linkedTask.fetchOne(); + expect(fetch1).toHaveBeenCalledTimes(3); + expect(fetch2).toHaveBeenCalledTimes(2); + + await todo2.linkedTask.fetchOne(); + expect(fetch1).toHaveBeenCalledTimes(3); + expect(fetch2).toHaveBeenCalledTimes(3); }); function mockObjectPage( diff --git a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.ts b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.ts index 8bd499ab4..5ca9d468a 100644 --- a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.ts +++ b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.ts @@ -34,7 +34,7 @@ import type { LinksProperties, SelectableProperties, } from "../interfaces/utils/OmitProperties"; -import { getObject } from "../net/getObject"; +import { getObject, getObjectWithoutErrors } from "../net/getObject"; import type { OsdkLegacyObjectFrom } from "../OsdkLegacyObject"; import { createCachedOntologyTransform } from "./createCachedOntologyTransform"; import { createFilteredPropertiesObjectSetWithGetTerminalOperationsStep } from "./createFilteredPropertiesObjectSetWithGetTerminalOperationsStep"; @@ -198,6 +198,15 @@ export function createBaseOsdkObjectSet< get(primaryKey) { return getObject(client, apiName, primaryKey); }, + + fetchOneWithErrors(primaryKey) { + return getObject(client, apiName, primaryKey); + }, + + fetchOne(primaryKey) { + return getObjectWithoutErrors(client, apiName, primaryKey); + }, + select(properties) { return createFilteredPropertiesObjectSetWithGetTerminalOperationsStep( client, diff --git a/packages/legacy-client/src/client/objectSets/createFilteredPropertiesObjectSetWithGetTerminalOperationsStep.ts b/packages/legacy-client/src/client/objectSets/createFilteredPropertiesObjectSetWithGetTerminalOperationsStep.ts index 4f424aa1d..67536e8a4 100644 --- a/packages/legacy-client/src/client/objectSets/createFilteredPropertiesObjectSetWithGetTerminalOperationsStep.ts +++ b/packages/legacy-client/src/client/objectSets/createFilteredPropertiesObjectSetWithGetTerminalOperationsStep.ts @@ -21,7 +21,7 @@ import type { ObjectSetDefinition, } from ".."; import type { SelectableProperties } from "../interfaces/utils/OmitProperties"; -import { getObject } from "../net/getObject"; +import { getObject, getObjectWithoutErrors } from "../net/getObject"; import { loadAllObjects } from "../net/loadObjects"; import { loadObjectsIterator, @@ -98,5 +98,16 @@ export function createFilteredPropertiesObjectSetWithGetTerminalOperationsStep< get(primaryKey) { return getObject(client, apiName as string, primaryKey, properties); }, + fetchOneWithErrors(primaryKey) { + return getObject(client, apiName as string, primaryKey, properties); + }, + fetchOne(primaryKey) { + return getObjectWithoutErrors( + client, + apiName as string, + primaryKey, + properties, + ); + }, }; } diff --git a/packages/legacy-client/src/client/objects/createMultiLinkStep.ts b/packages/legacy-client/src/client/objects/createMultiLinkStep.ts index 5f46c8732..0ed36e6cb 100644 --- a/packages/legacy-client/src/client/objects/createMultiLinkStep.ts +++ b/packages/legacy-client/src/client/objects/createMultiLinkStep.ts @@ -17,7 +17,10 @@ import type { ClientContext } from "@osdk/shared.net"; import type { MultiLink, OntologyObject, ParameterValue } from "../baseTypes"; import type { GetLinkedObjectError, ListLinkedObjectsError } from "../errors"; -import { getLinkedObject } from "../net/getLinkedObject"; +import { + getLinkedObject, + getLinkedObjectNoErrors, +} from "../net/getLinkedObject"; import { listLinkedObjects, loadLinkedObjects } from "../net/listLinkedObjects"; import { pageLinkedObjects, @@ -44,7 +47,28 @@ export function createMultiLinkStep( primaryKey.toString(), ); }, - + fetchOneWithErrors( + primaryKey: T["__primaryKey"], + ): Promise> { + return getLinkedObject( + client, + sourceApiName, + sourcePrimaryKey, + targetApiName, + primaryKey.toString(), + ); + }, + fetchOne( + primaryKey: T["__primaryKey"], + ): Promise { + return getLinkedObjectNoErrors( + client, + sourceApiName, + sourcePrimaryKey, + targetApiName, + primaryKey.toString(), + ); + }, all(): Promise> { return listLinkedObjects( client, diff --git a/packages/legacy-client/src/client/objects/createSingleLinkStep.ts b/packages/legacy-client/src/client/objects/createSingleLinkStep.ts index d9de6eae5..fedc1b581 100644 --- a/packages/legacy-client/src/client/objects/createSingleLinkStep.ts +++ b/packages/legacy-client/src/client/objects/createSingleLinkStep.ts @@ -18,7 +18,10 @@ import type { ClientContext } from "@osdk/shared.net"; import type { OntologyObject, ParameterValue, SingleLink } from "../baseTypes"; import type { GetLinkedObjectError } from "../errors"; -import { getOnlyLinkedObject } from "../net/getOnlyLinkedObject"; +import { + getOnlyLinkedObject, + getOnlyLinkedObjectNoErrors, +} from "../net/getOnlyLinkedObject"; import type { Result } from "../Result"; export function createSingleLinkStep( @@ -36,5 +39,21 @@ export function createSingleLinkStep( targetLinkType, ); }, + async fetchOneWithErrors(): Promise> { + return getOnlyLinkedObject( + client, + sourceObjectType, + sourcePrimaryKey, + targetLinkType, + ); + }, + async fetchOne(): Promise { + return getOnlyLinkedObjectNoErrors( + client, + sourceObjectType, + sourcePrimaryKey, + targetLinkType, + ); + }, }; }