From c5fd1e6af87c80be0f23b59182966658f09192ed Mon Sep 17 00:00:00 2001 From: Saurav Date: Thu, 6 Jun 2024 13:35:54 -0400 Subject: [PATCH 01/21] starting queries work --- packages/client.api/src/index.ts | 1 + packages/client.api/src/queries/Queries.ts | 44 ++++++++++++++++++++++ packages/client/src/Client.ts | 10 ++++- packages/client/src/createClient.ts | 12 +++++- 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 packages/client.api/src/queries/Queries.ts diff --git a/packages/client.api/src/index.ts b/packages/client.api/src/index.ts index 3beb0554e..746d499f5 100644 --- a/packages/client.api/src/index.ts +++ b/packages/client.api/src/index.ts @@ -32,6 +32,7 @@ export type { Attachment } from "./object/Attachment.js"; export type { BaseObjectSet } from "./objectSet/BaseObjectSet.js"; export type { OsdkBase } from "./OsdkBase.js"; export type { OsdkObjectPrimaryKeyType } from "./OsdkObjectPrimaryKeyType.js"; +export type { QuerySignatureFromDef } from "./queries/Queries.js"; export type { NOOP } from "./util/NOOP.js"; export {}; diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts new file mode 100644 index 000000000..aaad15722 --- /dev/null +++ b/packages/client.api/src/queries/Queries.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + OntologyDefinition, + QueryDataTypeDefinition, + QueryDefinition, +} from "@osdk/api"; +import type { NOOP } from "../index.js"; +import type { PartialByNotStrict } from "../util/PartialBy.js"; + +export type Queries> = { + [K in keyof O["queries"]]: QuerySignatureFromDef; +}; + +export type QuerySignatureFromDef> = + keyof T["parameters"] extends never ? ( + params: QueryParameterType, + ) => Promise> + : () => Promise>; + +export type QueryParameterType< + T extends Record>, +> = NOOP>>; + +export type QueryReturnType> = T; + +type OptionalQueryParams>> = + { + [K in keyof T]: T[K] extends { nullable: true } ? never : K; + }[keyof T]; diff --git a/packages/client/src/Client.ts b/packages/client/src/Client.ts index 0be93c682..8cb90cd74 100644 --- a/packages/client/src/Client.ts +++ b/packages/client/src/Client.ts @@ -17,9 +17,13 @@ import type { ActionDefinition, ObjectTypeDefinition, + QueryDefinition, VersionBound, } from "@osdk/api"; -import type { ActionSignatureFromDef } from "@osdk/client.api"; +import type { + ActionSignatureFromDef, + QuerySignatureFromDef, +} from "@osdk/client.api"; import type { SharedClient } from "@osdk/shared.client"; import type { MinimalClient } from "./MinimalClientContext.js"; import type { ObjectSet } from "./objectSet/ObjectSet.js"; @@ -42,6 +46,10 @@ export interface Client extends SharedClient { >( o: CheckVersionBound, ): ActionSignatureFromDef; + + >( + o: CheckVersionBound, + ): QuerySignatureFromDef; } // BEGIN: THIS IS GENERATED CODE. DO NOT EDIT. diff --git a/packages/client/src/createClient.ts b/packages/client/src/createClient.ts index bf73016aa..e3582db38 100644 --- a/packages/client/src/createClient.ts +++ b/packages/client/src/createClient.ts @@ -19,8 +19,12 @@ import type { InterfaceDefinition, ObjectOrInterfaceDefinition, ObjectTypeDefinition, + QueryDefinition, } from "@osdk/api"; -import type { ActionSignatureFromDef } from "@osdk/client.api"; +import type { + ActionSignatureFromDef, + QuerySignatureFromDef, +} from "@osdk/client.api"; import { symbolClientContext } from "@osdk/shared.client"; import type { Logger } from "pino"; import { createActionInvoker } from "./actions/createActionInvoker.js"; @@ -51,10 +55,12 @@ export function createClientInternal( function clientFn< T extends | ObjectOrInterfaceDefinition - | ActionDefinition, + | ActionDefinition + | QueryDefinition, >(o: T): T extends ObjectTypeDefinition ? ObjectSet : T extends InterfaceDefinition ? MinimalObjectSet : T extends ActionDefinition ? ActionSignatureFromDef + : T extends QueryDefinition ? QuerySignatureFromDef : never { if (o.type === "object" || o.type === "interface") { @@ -65,6 +71,8 @@ export function createClientInternal( return createActionInvoker(clientCtx, o) as ActionSignatureFromDef< any > as any; + } else if (o.type === "query") { + return undefined as any; } else { throw new Error("not implemented"); } From e1d196976ab3e95562651e3bf0fb3a0772989068 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 18 Jun 2024 13:14:04 -0400 Subject: [PATCH 02/21] first pass, no tests --- packages/api/src/ontology/QueryDefinition.ts | 3 + packages/client.api/src/index.ts | 11 +- .../src/mapping/DataValueMapping.ts | 7 + packages/client.api/src/queries/Queries.ts | 7 +- .../src/queries/queryObjectResponse.ts | 21 ++ packages/client/src/createClient.ts | 5 +- packages/client/src/queries/applyQuery.ts | 321 ++++++++++++++++++ .../client/src/queries/createQueryInvoker.ts | 29 ++ packages/client/src/util/datamapping.ts | 45 +++ .../client/src/util/toDataValueQueries.ts | 129 +++++++ 10 files changed, 574 insertions(+), 4 deletions(-) create mode 100644 packages/client.api/src/queries/queryObjectResponse.ts create mode 100644 packages/client/src/queries/applyQuery.ts create mode 100644 packages/client/src/queries/createQueryInvoker.ts create mode 100644 packages/client/src/util/datamapping.ts create mode 100644 packages/client/src/util/toDataValueQueries.ts diff --git a/packages/api/src/ontology/QueryDefinition.ts b/packages/api/src/ontology/QueryDefinition.ts index d5574144f..f9df6fcd8 100644 --- a/packages/api/src/ontology/QueryDefinition.ts +++ b/packages/api/src/ontology/QueryDefinition.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import type { OsdkMetadata } from "../OsdkMetadata.js"; + export interface QueryDefinition { type: "query"; apiName: Q; @@ -22,6 +24,7 @@ export interface QueryDefinition { version: string; parameters: Record>; output: QueryDataTypeDefinition; + osdkMetadata?: OsdkMetadata; } export type QueryParameterDefinition = { diff --git a/packages/client.api/src/index.ts b/packages/client.api/src/index.ts index 286fb8c51..8e49647f3 100644 --- a/packages/client.api/src/index.ts +++ b/packages/client.api/src/index.ts @@ -25,6 +25,10 @@ export type { ApplyBatchActionOptions, OsdkActionParameters, } from "./actions/Actions.js"; +export type { + DataValueClientToWire, + DataValueWireToClient, +} from "./mapping/DataValueMapping.js"; export type { PropertyValueClientToWire, PropertyValueWireToClient, @@ -38,7 +42,12 @@ export type { export type { BaseObjectSet } from "./objectSet/BaseObjectSet.js"; export type { OsdkBase } from "./OsdkBase.js"; export type { OsdkObjectPrimaryKeyType } from "./OsdkObjectPrimaryKeyType.js"; -export type { QuerySignatureFromDef } from "./queries/Queries.js"; +export type { + QueryParameterType, + QueryReturnType, + QuerySignatureFromDef, +} from "./queries/Queries.js"; +export type { QueryObjectResponse } from "./queries/queryObjectResponse.js"; export type { NOOP } from "./util/NOOP.js"; export {}; diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index 5cae4a960..ba775cddb 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -15,6 +15,7 @@ */ import type { Attachment, AttachmentUpload } from "../object/Attachment.js"; +import type { QueryObjectResponse } from "../queries/queryObjectResponse.js"; /** * Map from the DataValue type to the typescript type that we return @@ -54,4 +55,10 @@ export interface DataValueClientToWire { short: number; string: string; timestamp: string; + set: Set; + twoDimensionalAggregation: Record; + threeDimensionalAggregation: Record>; + struct: Record; + object: QueryObjectResponse; + objectSet: never; } diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts index aaad15722..16b3fcec0 100644 --- a/packages/client.api/src/queries/Queries.ts +++ b/packages/client.api/src/queries/Queries.ts @@ -19,7 +19,7 @@ import type { QueryDataTypeDefinition, QueryDefinition, } from "@osdk/api"; -import type { NOOP } from "../index.js"; +import type { DataValueClientToWire, NOOP } from "../index.js"; import type { PartialByNotStrict } from "../util/PartialBy.js"; export type Queries> = { @@ -36,7 +36,10 @@ export type QueryParameterType< T extends Record>, > = NOOP>>; -export type QueryReturnType> = T; +export type QueryReturnType> = + T["type"] extends keyof DataValueClientToWire + ? DataValueClientToWire[T["type"]] + : never; type OptionalQueryParams>> = { diff --git a/packages/client.api/src/queries/queryObjectResponse.ts b/packages/client.api/src/queries/queryObjectResponse.ts new file mode 100644 index 000000000..9cdbf0083 --- /dev/null +++ b/packages/client.api/src/queries/queryObjectResponse.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface QueryObjectResponse { + apiName: N; + objectType: string; + primaryKey: string; +} diff --git a/packages/client/src/createClient.ts b/packages/client/src/createClient.ts index bb34963fd..c375ac3d9 100644 --- a/packages/client/src/createClient.ts +++ b/packages/client/src/createClient.ts @@ -38,6 +38,7 @@ import { isAttachment } from "./object/Attachment.js"; import { createObjectSet } from "./objectSet/createObjectSet.js"; import type { MinimalObjectSet, ObjectSet } from "./objectSet/ObjectSet.js"; import type { ObjectSetFactory } from "./objectSet/ObjectSetFactory.js"; +import { createQueryInvoker } from "./queries/createQueryInvoker.js"; export function createClientInternal( objectSetFactory: ObjectSetFactory, // first so i can bind @@ -81,7 +82,9 @@ export function createClientInternal( any > as any; } else if (o.type === "query") { - return undefined as any; + return createQueryInvoker(clientCtx, o) as QuerySignatureFromDef< + any + > as any; } else { throw new Error("not implemented"); } diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts new file mode 100644 index 000000000..ad6ff2610 --- /dev/null +++ b/packages/client/src/queries/applyQuery.ts @@ -0,0 +1,321 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + ObjectOrInterfaceDefinition, + QueryDataTypeDefinition, + QueryDefinition, + QueryParameterDefinition, +} from "@osdk/api"; +import type { + DataValueWireToClient, + QueryObjectResponse, + QueryParameterType, + QueryReturnType, +} from "@osdk/client.api"; +import type { + DataValue, + ObjectSet as WireObjectSet, +} from "@osdk/internal.foundry"; +import { OntologiesV2 } from "@osdk/internal.foundry"; +import type { MinimalClient } from "../MinimalClientContext.js"; +import { Attachment } from "../object/Attachment.js"; +import { createObjectSet } from "../objectSet/createObjectSet.js"; +import { addUserAgent } from "../util/addUserAgent.js"; +import { toDataValue } from "../util/toDataValue.js"; +import { toDataValueQueries } from "../util/toDataValueQueries.js"; + +export async function applyQuery< + QD extends QueryDefinition, + P extends QueryParameterType, +>( + client: MinimalClient, + query: QD, + params?: P, +): Promise< + QueryReturnType +> { + const response = await OntologiesV2.QueryTypes.executeQueryV2( + addUserAgent(client, query), + client.ontologyRid, + query.apiName, + { + parameters: params + ? await remapQueryParams( + params as { [parameterId: string]: any }, + client, + query.parameters, + ) + : {}, + }, + ); + const remappedResponse = await remapQueryResponse( + client, + query.output, + response.value, + ); + return remappedResponse; +} + +async function remapQueryParams( + params: { [parameterId: string]: any }, + client: MinimalClient, + paramTypes: Record>, +): Promise<{ [parameterId: string]: any }> { + const parameterMap: { [parameterName: string]: unknown } = {}; + for (const [key, value] of Object.entries(params)) { + parameterMap[key] = await toDataValueQueries( + value, + client, + paramTypes[key], + ); + } + + return parameterMap; +} + +async function remapQueryResponse< + K extends string, + T extends QueryDataTypeDefinition, +>( + client: MinimalClient, + responseDataType: T, + responseValue: DataValue, + // definitions: Map, +): Promise> { + // handle null responses + if (responseValue == null) { + if (responseDataType.nullable) { + return undefined as unknown as QueryReturnType; + } else { + throw new Error("Got null response when nullable was not allowed"); + } + } + + if (responseDataType.multiplicity !== false) { + const withoutMultiplicity = { ...responseDataType, multiplicity: false }; + for (let i = 0; i < responseValue.length; i++) { + responseValue[i] = remapQueryResponse( + responseValue[i], + withoutMultiplicity, + client, + ); + } + return responseValue as QueryReturnType; + } + + switch (responseDataType.type) { + case "union": { + throw new Error("Union return types are not supported"); + } + + case "set": { + for (let i = 0; i < responseValue.length; i++) { + responseValue[i] = remapQueryResponse( + responseValue[i], + responseDataType.set, + client, + ); + } + + return responseValue as QueryReturnType; + } + + case "attachment": { + return new Attachment(responseValue) as QueryReturnType< + typeof responseDataType + >; + } + case "object": { + return createQueryObjectResponse( + responseDataType.object, + responseValue, + responseDataType.object, + ) as QueryReturnType< + typeof responseDataType + >; + } + // const def = definitions.get(responseDataType.object); + // const withPk: WireObjectSet = { + // type: "filter", + // objectSet: { + // type: "base", + // objectType: responseDataType.object, + // }, + // where: { + // type: "eq", + // field: def?.properties["pr"], + // value: primaryKey, + // }, + // }; + // } + + // return await fetchSingle( + // clientCtx, + // objectType, + // options, + // withPk, + // ) as Osdk; + case "objectSet": { + throw new Error("not implemented"); + // const def = definitions.get(responseDataType.objectSet); + // if (!def) { + // throw new Error( + // `Missing definition for ${responseDataType.objectSet}`, + // ); + // } + // if (typeof responseValue === "string") { + // return createObjectSet(def, client, { + // type: "intersect", + // objectSets: [ + // { type: "base", objectType: responseDataType.objectSet }, + // { type: "reference", reference: responseValue }, + // ], + // }) as unknown as QueryReturnType; + // } + + // return createObjectSet( + // def, + // client, + // responseValue, + // ) as unknown as QueryReturnType< + // typeof responseDataType + // >; + } + case "struct": { + // figure out what keys need to be fixed up + for (const [key, subtype] of Object.entries(responseDataType.struct)) { + if (requiresConversion(subtype)) { + responseValue[key] = remapQueryResponse( + responseValue[key], + subtype, + client, + ); + } + } + + return responseValue as QueryReturnType; + } + case "twoDimensionalAggregation": { + const result: Record = {}; + for (const { key, value } of responseValue.groups) { + result[key] = value; + } + return result as QueryReturnType; + } + + case "threeDimensionalAggregation": { + const result: Record> = {}; + for (const { key, groups } of responseValue.groups) { + const subresult: Record = {}; + result[key] = subresult; + for (const { key: subkey, value } of groups) { + subresult[subkey] = value; + } + } + return result as QueryReturnType; + } + } + + return responseValue as QueryReturnType; +} + +export function getRequiredDefinitions( + dataType: QueryDataTypeDefinition, +): Set { + const result = new Set(); + switch (dataType.type) { + case "objectSet": + result.add(dataType.objectSet); + break; + + case "set": + for (const s of getRequiredDefinitions(dataType.set)) { + result.add(s); + } + break; + + case "struct": + for (const value of Object.values(dataType.struct)) { + for (const s of getRequiredDefinitions(value)) { + result.add(s); + } + } + break; + + case "attachment": + case "boolean": + case "date": + case "double": + case "float": + case "integer": + case "long": + case "object": + case "string": + case "threeDimensionalAggregation": + case "timestamp": + case "twoDimensionalAggregation": + case "union": + break; + + default: + const _: never = dataType; + break; + } + + return result; +} +function requiresConversion(dataType: QueryDataTypeDefinition) { + switch (dataType.type) { + case "boolean": + case "date": + case "double": + case "float": + case "integer": + case "long": + case "object": // JSON encoded primary key + case "string": + case "timestamp": + return false; + + case "union": + return true; + + case "struct": + return Object.values(dataType.struct).some(requiresConversion); + + case "set": + return requiresConversion(dataType.set); + + case "attachment": + case "objectSet": + case "twoDimensionalAggregation": + case "threeDimensionalAggregation": + return true; + + default: + const _: never = dataType; + return false; + } +} + +export function createQueryObjectResponse( + objectType: string, + primaryKey: string, + apiName: N, +): QueryObjectResponse { + return { apiName, objectType, primaryKey }; +} diff --git a/packages/client/src/queries/createQueryInvoker.ts b/packages/client/src/queries/createQueryInvoker.ts new file mode 100644 index 000000000..a0267b0be --- /dev/null +++ b/packages/client/src/queries/createQueryInvoker.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { OntologyDefinition, QueryDefinition } from "@osdk/api"; +import type { QuerySignatureFromDef } from "@osdk/client.api"; +import type { MinimalClient } from "../MinimalClientContext.js"; +import { applyQuery } from "./applyQuery.js"; + +export function createQueryInvoker>( + client: MinimalClient, + query: Q, +): QuerySignatureFromDef { + return function(...args: any[]) { + return applyQuery(client, query, ...args); + }; +} diff --git a/packages/client/src/util/datamapping.ts b/packages/client/src/util/datamapping.ts new file mode 100644 index 000000000..21693bd20 --- /dev/null +++ b/packages/client/src/util/datamapping.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + Attachment, + AttachmentUpload, + QueryObjectResponse, +} from "@osdk/client.api"; +import type { ObjectSet } from "../objectSet/ObjectSet.js"; + +export interface DataValueClientToWire { + attachment: Attachment | AttachmentUpload; + boolean: boolean; + byte: number; + datetime: string; + decimal: string | number; + float: number; + double: number; + integer: number; + long: string | number; + marking: string; + null: null; + short: number; + string: string; + timestamp: string; + set: Set; + twoDimensionalAggregation: Record; + threeDimensionalAggregation: Record>; + struct: Record; + object: QueryObjectResponse; + objectSet: ObjectSet; +} diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts new file mode 100644 index 000000000..74d3b5236 --- /dev/null +++ b/packages/client/src/util/toDataValueQueries.ts @@ -0,0 +1,129 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { QueryDataTypeDefinition } from "@osdk/api"; +import { type DataValue, Ontologies } from "@osdk/internal.foundry"; +import type { SharedClient, SharedClientContext } from "@osdk/shared.client"; +import type { MinimalClient } from "../MinimalClientContext.js"; +import { + Attachment, + isAttachment, + isAttachmentUpload, +} from "../object/Attachment.js"; +import { getWireObjectSet, isObjectSet } from "../objectSet/createObjectSet.js"; +import { isOntologyObjectV2 } from "./isOntologyObjectV2.js"; +import { isWireObjectSet } from "./WireObjectSet.js"; + +/** + * Marshall user-facing data into the wire DataValue type + * + * @see DataValue for the expected payloads + */ +export async function toDataValueQueries( + value: unknown, + client: MinimalClient, + desiredType: QueryDataTypeDefinition, +): Promise { + if (value == null) { + // typeof null is 'object' so do this first + return value; + } + + // arrays and sets are both sent over the wire as arrays + if (Array.isArray(value) || value instanceof Set) { + const promiseArray = Array.from( + value, + async (innerValue) => + await toDataValueQueries(innerValue, client, desiredType), + ); + return Promise.all(promiseArray); + } + + // attachments just send the rid directly + if (isAttachment(value) && desiredType.type === "attachment") { + return value.rid; + } + + // For uploads, we need to upload ourselves first to get the RID of the attachment + if (isAttachmentUpload(value)) { + const attachment = await Ontologies.Attachments.uploadAttachment( + client, + value, + { + filename: value.name, + }, + { + "Content-Length": value.size.toString(), + "Content-Type": value.type, + }, + ); + return await toDataValueQueries( + new Attachment(attachment.rid), + client, + desiredType, + ); + } + + // objects just send the JSON'd primaryKey + if (isOntologyObjectV2(value)) { + return await toDataValueQueries(value.__primaryKey, client, desiredType); + } + + // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) + if (isWireObjectSet(value)) { + return value; + } + if (isObjectSet(value)) { + return getWireObjectSet(value); + } + + if (desiredType.type === "twoDimensionalAggregation") { + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + values, + })), + }; + } + + if (desiredType.type === "threeDimensionalAggregation") { + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + groups: Object.entries(values).map(([key, value]) => ({ key, value })), + })), + }; + } + + // TODO (during queries implementation) + // two dimensional aggregation + // three dimensional aggregation + + // struct + if (typeof value === "object" && desiredType.type === "struct") { + return Object.entries(value).reduce( + async (promisedAcc, [key, structValue]) => { + const acc = await promisedAcc; + acc[key] = await toDataValueQueries(structValue, client, desiredType); + return acc; + }, + Promise.resolve({} as { [key: string]: DataValue }), + ); + } + + // expected to pass through - boolean, byte, date, decimal, float, double, integer, long, short, string, timestamp + return value; +} From df61560e50885a80e493ba3213e5abe35842e677 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 18 Jun 2024 14:30:01 -0400 Subject: [PATCH 03/21] refactor --- .../client/src/util/toDataValueQueries.ts | 160 ++++++++++-------- 1 file changed, 88 insertions(+), 72 deletions(-) diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index 74d3b5236..b04e98c36 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -42,8 +42,8 @@ export async function toDataValueQueries( return value; } - // arrays and sets are both sent over the wire as arrays - if (Array.isArray(value) || value instanceof Set) { + // LOOK AT: For some reason, query parameter types do not specify arrays as an allowed type + if (Array.isArray(value)) { const promiseArray = Array.from( value, async (innerValue) => @@ -52,78 +52,94 @@ export async function toDataValueQueries( return Promise.all(promiseArray); } - // attachments just send the rid directly - if (isAttachment(value) && desiredType.type === "attachment") { - return value.rid; - } + switch (desiredType.type) { + case "attachment": + // attachments just send the rid directly + if (isAttachment(value)) { + return value.rid; + } - // For uploads, we need to upload ourselves first to get the RID of the attachment - if (isAttachmentUpload(value)) { - const attachment = await Ontologies.Attachments.uploadAttachment( - client, - value, - { - filename: value.name, - }, - { - "Content-Length": value.size.toString(), - "Content-Type": value.type, - }, - ); - return await toDataValueQueries( - new Attachment(attachment.rid), - client, - desiredType, - ); - } + // For uploads, we need to upload ourselves first to get the RID of the attachment + if (isAttachmentUpload(value)) { + const attachment = await Ontologies.Attachments.uploadAttachment( + client, + value, + { + filename: value.name, + }, + { + "Content-Length": value.size.toString(), + "Content-Type": value.type, + }, + ); + return await toDataValueQueries( + new Attachment(attachment.rid), + client, + desiredType, + ); + } - // objects just send the JSON'd primaryKey - if (isOntologyObjectV2(value)) { - return await toDataValueQueries(value.__primaryKey, client, desiredType); - } + case "set": + if (value instanceof Set) { + const promiseArray = Array.from( + value, + async (innerValue) => + await toDataValueQueries(innerValue, client, desiredType), + ); + return Promise.all(promiseArray); + } + case "object": + // objects just send the JSON'd primaryKey + if (isOntologyObjectV2(value)) { + return await toDataValueQueries( + value.__primaryKey, + client, + desiredType, + ); + } + case "objectSet": + // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) + if (isWireObjectSet(value)) { + return value; + } + if (isObjectSet(value)) { + return getWireObjectSet(value); + } - // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) - if (isWireObjectSet(value)) { - return value; + case "twoDimensionalAggregation": + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + values, + })), + }; + case "threeDimensionalAggregation": + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + groups: Object.entries(values).map(([key, value]) => ({ + key, + value, + })), + })), + }; + case "struct": + return Object.entries(value).reduce( + async (promisedAcc, [key, structValue]) => { + const acc = await promisedAcc; + acc[key] = await toDataValueQueries(structValue, client, desiredType); + return acc; + }, + Promise.resolve({} as { [key: string]: DataValue }), + ); + case "boolean": + case "date": + case "double": + case "float": + case "integer": + case "long": + case "string": + case "timestamp": + return value; } - if (isObjectSet(value)) { - return getWireObjectSet(value); - } - - if (desiredType.type === "twoDimensionalAggregation") { - return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - values, - })), - }; - } - - if (desiredType.type === "threeDimensionalAggregation") { - return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - groups: Object.entries(values).map(([key, value]) => ({ key, value })), - })), - }; - } - - // TODO (during queries implementation) - // two dimensional aggregation - // three dimensional aggregation - - // struct - if (typeof value === "object" && desiredType.type === "struct") { - return Object.entries(value).reduce( - async (promisedAcc, [key, structValue]) => { - const acc = await promisedAcc; - acc[key] = await toDataValueQueries(structValue, client, desiredType); - return acc; - }, - Promise.resolve({} as { [key: string]: DataValue }), - ); - } - - // expected to pass through - boolean, byte, date, decimal, float, double, integer, long, short, string, timestamp - return value; } From 3166a4eecbeae49fc80a4e214317ab2ad34937f3 Mon Sep 17 00:00:00 2001 From: Saurav Date: Sun, 23 Jun 2024 15:02:54 -0400 Subject: [PATCH 04/21] progress --- .../sdk/src/generatedNoCheck/Ontology.ts | 7 +- .../basic/sdk/src/generatedNoCheck/index.ts | 1 + .../ontology/queries/getTodoCount.ts | 9 + .../ontology/queries/index.ts | 2 + .../queries/queryTakesAllParameterTypes.ts | 61 ++++++ .../src/generatedNoCheck/Ontology.ts | 8 +- .../src/generatedNoCheck/index.ts | 1 + .../ontology/queries/index.ts | 0 .../todoapp/src/generatedNoCheck2/Ontology.ts | 8 +- .../todoapp/src/generatedNoCheck2/index.ts | 1 + .../ontology/queries/index.ts | 0 .../src/mapping/DataValueMapping.ts | 18 +- packages/client.api/src/queries/Queries.ts | 41 +++- packages/client/src/queries/applyQuery.ts | 28 ++- packages/client/src/queries/queries.test.ts | 98 ++++++++++ .../client/src/util/toDataValueQueries.ts | 182 ++++++++++-------- .../tsup.config.bundled_xnzkd6wirio.mjs | 11 ++ .../tsup.config.bundled_utoam7othn.mjs | 11 ++ .../generateClientSdkVersionTwoPointZero.ts | 24 ++- packages/shared.test/src/errors.ts | 12 ++ .../src/handlers/loadObjectsEndpoints.ts | 9 +- .../src/handlers/queriesEndpoints.ts | 82 ++++++++ packages/shared.test/src/setupServers.ts | 1 + packages/shared.test/src/stubs/queries.ts | 13 ++ packages/shared.test/src/stubs/queryTypes.ts | 24 +++ 25 files changed, 535 insertions(+), 117 deletions(-) create mode 100644 examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts create mode 100644 examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/index.ts create mode 100644 examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts create mode 100644 examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts create mode 100644 examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts create mode 100644 packages/client/src/queries/queries.test.ts create mode 100644 packages/client/tsup.config.bundled_xnzkd6wirio.mjs create mode 100644 packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs create mode 100644 packages/shared.test/src/handlers/queriesEndpoints.ts diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/Ontology.ts b/examples-extra/basic/sdk/src/generatedNoCheck/Ontology.ts index 0c031324a..9b8c0b759 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/Ontology.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/Ontology.ts @@ -3,6 +3,7 @@ import { OntologyMetadata } from './OntologyMetadata.js'; import * as Actions from './ontology/actions/index.js'; import * as Interfaces from './ontology/interfaces.js'; import * as Objects from './ontology/objects.js'; +import * as Queries from './ontology/queries/index.js'; export interface Ontology extends OntologyDefinition< @@ -32,7 +33,8 @@ export interface Ontology createTodo: typeof Actions.createTodo; }; queries: { - // TODO + getTodoCount: typeof Queries.getTodoCount; + queryTakesAllParameterTypes: typeof Queries.queryTakesAllParameterTypes; }; interfaces: { FooInterface: Interfaces.FooInterface; @@ -57,7 +59,8 @@ export const Ontology: Ontology = { createTodo: Actions.createTodo, }, queries: { - // TODO + getTodoCount: Queries.getTodoCount, + queryTakesAllParameterTypes: Queries.queryTakesAllParameterTypes, }, interfaces: { FooInterface: Interfaces.FooInterface, diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/index.ts b/examples-extra/basic/sdk/src/generatedNoCheck/index.ts index ff3b88e0c..1353972dd 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/index.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/index.ts @@ -2,3 +2,4 @@ export { Ontology } from './Ontology.js'; export * from './ontology/actions/index.js'; export * from './ontology/interfaces.js'; export * from './ontology/objects.js'; +export * from './ontology/queries/index.js'; diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts new file mode 100644 index 000000000..02d824381 --- /dev/null +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts @@ -0,0 +1,9 @@ +import { QueryDefinition } from '@osdk/api'; + +export const getTodoCount = { + type: 'query', + apiName: 'getTodoCount', + version: '0.1.2', + parameters: {}, + output: { type: 'integer', nullable: false }, +} satisfies QueryDefinition<'getTodoCount', never>; diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/index.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/index.ts new file mode 100644 index 000000000..6185c146e --- /dev/null +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/index.ts @@ -0,0 +1,2 @@ +export * from './getTodoCount.js'; +export * from './queryTakesAllParameterTypes.js'; diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts new file mode 100644 index 000000000..41487210e --- /dev/null +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -0,0 +1,61 @@ +import { QueryDefinition } from '@osdk/api'; + +export const queryTakesAllParameterTypes = { + type: 'query', + apiName: 'queryTakesAllParameterTypes', + description: 'description of the query that takes all parameter types', + displayName: 'qTAPT', + version: 'version', + parameters: { + double: { description: 'a double parameter', type: 'double', nullable: false }, + float: { type: 'float', nullable: false }, + integer: { type: 'integer', nullable: false }, + long: { type: 'long', nullable: false }, + attachment: { type: 'attachment', nullable: false }, + boolean: { type: 'boolean', nullable: false }, + date: { type: 'date', nullable: false }, + string: { type: 'string', nullable: false }, + timestamp: { type: 'timestamp', nullable: false }, + object: { type: 'object', object: 'Todo', nullable: false }, + objectSet: { type: 'objectSet', objectSet: 'Todo', nullable: false }, + array: { description: 'an array of strings', type: 'string', nullable: false, multiplicity: true }, + set: { description: 'a set of strings', type: 'set', set: { type: 'string', nullable: false }, nullable: false }, + unionNonNullable: { + description: 'a union of strings and integers', + type: 'union', + union: [ + { type: 'string', nullable: false }, + { type: 'integer', nullable: false }, + ], + nullable: false, + }, + unionNullable: { + description: 'a union of strings and integers but its optional', + type: 'union', + union: [ + { type: 'string', nullable: false }, + { type: 'integer', nullable: false }, + ], + nullable: true, + }, + struct: { + description: 'a struct with some fields', + type: 'struct', + struct: { name: { type: 'string', nullable: false }, id: { type: 'integer', nullable: false } }, + nullable: false, + }, + twoDimensionalAggregation: { + type: 'twoDimensionalAggregation', + twoDimensionalAggregation: { keyType: 'string', valueType: 'double' }, + }, + threeDimensionalAggregation: { + type: 'threeDimensionalAggregation', + threeDimensionalAggregation: { + keyType: 'range', + keySubtype: 'date', + valueType: { keyType: 'range', keySubtype: 'timestamp', valueType: 'date' }, + }, + }, + }, + output: { type: 'string', nullable: false }, +} satisfies QueryDefinition<'queryTakesAllParameterTypes', 'Todo'>; diff --git a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts index 8f2706dc4..04d660fd0 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts @@ -20,9 +20,7 @@ export interface Ontology extends OntologyDefinition<'Employee' | 'equipment' | promoteEmployee: typeof Actions.promoteEmployee; promoteEmployeeObject: typeof Actions.promoteEmployeeObject; }; - queries: { - // TODO - }; + queries: {}; interfaces: {}; } @@ -43,8 +41,6 @@ export const Ontology: Ontology = { promoteEmployee: Actions.promoteEmployee, promoteEmployeeObject: Actions.promoteEmployeeObject, }, - queries: { - // TODO - }, + queries: {}, interfaces: {}, }; diff --git a/examples-extra/docs_example/src/generatedNoCheck/index.ts b/examples-extra/docs_example/src/generatedNoCheck/index.ts index eb6457683..3f96ac903 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/index.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/index.ts @@ -2,3 +2,4 @@ export { Ontology } from './Ontology'; export * from './ontology/actions/index'; export * from './ontology/interfaces'; export * from './ontology/objects'; +export * from './ontology/queries/index'; diff --git a/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts b/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts index 49852e4f9..e9dd49ecd 100644 --- a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts +++ b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts @@ -12,9 +12,7 @@ export interface Ontology extends OntologyDefinition<'Todo'> { completeTodo: typeof Actions.completeTodo; createTodo: typeof Actions.createTodo; }; - queries: { - // TODO - }; + queries: {}; interfaces: {}; } @@ -27,8 +25,6 @@ export const Ontology: Ontology = { completeTodo: Actions.completeTodo, createTodo: Actions.createTodo, }, - queries: { - // TODO - }, + queries: {}, interfaces: {}, }; diff --git a/examples-extra/todoapp/src/generatedNoCheck2/index.ts b/examples-extra/todoapp/src/generatedNoCheck2/index.ts index eb6457683..3f96ac903 100644 --- a/examples-extra/todoapp/src/generatedNoCheck2/index.ts +++ b/examples-extra/todoapp/src/generatedNoCheck2/index.ts @@ -2,3 +2,4 @@ export { Ontology } from './Ontology'; export * from './ontology/actions/index'; export * from './ontology/interfaces'; export * from './ontology/objects'; +export * from './ontology/queries/index'; diff --git a/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts b/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index ba775cddb..b28ca3cb7 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -56,9 +56,23 @@ export interface DataValueClientToWire { string: string; timestamp: string; set: Set; - twoDimensionalAggregation: Record; - threeDimensionalAggregation: Record>; + twoDimensionalAggregation: { + key: allowedBucketKeyTypes; + value: allowedBucketTypes; + }[]; + threeDimensionalAggregation: { + key: allowedBucketKeyTypes; + groups: { key: allowedBucketKeyTypes; value: allowedBucketTypes }[]; + }[]; struct: Record; object: QueryObjectResponse; objectSet: never; } + +type allowedBucketTypes = string | number | boolean; +type allowedBucketKeyTypes = + | allowedBucketTypes + | { + startValue: allowedBucketTypes; + endValue: allowedBucketTypes; + }; diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts index 16b3fcec0..80f1997ad 100644 --- a/packages/client.api/src/queries/Queries.ts +++ b/packages/client.api/src/queries/Queries.ts @@ -15,11 +15,19 @@ */ import type { + ObjectQueryDataType, + ObjectSetQueryDataType, OntologyDefinition, QueryDataTypeDefinition, QueryDefinition, } from "@osdk/api"; -import type { DataValueClientToWire, NOOP } from "../index.js"; +import type { + BaseObjectSet, + DataValueClientToWire, + NOOP, + OsdkBase, + OsdkObjectPrimaryKeyType, +} from "../index.js"; import type { PartialByNotStrict } from "../util/PartialBy.js"; export type Queries> = { @@ -27,14 +35,15 @@ export type Queries> = { }; export type QuerySignatureFromDef> = - keyof T["parameters"] extends never ? ( + keyof T["parameters"] extends never + ? () => Promise> + : ( params: QueryParameterType, - ) => Promise> - : () => Promise>; + ) => Promise>; export type QueryParameterType< T extends Record>, -> = NOOP>>; +> = NOOP, OptionalQueryParams>>; export type QueryReturnType> = T["type"] extends keyof DataValueClientToWire @@ -45,3 +54,25 @@ type OptionalQueryParams>> = { [K in keyof T]: T[K] extends { nullable: true } ? never : K; }[keyof T]; + +type NotOptionalParams>> = { + [K in keyof T]: MaybeArrayType; +}; + +type MaybeArrayType> = + T["multiplicity"] extends true ? Array> + : BaseType; + +// type BaseType> = T extends +// ObjectQueryDataType +// ? OsdkBase | OsdkObjectPrimaryKeyType +// : T extends ObjectSetQueryDataType +// ? BaseObjectSet +// : T["type"] extends keyof DataValueClientToWire +// ? DataValueClientToWire[T["type"]] +// : never; +type BaseType> = T extends + ObjectQueryDataType | ObjectSetQueryDataType ? never + : T["type"] extends keyof DataValueClientToWire + ? DataValueClientToWire[T["type"]] + : never; diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index ad6ff2610..0a409440d 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -62,6 +62,9 @@ export async function applyQuery< : {}, }, ); + + // eslint-disable-next-line no-console + console.log("I got a response,", response, query); const remappedResponse = await remapQueryResponse( client, query.output, @@ -77,13 +80,14 @@ async function remapQueryParams( ): Promise<{ [parameterId: string]: any }> { const parameterMap: { [parameterName: string]: unknown } = {}; for (const [key, value] of Object.entries(params)) { + // eslint-disable-next-line no-console + console.log("thisiswhatagain?", key, value); parameterMap[key] = await toDataValueQueries( value, client, paramTypes[key], ); } - return parameterMap; } @@ -104,8 +108,14 @@ async function remapQueryResponse< throw new Error("Got null response when nullable was not allowed"); } } - - if (responseDataType.multiplicity !== false) { + // eslint-disable-next-line no-console + console.log("lookiehere", responseDataType); + // eslint-disable-next-line no-console + console.log("lookiehere2", responseValue); + if ( + responseDataType.multiplicity != null + && responseDataType.multiplicity !== false + ) { const withoutMultiplicity = { ...responseDataType, multiplicity: false }; for (let i = 0; i < responseValue.length; i++) { responseValue[i] = remapQueryResponse( @@ -210,21 +220,21 @@ async function remapQueryResponse< return responseValue as QueryReturnType; } case "twoDimensionalAggregation": { - const result: Record = {}; + const result: { key: any; value: any }[] = []; for (const { key, value } of responseValue.groups) { - result[key] = value; + result.push({ key, value }); } return result as QueryReturnType; } case "threeDimensionalAggregation": { - const result: Record> = {}; + const result: { key: any; groups: { key: any; value: any }[] }[] = []; for (const { key, groups } of responseValue.groups) { - const subresult: Record = {}; - result[key] = subresult; + const subresult: { key: any; value: any }[] = []; for (const { key: subkey, value } of groups) { - subresult[subkey] = value; + subresult.push({ key: subkey, value }); } + result.push({ key, groups: subresult }); } return result as QueryReturnType; } diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts new file mode 100644 index 000000000..2cf6fb46c --- /dev/null +++ b/packages/client/src/queries/queries.test.ts @@ -0,0 +1,98 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { QuerySignatureFromDef } from "@osdk/client.api"; +import { + addOne, + incrementPersonAge, + Ontology as MockOntology, + queryAcceptsObject, + returnsDate, + returnsTimestamp, + threeDimensionalAggregationFunction, + twoDimensionalAggregationFunction, +} from "@osdk/client.test.ontology"; +import { apiServer } from "@osdk/shared.test"; +import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import type { Client } from "../Client.js"; +import { createClient } from "../createClient.js"; + +describe("queries", () => { + let client: Client; + + beforeAll(async () => { + apiServer.listen(); + client = createClient( + "https://stack.palantir.com", + MockOntology.metadata.ontologyRid, + async () => "myAccessToken", + ); + }); + + afterAll(() => { + apiServer.close(); + }); + + it("simple query works", async () => { + const result = await client(addOne)({ n: 2 }); + expect(result).toBe(3); + }); + + it("accepts objects", async () => { + }); + + it("no params work", async () => { + const resultWithTimestamp = await client(returnsTimestamp)(); + expect(resultWithTimestamp).toBe("2019-01-01T00:00:00.000Z"); + + const resultWithDate = await client(returnsDate)(); + expect(resultWithDate).toBe("2019-01-01"); + }); + + it("returns and accepts structs property", async () => { + const result = await client(incrementPersonAge)({ + person: { firstName: "John", lastName: "Doe", age: 42 }, + }); + console.error(result); + expect(result).toEqual({ + firstName: "John", + lastName: "Doe", + age: 43, + }); + }); + + it("two dimensional aggs response works", async () => { + const result = await client(twoDimensionalAggregationFunction)(); + expect(result).toEqual([{ key: "Q-AFN", value: 1 }, { + key: "Q-AFO", + value: 2, + }]); + }); + + it("three dimensional aggs response works", async () => { + const result = await client(threeDimensionalAggregationFunction)(); + expect(result).toEqual([{ + key: "Q-AFN", + groups: [{ + key: { + startValue: "2010-10-01T00:00:00Z", + endValue: "2010-10-02T00:00:00Z", + }, + value: 65.0, + }], + }, { key: "Q-AFO", groups: [] }]); + }); +}); diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index b04e98c36..019d86573 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -41,7 +41,6 @@ export async function toDataValueQueries( // typeof null is 'object' so do this first return value; } - // LOOK AT: For some reason, query parameter types do not specify arrays as an allowed type if (Array.isArray(value)) { const promiseArray = Array.from( @@ -52,94 +51,109 @@ export async function toDataValueQueries( return Promise.all(promiseArray); } - switch (desiredType.type) { - case "attachment": - // attachments just send the rid directly - if (isAttachment(value)) { - return value.rid; - } + if (value instanceof Set && desiredType.type === "set") { + const promiseArray = Array.from( + value, + async (innerValue) => + await toDataValueQueries(innerValue, client, desiredType["set"]), + ); + return Promise.all(promiseArray); + } - // For uploads, we need to upload ourselves first to get the RID of the attachment - if (isAttachmentUpload(value)) { - const attachment = await Ontologies.Attachments.uploadAttachment( - client, - value, - { - filename: value.name, - }, - { - "Content-Length": value.size.toString(), - "Content-Type": value.type, - }, - ); - return await toDataValueQueries( - new Attachment(attachment.rid), - client, - desiredType, - ); - } + // attachments just send the rid directly + if (isAttachment(value) && desiredType.type === "attachment") { + return value.rid; + } - case "set": - if (value instanceof Set) { - const promiseArray = Array.from( - value, - async (innerValue) => - await toDataValueQueries(innerValue, client, desiredType), - ); - return Promise.all(promiseArray); - } - case "object": - // objects just send the JSON'd primaryKey - if (isOntologyObjectV2(value)) { - return await toDataValueQueries( - value.__primaryKey, - client, - desiredType, - ); - } - case "objectSet": - // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) - if (isWireObjectSet(value)) { - return value; - } - if (isObjectSet(value)) { - return getWireObjectSet(value); - } + // For uploads, we need to upload ourselves first to get the RID of the attachment + if (isAttachmentUpload(value) && desiredType.type === "attachment") { + const attachment = await Ontologies.Attachments.uploadAttachment( + client, + value, + { + filename: value.name, + }, + { + "Content-Length": value.size.toString(), + "Content-Type": value.type, + }, + ); + return attachment.rid; + } - case "twoDimensionalAggregation": - return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - values, - })), - }; - case "threeDimensionalAggregation": - return { - groups: Object.entries(value).map(([key, values]) => ({ + if (desiredType.type === "twoDimensionalAggregation") { + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + values, + })), + }; + } + + if (desiredType.type === "threeDimensionalAggregation") { + return { + groups: Object.entries(value).map(([key, values]) => ({ + key, + groups: Object.entries(values).map(([key, value]) => ({ key, - groups: Object.entries(values).map(([key, value]) => ({ - key, - value, - })), + value, })), - }; - case "struct": - return Object.entries(value).reduce( - async (promisedAcc, [key, structValue]) => { - const acc = await promisedAcc; - acc[key] = await toDataValueQueries(structValue, client, desiredType); - return acc; - }, - Promise.resolve({} as { [key: string]: DataValue }), - ); - case "boolean": - case "date": - case "double": - case "float": - case "integer": - case "long": - case "string": - case "timestamp": + })), + }; + } + + // objects just send the JSON'd primaryKey + if (isOntologyObjectV2(value) && desiredType.type === "object") { + return value.__primaryKey; + } + + if (desiredType.type === "objectSet") { + // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) + if (isWireObjectSet(value)) { return value; + } + if (isObjectSet(value)) { + return getWireObjectSet(value); + } } + + if (desiredType.type === "struct") { + const structMap: { [key: string]: unknown } = {}; + for (const [key, structValue] of Object.entries(value)) { + structMap[key] = await toDataValueQueries( + structValue, + client, + desiredType["struct"][key], + ); + } + return structMap; + } + return value; + + // switch (desiredType.type) { + // case "boolean": + // case "date": + // case "double": + // case "float": + // case "integer": + // case "long": + // case "string": + // case "timestamp": + // return value; + // case "attachment": { + // } + // case "twoDimensionalAggregation": { + // } + // case "threeDimensionalAggregation": { + // } + // case "set": { + // } + // case "object": { + // } + // case "objectSet": { + // } + + // case "struct": { + // } + // } } diff --git a/packages/client/tsup.config.bundled_xnzkd6wirio.mjs b/packages/client/tsup.config.bundled_xnzkd6wirio.mjs new file mode 100644 index 000000000..dd03ef8b7 --- /dev/null +++ b/packages/client/tsup.config.bundled_xnzkd6wirio.mjs @@ -0,0 +1,11 @@ +// tsup.config.js +import { defineConfig } from "tsup"; +var tsup_config_default = defineConfig( + async (options) => (await import("mytsup")).default(options, { + esmOnly: true + }) +); +export { + tsup_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHN1cC5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL1ZvbHVtZXMvZ2l0L29zZGstdHMvcGFja2FnZXMvY2xpZW50L3RzdXAuY29uZmlnLmpzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9Wb2x1bWVzL2dpdC9vc2RrLXRzL3BhY2thZ2VzL2NsaWVudFwiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vVm9sdW1lcy9naXQvb3Nkay10cy9wYWNrYWdlcy9jbGllbnQvdHN1cC5jb25maWcuanNcIjsvKlxuICogQ29weXJpZ2h0IDIwMjMgUGFsYW50aXIgVGVjaG5vbG9naWVzLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ0c3VwXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhhc3luYyAob3B0aW9ucykgPT5cbiAgKGF3YWl0IGltcG9ydChcIm15dHN1cFwiKSkuZGVmYXVsdChvcHRpb25zLCB7XG4gICAgZXNtT25seTogdHJ1ZSxcbiAgfSlcbik7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBZ0JBLFNBQVMsb0JBQW9CO0FBRTdCLElBQU8sc0JBQVE7QUFBQSxFQUFhLE9BQU8sYUFDaEMsTUFBTSxPQUFPLFFBQVEsR0FBRyxRQUFRLFNBQVM7QUFBQSxJQUN4QyxTQUFTO0FBQUEsRUFDWCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs b/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs new file mode 100644 index 000000000..6ec6a3b24 --- /dev/null +++ b/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs @@ -0,0 +1,11 @@ +// tsup.config.js +import { defineConfig } from "tsup"; +var tsup_config_default = defineConfig( + async (options) => (await import("mytsup")).default(options, { + esmOnly: true + }) +); +export { + tsup_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHN1cC5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL1ZvbHVtZXMvZ2l0L29zZGstdHMvcGFja2FnZXMvZm91bmRyeS1zZGstZ2VuZXJhdG9yL3RzdXAuY29uZmlnLmpzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9Wb2x1bWVzL2dpdC9vc2RrLXRzL3BhY2thZ2VzL2ZvdW5kcnktc2RrLWdlbmVyYXRvclwiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vVm9sdW1lcy9naXQvb3Nkay10cy9wYWNrYWdlcy9mb3VuZHJ5LXNkay1nZW5lcmF0b3IvdHN1cC5jb25maWcuanNcIjsvKlxuICogQ29weXJpZ2h0IDIwMjMgUGFsYW50aXIgVGVjaG5vbG9naWVzLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ0c3VwXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhhc3luYyAob3B0aW9ucykgPT5cbiAgKGF3YWl0IGltcG9ydChcIm15dHN1cFwiKSkuZGVmYXVsdChvcHRpb25zLCB7XG4gICAgZXNtT25seTogdHJ1ZSxcbiAgfSlcbik7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBZ0JBLFNBQVMsb0JBQW9CO0FBRTdCLElBQU8sc0JBQVE7QUFBQSxFQUFhLE9BQU8sYUFDaEMsTUFBTSxPQUFPLFFBQVEsR0FBRyxRQUFRLFNBQVM7QUFBQSxJQUN4QyxTQUFTO0FBQUEsRUFDWCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts b/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts index f607edf79..2f97cd18e 100644 --- a/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts +++ b/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts @@ -24,6 +24,7 @@ import { } from "../shared/wireObjectTypeV2ToSdkObjectConst.js"; import { formatTs } from "../util/test/formatTs.js"; import { verifyOutdir } from "../util/verifyOutdir.js"; +import { generatePerQueryDataFiles } from "../v1.1/generatePerQueryDataFiles.js"; import type { WireOntologyDefinition } from "../WireOntologyDefinition.js"; import { generateOntologyMetadataFile } from "./generateMetadata.js"; @@ -62,6 +63,7 @@ export async function generateClientSdkVersionTwoPointZero( export * from "./ontology/actions/index${importExt}"; export * from "./ontology/objects${importExt}"; export * from "./ontology/interfaces${importExt}"; + export * from "./ontology/queries/index${importExt}"; `, ), ); @@ -76,6 +78,7 @@ export async function generateClientSdkVersionTwoPointZero( import * as Actions from "./ontology/actions/index${importExt}"; import * as Objects from "./ontology/objects${importExt}"; import * as Interfaces from "./ontology/interfaces${importExt}"; + import * as Queries from "./ontology/queries/index${importExt}"; import { OntologyMetadata } from "./OntologyMetadata${importExt}"; export interface Ontology extends OntologyDefinition<${ @@ -97,7 +100,11 @@ export async function generateClientSdkVersionTwoPointZero( } }, queries: { - // TODO + ${ + queryNames.map((queryName) => { + return `${queryName}: typeof Queries.${queryName}`; + }).join(",\n") + } }, interfaces: { ${ @@ -126,7 +133,11 @@ export async function generateClientSdkVersionTwoPointZero( } }, queries: { - // TODO + ${ + queryNames.map((queryName) => { + return `${queryName}: Queries.${queryName}`; + }).join(",\n") + } }, interfaces: { ${ @@ -188,6 +199,15 @@ export async function generateClientSdkVersionTwoPointZero( ${Object.keys(ontology.objectTypes).length === 0 ? "export {};" : ""} `), ); + + const queriesDir = path.join(outDir, "ontology", "queries"); + await fs.mkdir(queriesDir, { recursive: true }); + await generatePerQueryDataFiles( + sanitizedOntology, + fs, + queriesDir, + importExt, + ); } function stringUnionFrom(values: ReadonlyArray) { diff --git a/packages/shared.test/src/errors.ts b/packages/shared.test/src/errors.ts index a1a93a715..6660a828e 100644 --- a/packages/shared.test/src/errors.ts +++ b/packages/shared.test/src/errors.ts @@ -107,6 +107,18 @@ export const ApplyActionFailedError: errors.ApplyActionFailed = { parameters: {}, }; +export const ExecuteQueryFailedError: errors.QueryEncounteredUserFacingError = { + errorCode: "CONFLICT", + errorName: "QueryEncounteredUserFacingError", + errorInstanceId, + parameters: { + functionRid: + "ri.function-registry.main.function.9b55870a-63c7-4d48-8f06-9627c0805968", + functionVersion: "0.11.0", + message: "test failed", + }, +}; + export const InvalidContentTypeError: errors.InvalidContentType = { errorCode: "INVALID_ARGUMENT", errorName: "InvalidContentType", diff --git a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts index eeb75b27b..22943b289 100644 --- a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts +++ b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts @@ -485,15 +485,22 @@ export const loadObjectsEndpoints: Array = [ ); } + // eslint-disable-next-line no-console + console.error("here i am", parsedBody, queryApiName); + const queryResponses = queryRequestHandlers[queryApiName]; if (!queryResponses) { throw new OpenApiCallError(404, QueryNotFoundError(queryApiName)); } const queryResponse = queryResponses[JSON.stringify(parsedBody)]; + + // eslint-disable-next-line no-console + console.error("here i am2", queryResponse, req); if ( req.params.ontologyApiName === defaultOntology.apiName - && queryResponse + || req.params.ontologyApiName === defaultOntology.rid + && queryResponse ) { return queryResponse; } diff --git a/packages/shared.test/src/handlers/queriesEndpoints.ts b/packages/shared.test/src/handlers/queriesEndpoints.ts new file mode 100644 index 000000000..62e0bf570 --- /dev/null +++ b/packages/shared.test/src/handlers/queriesEndpoints.ts @@ -0,0 +1,82 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { HttpResponseResolver, PathParams, RequestHandler } from "msw"; + +import { executeQueryV2 } from "@osdk/gateway/requests"; +import type { ExecuteQueryResponse } from "@osdk/gateway/types"; +import stableStringify from "json-stable-stringify"; +import type { BaseAPIError } from "../BaseError.js"; +import { + ApplyActionFailedError, + ExecuteQueryFailedError, + InvalidRequest, +} from "../errors.js"; +import { defaultOntology } from "../stubs/ontologies.js"; +import { queryRequestHandlers } from "../stubs/queries.js"; +import type { ExtractBody } from "./util/handleOpenApiCall.js"; +import { + handleOpenApiCall, + OpenApiCallError, +} from "./util/handleOpenApiCall.js"; + +export const queryHandlers: Array = [ + /** + * Execute Query + */ + handleOpenApiCall( + executeQueryV2, + ["ontologyApiName", "queryApiName"], + handleQuery, + ), +]; + +async function handleQuery< + T extends ExecuteQueryResponse, +>( + req: Parameters< + HttpResponseResolver< + PathParams, + | ExtractBody + | T + | BaseAPIError + > + >[0], +) { + const parsedBody = await req.request.json(); + + const ontologyApiName = req.params.ontologyApiName; + const queryType = req.params.queryApiName; + + if ( + typeof ontologyApiName !== "string" || typeof queryType !== "string" + ) { + throw new OpenApiCallError(400, InvalidRequest("Invalid parameters")); + } + + const queryResponse = + queryRequestHandlers[queryType][stableStringify(parsedBody)]; + + if ( + (req.params.ontologyApiName === defaultOntology.apiName + || req.params.ontologyApiName === defaultOntology.rid) + && queryResponse + ) { + return queryResponse; + } + + throw new OpenApiCallError(400, ExecuteQueryFailedError); +} diff --git a/packages/shared.test/src/setupServers.ts b/packages/shared.test/src/setupServers.ts index 236a71be2..5ade6bd5a 100644 --- a/packages/shared.test/src/setupServers.ts +++ b/packages/shared.test/src/setupServers.ts @@ -23,6 +23,7 @@ import { objectSetHandlers, ontologyMetadataEndpoint, } from "./handlers/index.js"; +import { queryHandlers } from "./handlers/queriesEndpoints.js"; export const apiServer: SetupServer = setupServer( ...loadObjectsEndpoints, diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index ad2c03145..0a7d98a70 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -21,6 +21,7 @@ import type { import { employee1 } from "./objects.js"; import { addOneQueryType, + queryTypeAcceptsObjects, queryTypeReturnsDate, queryTypeReturnsObject, queryTypeReturnsStruct, @@ -69,6 +70,14 @@ export const queryTypeReturnsObjectResponse: ExecuteQueryResponse = { value: employee1.__primaryKey, }; +export const queryTypeAcceptsObjectRequest: ExecuteQueryRequest = { + parameters: {}, +}; + +export const queryTypeAcceptsObjectResponse: ExecuteQueryResponse = { + value: employee1.__primaryKey, +}; + export const queryTypeThreeDimensionalAggregationResponse: ExecuteQueryResponse = { value: { @@ -140,4 +149,8 @@ export const queryRequestHandlers: { [queryTypeThreeDimensionalAggregation.apiName]: { [emptyBody]: queryTypeThreeDimensionalAggregationResponse, }, + [queryTypeAcceptsObjects.apiName]: { + [JSON.stringify(queryTypeAcceptsObjectRequest)]: + queryTypeAcceptsObjectResponse, + }, }; diff --git a/packages/shared.test/src/stubs/queryTypes.ts b/packages/shared.test/src/stubs/queryTypes.ts index be9c62748..625765823 100644 --- a/packages/shared.test/src/stubs/queryTypes.ts +++ b/packages/shared.test/src/stubs/queryTypes.ts @@ -190,6 +190,29 @@ export const queryTypeTwoDimensionalAggregation: QueryTypeV2 = { version: "0.11.0", }; +export const queryTypeAcceptsObjects: QueryTypeV2 = { + apiName: "queryAcceptsObject", + description: "description of the query that takes object types", + displayName: "QueryAcceptsObject", + parameters: { + object: { + dataType: { + type: "object", + objectApiName: "Employee", + objectTypeApiName: "Employee", + }, + }, + }, + output: { + type: "object", + objectApiName: "Employee", + objectTypeApiName: "Employee", + }, + rid: + "ri.function-registry.main.function.9b55870a-63c7-4d48-8f06-9627c0805968", + version: "0.11.0", +}; + export const queryTypes: QueryTypeV2[] = [ addOneQueryType, queryTypeReturnsStruct, @@ -198,4 +221,5 @@ export const queryTypes: QueryTypeV2[] = [ queryTypeReturnsTimestamp, queryTypeTwoDimensionalAggregation, queryTypeThreeDimensionalAggregation, + queryTypeAcceptsObjects, ]; From 4de0dc0186642498c0c7ab8869abf612460d1713 Mon Sep 17 00:00:00 2001 From: Saurav Date: Mon, 24 Jun 2024 15:20:05 -0400 Subject: [PATCH 05/21] Get objects working --- .../ontology/queries/getTodoCount.ts | 2 +- .../queries/queryTakesAllParameterTypes.ts | 18 ++- packages/api/src/ontology/QueryDefinition.ts | 42 ++++-- packages/client.api/src/queries/Queries.ts | 37 ++--- packages/client/src/queries/queries.test.ts | 17 +++ .../client/src/util/isOntologyObjectV2.ts | 6 + .../client/src/util/toDataValueQueries.ts | 6 +- ...eQueryDataTypeToQueryDataTypeDefinition.ts | 7 +- .../wireQueryTypeV2ToSdkQueryDefinition.ts | 14 +- .../src/v1.1/generatePerQueryDataFiles.ts | 131 ++++++++++++++++-- .../generateClientSdkVersionTwoPointZero.ts | 1 + packages/legacy-client/src/client/queries.ts | 6 +- packages/shared.test/src/stubs/queries.ts | 18 ++- packages/shared.test/src/stubs/queryTypes.ts | 23 +++ 14 files changed, 266 insertions(+), 62 deletions(-) diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts index 02d824381..82df97e10 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts @@ -1,8 +1,8 @@ import { QueryDefinition } from '@osdk/api'; export const getTodoCount = { - type: 'query', apiName: 'getTodoCount', + type: 'query', version: '0.1.2', parameters: {}, output: { type: 'integer', nullable: false }, diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 41487210e..3ffcf00a4 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -1,10 +1,10 @@ import { QueryDefinition } from '@osdk/api'; - +import { Todo } from '../objects.js'; export const queryTakesAllParameterTypes = { - type: 'query', apiName: 'queryTakesAllParameterTypes', description: 'description of the query that takes all parameter types', displayName: 'qTAPT', + type: 'query', version: 'version', parameters: { double: { description: 'a double parameter', type: 'double', nullable: false }, @@ -16,8 +16,18 @@ export const queryTakesAllParameterTypes = { date: { type: 'date', nullable: false }, string: { type: 'string', nullable: false }, timestamp: { type: 'timestamp', nullable: false }, - object: { type: 'object', object: 'Todo', nullable: false }, - objectSet: { type: 'objectSet', objectSet: 'Todo', nullable: false }, + object: { + type: 'object', + object: 'Todo', + nullable: false, + __OsdkTargetType: Todo, + }, + objectSet: { + type: 'object', + object: 'Todo', + nullable: false, + __OsdkTargetType: Todo, + }, array: { description: 'an array of strings', type: 'string', nullable: false, multiplicity: true }, set: { description: 'a set of strings', type: 'set', set: { type: 'string', nullable: false }, nullable: false }, unionNonNullable: { diff --git a/packages/api/src/ontology/QueryDefinition.ts b/packages/api/src/ontology/QueryDefinition.ts index f9df6fcd8..83bfd86c4 100644 --- a/packages/api/src/ontology/QueryDefinition.ts +++ b/packages/api/src/ontology/QueryDefinition.ts @@ -15,26 +15,36 @@ */ import type { OsdkMetadata } from "../OsdkMetadata.js"; +import type { ObjectTypeDefinition } from "./ObjectTypeDefinition.js"; -export interface QueryDefinition { +export interface QueryDefinition< + Q extends string, + K extends string, +> { type: "query"; apiName: Q; description?: string; displayName?: string; version: string; - parameters: Record>; - output: QueryDataTypeDefinition; + parameters: Record>; + output: QueryDataTypeDefinition; osdkMetadata?: OsdkMetadata; } -export type QueryParameterDefinition = { +export type QueryParameterDefinition< + K extends string, + T_Target extends ObjectTypeDefinition = never, +> = { description?: string; -} & QueryDataTypeDefinition; +} & QueryDataTypeDefinition; -export type QueryDataTypeDefinition = +export type QueryDataTypeDefinition< + K extends string, + T_Target extends ObjectTypeDefinition = never, +> = | PrimitiveDataType - | ObjectQueryDataType - | ObjectSetQueryDataType + | ObjectQueryDataType + | ObjectSetQueryDataType | SetQueryDataType | UnionQueryDataType | StructQueryDataType @@ -62,16 +72,20 @@ export type PrimitiveDataType< Q extends WireQueryDataTypes = WireQueryDataTypes, > = BaseQueryDataTypeDefinition; -export interface ObjectQueryDataType - extends BaseQueryDataTypeDefinition<"object"> -{ +export interface ObjectQueryDataType< + K extends string, + T_Target extends ObjectTypeDefinition = never, +> extends BaseQueryDataTypeDefinition<"object"> { object: K; + __OsdkTargetType?: T_Target; } -export interface ObjectSetQueryDataType - extends BaseQueryDataTypeDefinition<"objectSet"> -{ +export interface ObjectSetQueryDataType< + K extends string, + T_Target extends ObjectTypeDefinition = never, +> extends BaseQueryDataTypeDefinition<"objectSet"> { objectSet: K; + __OsdkTargetType?: T_Target; } export interface SetQueryDataType diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts index 80f1997ad..53c270987 100644 --- a/packages/client.api/src/queries/Queries.ts +++ b/packages/client.api/src/queries/Queries.ts @@ -42,37 +42,40 @@ export type QuerySignatureFromDef> = ) => Promise>; export type QueryParameterType< - T extends Record>, + T extends Record>, > = NOOP, OptionalQueryParams>>; -export type QueryReturnType> = +export type QueryReturnType> = T["type"] extends keyof DataValueClientToWire ? DataValueClientToWire[T["type"]] : never; -type OptionalQueryParams>> = - { - [K in keyof T]: T[K] extends { nullable: true } ? never : K; - }[keyof T]; +type OptionalQueryParams< + T extends Record>, +> = { + [K in keyof T]: T[K] extends { nullable: true } ? never : K; +}[keyof T]; -type NotOptionalParams>> = { +type NotOptionalParams< + T extends Record>, +> = { [K in keyof T]: MaybeArrayType; }; -type MaybeArrayType> = +type MaybeArrayType> = T["multiplicity"] extends true ? Array> : BaseType; +type BaseType> = T extends + ObjectQueryDataType + ? OsdkBase | OsdkObjectPrimaryKeyType + : T extends ObjectSetQueryDataType + ? BaseObjectSet + : T["type"] extends keyof DataValueClientToWire + ? DataValueClientToWire[T["type"]] + : never; // type BaseType> = T extends -// ObjectQueryDataType -// ? OsdkBase | OsdkObjectPrimaryKeyType -// : T extends ObjectSetQueryDataType -// ? BaseObjectSet +// ObjectQueryDataType | ObjectSetQueryDataType ? never // : T["type"] extends keyof DataValueClientToWire // ? DataValueClientToWire[T["type"]] // : never; -type BaseType> = T extends - ObjectQueryDataType | ObjectSetQueryDataType ? never - : T["type"] extends keyof DataValueClientToWire - ? DataValueClientToWire[T["type"]] - : never; diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index 2cf6fb46c..40e795d4a 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -52,6 +52,23 @@ describe("queries", () => { }); it("accepts objects", async () => { + const employee = await client(MockOntology.objects.Employee).fetchOne( + 50030, + ); + const result = await client(queryAcceptsObject)({ object: employee }); + expect(result).toEqual({ + apiName: "Employee", + objectType: "Employee", + primaryKey: 50031, + }); + + // Should also accept primary keys + const result2 = await client(queryAcceptsObject)({ object: 50030 }); + expect(result2).toEqual({ + apiName: "Employee", + objectType: "Employee", + primaryKey: 50031, + }); }); it("no params work", async () => { diff --git a/packages/client/src/util/isOntologyObjectV2.ts b/packages/client/src/util/isOntologyObjectV2.ts index e9e879c80..01fef155f 100644 --- a/packages/client/src/util/isOntologyObjectV2.ts +++ b/packages/client/src/util/isOntologyObjectV2.ts @@ -14,9 +14,15 @@ * limitations under the License. */ +import type { OsdkBase } from "@osdk/client.api"; import type { OntologyObjectV2 } from "@osdk/internal.foundry"; export function isOntologyObjectV2(o: any): o is OntologyObjectV2 { return o && typeof o === "object" && typeof o.__apiName === "string" && o.__primaryKey != null; } + +export function isOsdkBaseObject(o: any): o is OsdkBase { + return o && typeof o === "object" && typeof o.$apiName === "string" + && o.$primaryKey != null; +} diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index 019d86573..6a7d21ce7 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -24,7 +24,7 @@ import { isAttachmentUpload, } from "../object/Attachment.js"; import { getWireObjectSet, isObjectSet } from "../objectSet/createObjectSet.js"; -import { isOntologyObjectV2 } from "./isOntologyObjectV2.js"; +import { isOntologyObjectV2, isOsdkBaseObject } from "./isOntologyObjectV2.js"; import { isWireObjectSet } from "./WireObjectSet.js"; /** @@ -103,8 +103,8 @@ export async function toDataValueQueries( } // objects just send the JSON'd primaryKey - if (isOntologyObjectV2(value) && desiredType.type === "object") { - return value.__primaryKey; + if (isOsdkBaseObject(value) && desiredType.type === "object") { + return value.$primaryKey; } if (desiredType.type === "objectSet") { diff --git a/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts b/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts index 39f87333d..e9c8b31b8 100644 --- a/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts +++ b/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts @@ -28,10 +28,13 @@ import type { TwoDimensionalAggregation, } from "@osdk/gateway/types"; import { isNullableQueryDataType } from "./isNullableQueryDataType.js"; +import { getObjectDefIdentifier } from "./wireObjectTypeV2ToSdkObjectConst.js"; -export function wireQueryDataTypeToQueryDataTypeDefinition( +export function wireQueryDataTypeToQueryDataTypeDefinition< + K extends string, +>( input: QueryDataType, -): QueryDataTypeDefinition { +): QueryDataTypeDefinition { switch (input.type) { case "double": case "float": diff --git a/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts b/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts index 150ac30ba..de74008f6 100644 --- a/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts +++ b/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts @@ -36,7 +36,19 @@ export function wireQueryTypeV2ToSdkQueryDefinition( }; } -function wireQueryParameterV2ToQueryParameterDefinition( +export function wireQueryTypeV2ToSdkQueryDefinitionNoParams( + input: QueryTypeV2, +) { + return { + type: "query", + apiName: input.apiName, + description: input.description, + displayName: input.displayName, + version: input.version, + }; +} + +export function wireQueryParameterV2ToQueryParameterDefinition( parameter: QueryParameterV2, ): QueryParameterDefinition { return { diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index b928fde94..4638faeac 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -17,7 +17,15 @@ import type { QueryDataType, QueryTypeV2 } from "@osdk/gateway/types"; import path from "node:path"; import type { MinimalFs } from "../MinimalFs.js"; -import { wireQueryTypeV2ToSdkQueryDefinition } from "../shared/wireQueryTypeV2ToSdkQueryDefinition.js"; +import { getObjectDefIdentifier } from "../shared/wireObjectTypeV2ToSdkObjectConst.js"; +import { wireQueryDataTypeToQueryDataTypeDefinition } from "../shared/wireQueryDataTypeToQueryDataTypeDefinition.js"; +import { + wireQueryParameterV2ToQueryParameterDefinition, + wireQueryTypeV2ToSdkQueryDefinition, + wireQueryTypeV2ToSdkQueryDefinitionNoParams, +} from "../shared/wireQueryTypeV2ToSdkQueryDefinition.js"; +import { deleteUndefineds } from "../util/deleteUndefineds.js"; +import { stringify } from "../util/stringify.js"; import { formatTs } from "../util/test/formatTs.js"; import type { WireOntologyDefinition } from "../WireOntologyDefinition.js"; @@ -26,24 +34,119 @@ export async function generatePerQueryDataFiles( fs: MinimalFs, outDir: string, importExt: string = "", + v2: boolean = false, ) { await fs.mkdir(outDir, { recursive: true }); await Promise.all( Object.values(ontology.queryTypes).map(async query => { const objectTypes = getObjectTypesFromQuery(query); - await fs.writeFile( - path.join(outDir, `${query.apiName}.ts`), - await formatTs(` - import { QueryDefinition } from "@osdk/api"; - - export const ${query.apiName} = ${ - JSON.stringify(wireQueryTypeV2ToSdkQueryDefinition(query)) - } satisfies QueryDefinition<"${query.apiName}", ${ - objectTypes.length > 0 - ? objectTypes.map(apiName => `"${apiName}"`).join("|") - : "never" - }>;`), - ); + const importObjects = objectTypes.length > 0 + ? `import {${ + [...objectTypes].join(",") + }} from "../objects${importExt}";` + : ""; + if (v2) { + await fs.writeFile( + path.join(outDir, `${query.apiName}.ts`), + await formatTs(` + import { QueryDefinition } from "@osdk/api"; + ${importObjects} + export const ${query.apiName} = { + ${ + stringify( + deleteUndefineds( + wireQueryTypeV2ToSdkQueryDefinitionNoParams(query), + ), + ) + }, + parameters: {${ + Object.entries(query.parameters).map(( + [name, parameter], + ) => { + return ` + ${name}: ${ + parameter.dataType.type === "object" + ? `{ + type: "object", + object: "${parameter.dataType.objectTypeApiName}", + nullable: false, + __OsdkTargetType: ${ + getObjectDefIdentifier( + parameter.dataType.objectTypeApiName, + true, + ) + }, + }` + : parameter.dataType.type === "objectSet" + ? `{ + type: "object", + object: "${parameter.dataType.objectTypeApiName}", + nullable: false, + __OsdkTargetType: ${ + getObjectDefIdentifier( + parameter.dataType.objectTypeApiName!, + true, + ) + }, + }` + : JSON.stringify( + wireQueryParameterV2ToQueryParameterDefinition(parameter), + ) + } + `; + }) + }}, + output: ${ + query.output.type === "object" + ? `{ + type: "object", + object: "${query.output.objectTypeApiName}", + nullable: false, + __OsdkTargetType: ${ + getObjectDefIdentifier( + query.output.objectTypeApiName, + true, + ) + }, + }` + : query.output.type === "objectSet" + ? `{ + type: "object", + object: "${query.output.objectTypeApiName}", + nullable: false, + __OsdkTargetType: ${ + getObjectDefIdentifier( + query.output.objectTypeApiName!, + true, + ) + }, + }` + : JSON.stringify( + wireQueryDataTypeToQueryDataTypeDefinition(query.output), + ) + }, + + } satisfies QueryDefinition<"${query.apiName}", ${ + objectTypes.length > 0 + ? objectTypes.map(apiName => `"${apiName}"`).join("|") + : "never" + }>;`), + ); + } else { + await fs.writeFile( + path.join(outDir, `${query.apiName}.ts`), + await formatTs(` + import { QueryDefinition } from "@osdk/api"; + + export const ${query.apiName} = ${ + JSON.stringify(wireQueryTypeV2ToSdkQueryDefinition(query)) + } satisfies QueryDefinition<"${query.apiName}", ${ + objectTypes.length > 0 + ? objectTypes.map(apiName => `"${apiName}"`).join("|") + : "never" + }>;`), + ); + } }), ); diff --git a/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts b/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts index 2f97cd18e..bc445f0dd 100644 --- a/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts +++ b/packages/generator/src/v2.0/generateClientSdkVersionTwoPointZero.ts @@ -207,6 +207,7 @@ export async function generateClientSdkVersionTwoPointZero( fs, queriesDir, importExt, + true, ); } diff --git a/packages/legacy-client/src/client/queries.ts b/packages/legacy-client/src/client/queries.ts index 09ed71a32..6cb197f2a 100644 --- a/packages/legacy-client/src/client/queries.ts +++ b/packages/legacy-client/src/client/queries.ts @@ -103,7 +103,7 @@ export type QueryNamesFrom> = export type QueryDataType< O extends OntologyDefinition, - D extends QueryDataTypeDefinition, + D extends QueryDataTypeDefinition, T_ReturnValue extends boolean, > = D["multiplicity"] extends true ? Array> @@ -130,12 +130,12 @@ export type QueryDataTypeBase< ? (R extends true ? X extends "long" ? string : ValidLegacyBaseQueryDataTypes[X] : ValidLegacyBaseQueryDataTypes[X]) - : T extends ObjectQueryDataType + : T extends ObjectQueryDataType ? R extends true ? OsdkLegacyObjectFrom : | OsdkLegacyObjectFrom | OsdkLegacyObjectFrom["__primaryKey"] - : T extends ObjectSetQueryDataType + : T extends ObjectSetQueryDataType ? ObjectSet> : T extends SetQueryDataType ? Set> : T extends TwoDimensionalAggregationDataType ? TwoDimensionalAggregation< diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index 0a7d98a70..45a2fca7b 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -18,7 +18,7 @@ import type { ExecuteQueryRequest, ExecuteQueryResponse, } from "@osdk/gateway/types"; -import { employee1 } from "./objects.js"; +import { employee1, employee2 } from "./objects.js"; import { addOneQueryType, queryTypeAcceptsObjects, @@ -71,11 +71,23 @@ export const queryTypeReturnsObjectResponse: ExecuteQueryResponse = { }; export const queryTypeAcceptsObjectRequest: ExecuteQueryRequest = { - parameters: {}, + parameters: { object: employee1.__primaryKey }, }; export const queryTypeAcceptsObjectResponse: ExecuteQueryResponse = { - value: employee1.__primaryKey, + value: employee2.__primaryKey, +}; + +export const queryTypeAcceptsObjectSetRequest: ExecuteQueryRequest = { + parameters: { + employees: { type: "base", objectType: "employee" }, + }, +}; + +export const queryTypeAcceptsObjectSetResponse: ExecuteQueryResponse = { + value: { + employees: { type: "base", objectType: "employee" }, + }, }; export const queryTypeThreeDimensionalAggregationResponse: diff --git a/packages/shared.test/src/stubs/queryTypes.ts b/packages/shared.test/src/stubs/queryTypes.ts index 625765823..ef090e816 100644 --- a/packages/shared.test/src/stubs/queryTypes.ts +++ b/packages/shared.test/src/stubs/queryTypes.ts @@ -213,6 +213,28 @@ export const queryTypeAcceptsObjects: QueryTypeV2 = { version: "0.11.0", }; +export const queryTypeAcceptsObjectSets: QueryTypeV2 = { + apiName: "queryAcceptsObjectSets", + description: "description of the query that takes objectSet types", + displayName: "QueryAcceptsObjectSets", + parameters: { + objectSet: { + dataType: { + type: "objectSet", + objectApiName: "Employee", + objectTypeApiName: "Employee", + }, + }, + }, + output: { + type: "objectSet", + objectApiName: "Employee", + objectTypeApiName: "Employee", + }, + rid: + "ri.function-registry.main.function.9b55870a-63c7-4d48-8f06-9627c0805968", + version: "0.11.0", +}; export const queryTypes: QueryTypeV2[] = [ addOneQueryType, queryTypeReturnsStruct, @@ -222,4 +244,5 @@ export const queryTypes: QueryTypeV2[] = [ queryTypeTwoDimensionalAggregation, queryTypeThreeDimensionalAggregation, queryTypeAcceptsObjects, + queryTypeAcceptsObjectSets, ]; From 041f34d2065c5a102e7cd3ad8d243969522e7ce9 Mon Sep 17 00:00:00 2001 From: Saurav Date: Mon, 24 Jun 2024 16:56:47 -0400 Subject: [PATCH 06/21] object set support --- packages/client/src/queries/applyQuery.ts | 31 ++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index 0a409440d..ef74215e2 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -62,13 +62,14 @@ export async function applyQuery< : {}, }, ); - + const objectOutputDefs = await getRequiredDefinitions(query.output, client); // eslint-disable-next-line no-console console.log("I got a response,", response, query); const remappedResponse = await remapQueryResponse( client, query.output, response.value, + objectOutputDefs, ); return remappedResponse; } @@ -98,7 +99,7 @@ async function remapQueryResponse< client: MinimalClient, responseDataType: T, responseValue: DataValue, - // definitions: Map, + definitions: Map, ): Promise> { // handle null responses if (responseValue == null) { @@ -122,6 +123,7 @@ async function remapQueryResponse< responseValue[i], withoutMultiplicity, client, + definitions, ); } return responseValue as QueryReturnType; @@ -138,6 +140,7 @@ async function remapQueryResponse< responseValue[i], responseDataType.set, client, + definitions, ); } @@ -213,6 +216,7 @@ async function remapQueryResponse< responseValue[key], subtype, client, + definitions, ); } } @@ -243,25 +247,28 @@ async function remapQueryResponse< return responseValue as QueryReturnType; } -export function getRequiredDefinitions( +async function getRequiredDefinitions( dataType: QueryDataTypeDefinition, -): Set { - const result = new Set(); + client: MinimalClient, +): Promise> { + const result = new Map(); switch (dataType.type) { case "objectSet": - result.add(dataType.objectSet); + const objectDef = await client.ontologyProvider.getObjectDefinition( + dataType.objectSet, + ); + result.set(dataType.objectSet, objectDef); break; case "set": - for (const s of getRequiredDefinitions(dataType.set)) { - result.add(s); - } - break; + return getRequiredDefinitions(dataType.set, client); case "struct": for (const value of Object.values(dataType.struct)) { - for (const s of getRequiredDefinitions(value)) { - result.add(s); + for ( + const [type, objectDef] of await getRequiredDefinitions(value, client) + ) { + result.set(type, objectDef); } } break; From 7caaddb333ae98816395cd718ea71c2660acb2f7 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 25 Jun 2024 11:53:39 -0400 Subject: [PATCH 07/21] add obejctset supoprt --- .../queries/queryTakesAllParameterTypes.ts | 4 +- .../src/mapping/DataValueMapping.ts | 13 ++++ packages/client.api/src/queries/Queries.ts | 8 ++- packages/client/src/Client.ts | 2 - packages/client/src/createClient.ts | 1 - packages/client/src/queries/applyQuery.ts | 72 +++++++------------ packages/client/src/queries/queries.test.ts | 22 +++++- packages/client/src/util/datamapping.ts | 45 ------------ .../client/src/util/toDataValueQueries.ts | 12 +--- .../src/v1.1/generatePerQueryDataFiles.ts | 8 +-- .../src/handlers/loadObjectsEndpoints.ts | 2 + packages/shared.test/src/stubs/queries.ts | 9 ++- 12 files changed, 82 insertions(+), 116 deletions(-) delete mode 100644 packages/client/src/util/datamapping.ts diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 3ffcf00a4..d2fa15e99 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -23,8 +23,8 @@ export const queryTakesAllParameterTypes = { __OsdkTargetType: Todo, }, objectSet: { - type: 'object', - object: 'Todo', + type: 'objectSet', + objectSet: 'Todo', nullable: false, __OsdkTargetType: Todo, }, diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index 3d9557929..4b8f9a2dd 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ObjectSet } from "../index.js"; import type { Attachment, AttachmentUpload } from "../object/Attachment.js"; import type { QueryObjectResponse } from "../queries/queryObjectResponse.js"; @@ -35,6 +36,18 @@ export interface DataValueWireToClient { short: number; string: string; timestamp: string; + object: QueryObjectResponse; + objectSet: ObjectSet; + twoDimensionalAggregation: { + key: allowedBucketKeyTypes; + value: allowedBucketTypes; + }[]; + threeDimensionalAggregation: { + key: allowedBucketKeyTypes; + groups: { key: allowedBucketKeyTypes; value: allowedBucketTypes }[]; + }[]; + struct: Record; + set: Set; } /** diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts index 53c270987..c5a99c107 100644 --- a/packages/client.api/src/queries/Queries.ts +++ b/packages/client.api/src/queries/Queries.ts @@ -24,7 +24,9 @@ import type { import type { BaseObjectSet, DataValueClientToWire, + DataValueWireToClient, NOOP, + ObjectSet, OsdkBase, OsdkObjectPrimaryKeyType, } from "../index.js"; @@ -46,8 +48,10 @@ export type QueryParameterType< > = NOOP, OptionalQueryParams>>; export type QueryReturnType> = - T["type"] extends keyof DataValueClientToWire - ? DataValueClientToWire[T["type"]] + T extends ObjectSetQueryDataType + ? ObjectSet + : T["type"] extends keyof DataValueWireToClient + ? DataValueWireToClient[T["type"]] : never; type OptionalQueryParams< diff --git a/packages/client/src/Client.ts b/packages/client/src/Client.ts index d2b9c5c6f..7ec520924 100644 --- a/packages/client/src/Client.ts +++ b/packages/client/src/Client.ts @@ -22,8 +22,6 @@ import type { } from "@osdk/api"; import type { ActionSignatureFromDef, - Attachment, - AttachmentSignature, ObjectSet, QuerySignatureFromDef, } from "@osdk/client.api"; diff --git a/packages/client/src/createClient.ts b/packages/client/src/createClient.ts index 299984cdb..c7d20a6d3 100644 --- a/packages/client/src/createClient.ts +++ b/packages/client/src/createClient.ts @@ -23,7 +23,6 @@ import type { } from "@osdk/api"; import type { ActionSignatureFromDef, - AttachmentSignature, MinimalObjectSet, ObjectSet, QuerySignatureFromDef, diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index ef74215e2..04fd7da0b 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -21,6 +21,7 @@ import type { QueryParameterDefinition, } from "@osdk/api"; import type { + Attachment, DataValueWireToClient, QueryObjectResponse, QueryParameterType, @@ -31,8 +32,8 @@ import type { ObjectSet as WireObjectSet, } from "@osdk/internal.foundry"; import { OntologiesV2 } from "@osdk/internal.foundry"; +import { createAttachmentFromRid } from "../createAttachmentFromRid.js"; import type { MinimalClient } from "../MinimalClientContext.js"; -import { Attachment } from "../object/Attachment.js"; import { createObjectSet } from "../objectSet/createObjectSet.js"; import { addUserAgent } from "../util/addUserAgent.js"; import { toDataValue } from "../util/toDataValue.js"; @@ -71,7 +72,7 @@ export async function applyQuery< response.value, objectOutputDefs, ); - return remappedResponse; + return remappedResponse as QueryReturnType; } async function remapQueryParams( @@ -148,7 +149,7 @@ async function remapQueryResponse< } case "attachment": { - return new Attachment(responseValue) as QueryReturnType< + return createAttachmentFromRid(client, responseValue) as QueryReturnType< typeof responseDataType >; } @@ -161,52 +162,31 @@ async function remapQueryResponse< typeof responseDataType >; } - // const def = definitions.get(responseDataType.object); - // const withPk: WireObjectSet = { - // type: "filter", - // objectSet: { - // type: "base", - // objectType: responseDataType.object, - // }, - // where: { - // type: "eq", - // field: def?.properties["pr"], - // value: primaryKey, - // }, - // }; - // } - // return await fetchSingle( - // clientCtx, - // objectType, - // options, - // withPk, - // ) as Osdk; case "objectSet": { - throw new Error("not implemented"); - // const def = definitions.get(responseDataType.objectSet); - // if (!def) { - // throw new Error( - // `Missing definition for ${responseDataType.objectSet}`, - // ); - // } - // if (typeof responseValue === "string") { - // return createObjectSet(def, client, { - // type: "intersect", - // objectSets: [ - // { type: "base", objectType: responseDataType.objectSet }, - // { type: "reference", reference: responseValue }, - // ], - // }) as unknown as QueryReturnType; - // } + const def = definitions.get(responseDataType.objectSet); + if (!def) { + throw new Error( + `Missing definition for ${responseDataType.objectSet}`, + ); + } + if (typeof responseValue === "string") { + return createObjectSet(def, client, { + type: "intersect", + objectSets: [ + { type: "base", objectType: responseDataType.objectSet }, + { type: "reference", reference: responseValue }, + ], + }) as QueryReturnType; + } - // return createObjectSet( - // def, - // client, - // responseValue, - // ) as unknown as QueryReturnType< - // typeof responseDataType - // >; + return createObjectSet( + def, + client, + responseValue, + ) as QueryReturnType< + typeof responseDataType + >; } case "struct": { // figure out what keys need to be fixed up diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index 40e795d4a..d38fd9d8a 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -14,19 +14,28 @@ * limitations under the License. */ -import type { QuerySignatureFromDef } from "@osdk/client.api"; +import type { ObjectSet, QuerySignatureFromDef } from "@osdk/client.api"; +import type { Employee } from "@osdk/client.test.ontology"; import { addOne, incrementPersonAge, Ontology as MockOntology, queryAcceptsObject, + queryAcceptsObjectSets, returnsDate, returnsTimestamp, threeDimensionalAggregationFunction, twoDimensionalAggregationFunction, } from "@osdk/client.test.ontology"; import { apiServer } from "@osdk/shared.test"; -import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import { + afterAll, + beforeAll, + describe, + expect, + expectTypeOf, + it, +} from "vitest"; import type { Client } from "../Client.js"; import { createClient } from "../createClient.js"; @@ -71,6 +80,15 @@ describe("queries", () => { }); }); + it("accepts objectSets", async () => { + const employeeObjectSet = client(MockOntology.objects.Employee); + const result = await client(queryAcceptsObjectSets)({ + objectSet: employeeObjectSet, + }); + + expectTypeOf().toMatchTypeOf>(); + }); + it("no params work", async () => { const resultWithTimestamp = await client(returnsTimestamp)(); expect(resultWithTimestamp).toBe("2019-01-01T00:00:00.000Z"); diff --git a/packages/client/src/util/datamapping.ts b/packages/client/src/util/datamapping.ts deleted file mode 100644 index 21693bd20..000000000 --- a/packages/client/src/util/datamapping.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 Palantir Technologies, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { - Attachment, - AttachmentUpload, - QueryObjectResponse, -} from "@osdk/client.api"; -import type { ObjectSet } from "../objectSet/ObjectSet.js"; - -export interface DataValueClientToWire { - attachment: Attachment | AttachmentUpload; - boolean: boolean; - byte: number; - datetime: string; - decimal: string | number; - float: number; - double: number; - integer: number; - long: string | number; - marking: string; - null: null; - short: number; - string: string; - timestamp: string; - set: Set; - twoDimensionalAggregation: Record; - threeDimensionalAggregation: Record>; - struct: Record; - object: QueryObjectResponse; - objectSet: ObjectSet; -} diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index 6a7d21ce7..66529db7f 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -15,14 +15,11 @@ */ import type { QueryDataTypeDefinition } from "@osdk/api"; +import { Attachment } from "@osdk/client.api"; import { type DataValue, Ontologies } from "@osdk/internal.foundry"; import type { SharedClient, SharedClientContext } from "@osdk/shared.client"; import type { MinimalClient } from "../MinimalClientContext.js"; -import { - Attachment, - isAttachment, - isAttachmentUpload, -} from "../object/Attachment.js"; +import { isAttachmentUpload } from "../object/AttachmentUpload.js"; import { getWireObjectSet, isObjectSet } from "../objectSet/createObjectSet.js"; import { isOntologyObjectV2, isOsdkBaseObject } from "./isOntologyObjectV2.js"; import { isWireObjectSet } from "./WireObjectSet.js"; @@ -60,11 +57,6 @@ export async function toDataValueQueries( return Promise.all(promiseArray); } - // attachments just send the rid directly - if (isAttachment(value) && desiredType.type === "attachment") { - return value.rid; - } - // For uploads, we need to upload ourselves first to get the RID of the attachment if (isAttachmentUpload(value) && desiredType.type === "attachment") { const attachment = await Ontologies.Attachments.uploadAttachment( diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index 4638faeac..75f247543 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -79,8 +79,8 @@ export async function generatePerQueryDataFiles( }` : parameter.dataType.type === "objectSet" ? `{ - type: "object", - object: "${parameter.dataType.objectTypeApiName}", + type: "objectSet", + objectSet: "${parameter.dataType.objectTypeApiName}", nullable: false, __OsdkTargetType: ${ getObjectDefIdentifier( @@ -111,8 +111,8 @@ export async function generatePerQueryDataFiles( }` : query.output.type === "objectSet" ? `{ - type: "object", - object: "${query.output.objectTypeApiName}", + type: "objectSet", + objectSet: "${query.output.objectTypeApiName}", nullable: false, __OsdkTargetType: ${ getObjectDefIdentifier( diff --git a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts index 22943b289..5388d1f6c 100644 --- a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts +++ b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts @@ -489,6 +489,8 @@ export const loadObjectsEndpoints: Array = [ console.error("here i am", parsedBody, queryApiName); const queryResponses = queryRequestHandlers[queryApiName]; + // eslint-disable-next-line no-console + console.error("hereiam3", queryResponses); if (!queryResponses) { throw new OpenApiCallError(404, QueryNotFoundError(queryApiName)); } diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index 45a2fca7b..a9c090d9b 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -22,6 +22,7 @@ import { employee1, employee2 } from "./objects.js"; import { addOneQueryType, queryTypeAcceptsObjects, + queryTypeAcceptsObjectSets, queryTypeReturnsDate, queryTypeReturnsObject, queryTypeReturnsStruct, @@ -80,13 +81,13 @@ export const queryTypeAcceptsObjectResponse: ExecuteQueryResponse = { export const queryTypeAcceptsObjectSetRequest: ExecuteQueryRequest = { parameters: { - employees: { type: "base", objectType: "employee" }, + objectSet: { type: "base", objectType: "Employee" }, }, }; export const queryTypeAcceptsObjectSetResponse: ExecuteQueryResponse = { value: { - employees: { type: "base", objectType: "employee" }, + objectSet: { type: "base", objectType: "Employee" }, }, }; @@ -165,4 +166,8 @@ export const queryRequestHandlers: { [JSON.stringify(queryTypeAcceptsObjectRequest)]: queryTypeAcceptsObjectResponse, }, + [queryTypeAcceptsObjectSets.apiName]: { + [JSON.stringify(queryTypeAcceptsObjectSetRequest)]: + queryTypeAcceptsObjectSetResponse, + }, }; From 3b0a0b049f28100ca7ae6e39807ca40e6db93434 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 25 Jun 2024 12:52:18 -0400 Subject: [PATCH 08/21] remove console logs --- packages/client/src/queries/applyQuery.ts | 9 +-------- packages/client/src/queries/queries.test.ts | 1 - .../shared.test/src/handlers/loadObjectsEndpoints.ts | 8 +------- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index 04fd7da0b..59bc16767 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -64,8 +64,6 @@ export async function applyQuery< }, ); const objectOutputDefs = await getRequiredDefinitions(query.output, client); - // eslint-disable-next-line no-console - console.log("I got a response,", response, query); const remappedResponse = await remapQueryResponse( client, query.output, @@ -82,8 +80,6 @@ async function remapQueryParams( ): Promise<{ [parameterId: string]: any }> { const parameterMap: { [parameterName: string]: unknown } = {}; for (const [key, value] of Object.entries(params)) { - // eslint-disable-next-line no-console - console.log("thisiswhatagain?", key, value); parameterMap[key] = await toDataValueQueries( value, client, @@ -110,10 +106,7 @@ async function remapQueryResponse< throw new Error("Got null response when nullable was not allowed"); } } - // eslint-disable-next-line no-console - console.log("lookiehere", responseDataType); - // eslint-disable-next-line no-console - console.log("lookiehere2", responseValue); + if ( responseDataType.multiplicity != null && responseDataType.multiplicity !== false diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index d38fd9d8a..9cd8fd811 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -101,7 +101,6 @@ describe("queries", () => { const result = await client(incrementPersonAge)({ person: { firstName: "John", lastName: "Doe", age: 42 }, }); - console.error(result); expect(result).toEqual({ firstName: "John", lastName: "Doe", diff --git a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts index 5388d1f6c..3700d4fbb 100644 --- a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts +++ b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts @@ -485,20 +485,14 @@ export const loadObjectsEndpoints: Array = [ ); } - // eslint-disable-next-line no-console - console.error("here i am", parsedBody, queryApiName); - const queryResponses = queryRequestHandlers[queryApiName]; - // eslint-disable-next-line no-console - console.error("hereiam3", queryResponses); + if (!queryResponses) { throw new OpenApiCallError(404, QueryNotFoundError(queryApiName)); } const queryResponse = queryResponses[JSON.stringify(parsedBody)]; - // eslint-disable-next-line no-console - console.error("here i am2", queryResponse, req); if ( req.params.ontologyApiName === defaultOntology.apiName || req.params.ontologyApiName === defaultOntology.rid From 173e4fc2d1c85465a137f458d6c56e39af490070 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 25 Jun 2024 13:00:38 -0400 Subject: [PATCH 09/21] remove newlines --- packages/shared.test/src/handlers/loadObjectsEndpoints.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts index 3700d4fbb..5084c07e8 100644 --- a/packages/shared.test/src/handlers/loadObjectsEndpoints.ts +++ b/packages/shared.test/src/handlers/loadObjectsEndpoints.ts @@ -486,13 +486,11 @@ export const loadObjectsEndpoints: Array = [ } const queryResponses = queryRequestHandlers[queryApiName]; - if (!queryResponses) { throw new OpenApiCallError(404, QueryNotFoundError(queryApiName)); } const queryResponse = queryResponses[JSON.stringify(parsedBody)]; - if ( req.params.ontologyApiName === defaultOntology.apiName || req.params.ontologyApiName === defaultOntology.rid From 373ef2b488c105dff6b1057985cf64055dfed341 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 25 Jun 2024 13:40:16 -0400 Subject: [PATCH 10/21] remove unsused endpoints file --- .../src/handlers/queriesEndpoints.ts | 82 ------------------- packages/shared.test/src/setupServers.ts | 1 - 2 files changed, 83 deletions(-) delete mode 100644 packages/shared.test/src/handlers/queriesEndpoints.ts diff --git a/packages/shared.test/src/handlers/queriesEndpoints.ts b/packages/shared.test/src/handlers/queriesEndpoints.ts deleted file mode 100644 index 62e0bf570..000000000 --- a/packages/shared.test/src/handlers/queriesEndpoints.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2024 Palantir Technologies, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { HttpResponseResolver, PathParams, RequestHandler } from "msw"; - -import { executeQueryV2 } from "@osdk/gateway/requests"; -import type { ExecuteQueryResponse } from "@osdk/gateway/types"; -import stableStringify from "json-stable-stringify"; -import type { BaseAPIError } from "../BaseError.js"; -import { - ApplyActionFailedError, - ExecuteQueryFailedError, - InvalidRequest, -} from "../errors.js"; -import { defaultOntology } from "../stubs/ontologies.js"; -import { queryRequestHandlers } from "../stubs/queries.js"; -import type { ExtractBody } from "./util/handleOpenApiCall.js"; -import { - handleOpenApiCall, - OpenApiCallError, -} from "./util/handleOpenApiCall.js"; - -export const queryHandlers: Array = [ - /** - * Execute Query - */ - handleOpenApiCall( - executeQueryV2, - ["ontologyApiName", "queryApiName"], - handleQuery, - ), -]; - -async function handleQuery< - T extends ExecuteQueryResponse, ->( - req: Parameters< - HttpResponseResolver< - PathParams, - | ExtractBody - | T - | BaseAPIError - > - >[0], -) { - const parsedBody = await req.request.json(); - - const ontologyApiName = req.params.ontologyApiName; - const queryType = req.params.queryApiName; - - if ( - typeof ontologyApiName !== "string" || typeof queryType !== "string" - ) { - throw new OpenApiCallError(400, InvalidRequest("Invalid parameters")); - } - - const queryResponse = - queryRequestHandlers[queryType][stableStringify(parsedBody)]; - - if ( - (req.params.ontologyApiName === defaultOntology.apiName - || req.params.ontologyApiName === defaultOntology.rid) - && queryResponse - ) { - return queryResponse; - } - - throw new OpenApiCallError(400, ExecuteQueryFailedError); -} diff --git a/packages/shared.test/src/setupServers.ts b/packages/shared.test/src/setupServers.ts index 5ade6bd5a..236a71be2 100644 --- a/packages/shared.test/src/setupServers.ts +++ b/packages/shared.test/src/setupServers.ts @@ -23,7 +23,6 @@ import { objectSetHandlers, ontologyMetadataEndpoint, } from "./handlers/index.js"; -import { queryHandlers } from "./handlers/queriesEndpoints.js"; export const apiServer: SetupServer = setupServer( ...loadObjectsEndpoints, From 8680c25667fd9a1ae94ed1e5d84c4d37e51001a2 Mon Sep 17 00:00:00 2001 From: Saurav Date: Wed, 26 Jun 2024 09:23:26 -0500 Subject: [PATCH 11/21] add 2d agg input support --- .../src/mapping/DataValueMapping.ts | 4 - packages/client.api/src/queries/Queries.ts | 10 +- packages/client/src/queries/applyQuery.ts | 56 ++++-- packages/client/src/queries/queries.test.ts | 32 +++- .../client/src/util/toDataValueQueries.ts | 180 ++++++++---------- packages/shared.test/src/stubs/queries.ts | 39 ++++ packages/shared.test/src/stubs/queryTypes.ts | 31 +++ 7 files changed, 221 insertions(+), 131 deletions(-) diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index 4b8f9a2dd..5e10e1586 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -36,8 +36,6 @@ export interface DataValueWireToClient { short: number; string: string; timestamp: string; - object: QueryObjectResponse; - objectSet: ObjectSet; twoDimensionalAggregation: { key: allowedBucketKeyTypes; value: allowedBucketTypes; @@ -78,8 +76,6 @@ export interface DataValueClientToWire { groups: { key: allowedBucketKeyTypes; value: allowedBucketTypes }[]; }[]; struct: Record; - object: QueryObjectResponse; - objectSet: never; } type allowedBucketTypes = string | number | boolean; diff --git a/packages/client.api/src/queries/Queries.ts b/packages/client.api/src/queries/Queries.ts index c5a99c107..66e630b5a 100644 --- a/packages/client.api/src/queries/Queries.ts +++ b/packages/client.api/src/queries/Queries.ts @@ -48,8 +48,9 @@ export type QueryParameterType< > = NOOP, OptionalQueryParams>>; export type QueryReturnType> = - T extends ObjectSetQueryDataType - ? ObjectSet + T extends ObjectQueryDataType ? OsdkBase + : T extends ObjectSetQueryDataType + ? ObjectSet : T["type"] extends keyof DataValueWireToClient ? DataValueWireToClient[T["type"]] : never; @@ -78,8 +79,3 @@ type BaseType> = T extends : T["type"] extends keyof DataValueClientToWire ? DataValueClientToWire[T["type"]] : never; -// type BaseType> = T extends -// ObjectQueryDataType | ObjectSetQueryDataType ? never -// : T["type"] extends keyof DataValueClientToWire -// ? DataValueClientToWire[T["type"]] -// : never; diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index 59bc16767..81909c9b9 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -15,7 +15,9 @@ */ import type { + InterfaceDefinition, ObjectOrInterfaceDefinition, + ObjectTypeDefinition, QueryDataTypeDefinition, QueryDefinition, QueryParameterDefinition, @@ -23,6 +25,8 @@ import type { import type { Attachment, DataValueWireToClient, + OsdkBase, + OsdkObjectPrimaryKeyType, QueryObjectResponse, QueryParameterType, QueryReturnType, @@ -91,7 +95,7 @@ async function remapQueryParams( async function remapQueryResponse< K extends string, - T extends QueryDataTypeDefinition, + T extends QueryDataTypeDefinition, >( client: MinimalClient, responseDataType: T, @@ -125,7 +129,7 @@ async function remapQueryResponse< switch (responseDataType.type) { case "union": { - throw new Error("Union return types are not supported"); + throw new Error("Union return types are not yet supported"); } case "set": { @@ -147,10 +151,15 @@ async function remapQueryResponse< >; } case "object": { + const def = definitions.get(responseDataType.object); + if (!def) { + throw new Error( + `Missing definition for ${responseDataType.object}`, + ); + } return createQueryObjectResponse( - responseDataType.object, responseValue, - responseDataType.object, + def, ) as QueryReturnType< typeof responseDataType >; @@ -226,17 +235,26 @@ async function getRequiredDefinitions( ): Promise> { const result = new Map(); switch (dataType.type) { - case "objectSet": + case "objectSet": { const objectDef = await client.ontologyProvider.getObjectDefinition( dataType.objectSet, ); result.set(dataType.objectSet, objectDef); break; + } + case "object": { + const objectDef = await client.ontologyProvider.getObjectDefinition( + dataType.object, + ); + result.set(dataType.object, objectDef); + break; + } - case "set": + case "set": { return getRequiredDefinitions(dataType.set, client); + } - case "struct": + case "struct": { for (const value of Object.values(dataType.struct)) { for ( const [type, objectDef] of await getRequiredDefinitions(value, client) @@ -245,7 +263,7 @@ async function getRequiredDefinitions( } } break; - + } case "attachment": case "boolean": case "date": @@ -260,10 +278,6 @@ async function getRequiredDefinitions( case "twoDimensionalAggregation": case "union": break; - - default: - const _: never = dataType; - break; } return result; @@ -302,10 +316,16 @@ function requiresConversion(dataType: QueryDataTypeDefinition) { } } -export function createQueryObjectResponse( - objectType: string, - primaryKey: string, - apiName: N, -): QueryObjectResponse { - return { apiName, objectType, primaryKey }; +export function createQueryObjectResponse< + Q extends ObjectTypeDefinition | InterfaceDefinition, +>( + primaryKey: Q extends ObjectTypeDefinition ? OsdkObjectPrimaryKeyType + : unknown, + objectDef: Q, +): OsdkBase { + return { + $apiName: objectDef.apiName, + $objectType: objectDef.apiName, + $primaryKey: primaryKey, + }; } diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index 9cd8fd811..06fb222dc 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -17,6 +17,7 @@ import type { ObjectSet, QuerySignatureFromDef } from "@osdk/client.api"; import type { Employee } from "@osdk/client.test.ontology"; import { + acceptsTwoDimensionalAggregationFunction, addOne, incrementPersonAge, Ontology as MockOntology, @@ -66,17 +67,17 @@ describe("queries", () => { ); const result = await client(queryAcceptsObject)({ object: employee }); expect(result).toEqual({ - apiName: "Employee", - objectType: "Employee", - primaryKey: 50031, + $apiName: "Employee", + $objectType: "Employee", + $primaryKey: 50031, }); // Should also accept primary keys const result2 = await client(queryAcceptsObject)({ object: 50030 }); expect(result2).toEqual({ - apiName: "Employee", - objectType: "Employee", - primaryKey: 50031, + $apiName: "Employee", + $objectType: "Employee", + $primaryKey: 50031, }); }); @@ -116,6 +117,25 @@ describe("queries", () => { }]); }); + it("two dimensional aggs request/response works", async () => { + const result = await client(acceptsTwoDimensionalAggregationFunction)({ + aggFunction: [ + { + key: "testKey1", + value: 1, + }, + { + key: "testKey2", + value: 2, + }, + ], + }); + expect(result).toEqual([{ key: "responseKey1", value: 3 }, { + key: "responseKey2", + value: 4, + }]); + }); + it("three dimensional aggs response works", async () => { const result = await client(threeDimensionalAggregationFunction)(); expect(result).toEqual([{ diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index 66529db7f..e470d89a5 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -15,13 +15,11 @@ */ import type { QueryDataTypeDefinition } from "@osdk/api"; -import { Attachment } from "@osdk/client.api"; import { type DataValue, Ontologies } from "@osdk/internal.foundry"; -import type { SharedClient, SharedClientContext } from "@osdk/shared.client"; import type { MinimalClient } from "../MinimalClientContext.js"; import { isAttachmentUpload } from "../object/AttachmentUpload.js"; import { getWireObjectSet, isObjectSet } from "../objectSet/createObjectSet.js"; -import { isOntologyObjectV2, isOsdkBaseObject } from "./isOntologyObjectV2.js"; +import { isOsdkBaseObject } from "./isOntologyObjectV2.js"; import { isWireObjectSet } from "./WireObjectSet.js"; /** @@ -35,117 +33,107 @@ export async function toDataValueQueries( desiredType: QueryDataTypeDefinition, ): Promise { if (value == null) { - // typeof null is 'object' so do this first return value; } - // LOOK AT: For some reason, query parameter types do not specify arrays as an allowed type - if (Array.isArray(value)) { - const promiseArray = Array.from( - value, - async (innerValue) => - await toDataValueQueries(innerValue, client, desiredType), - ); - return Promise.all(promiseArray); - } - if (value instanceof Set && desiredType.type === "set") { + if (Array.isArray(value) && desiredType.multiplicity) { const promiseArray = Array.from( value, async (innerValue) => - await toDataValueQueries(innerValue, client, desiredType["set"]), + await toDataValueQueries(innerValue, client, desiredType), ); return Promise.all(promiseArray); } - // For uploads, we need to upload ourselves first to get the RID of the attachment - if (isAttachmentUpload(value) && desiredType.type === "attachment") { - const attachment = await Ontologies.Attachments.uploadAttachment( - client, - value, - { - filename: value.name, - }, - { - "Content-Length": value.size.toString(), - "Content-Type": value.type, - }, - ); - return attachment.rid; - } - - if (desiredType.type === "twoDimensionalAggregation") { - return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - values, - })), - }; - } + switch (desiredType.type) { + case "attachment": { + if (isAttachmentUpload(value)) { + const attachment = await Ontologies.Attachments.uploadAttachment( + client, + value, + { + filename: value.name, + }, + { + "Content-Length": value.size.toString(), + "Content-Type": value.type, + }, + ); + return attachment.rid; + } - if (desiredType.type === "threeDimensionalAggregation") { - return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - groups: Object.entries(values).map(([key, value]) => ({ + // If it's not an upload, it's just an attachment rid string which we can pass through + return value; + } + case "twoDimensionalAggregation": { + if (Array.isArray(value)) { + return { + groups: value, + }; + } + } + case "threeDimensionalAggregation": { + return { + groups: Object.entries(value).map(([key, values]) => ({ key, - value, + groups: Object.entries(values).map(([key, value]) => ({ + key, + value, + })), })), - })), - }; - } - - // objects just send the JSON'd primaryKey - if (isOsdkBaseObject(value) && desiredType.type === "object") { - return value.$primaryKey; - } + }; + } - if (desiredType.type === "objectSet") { - // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) - if (isWireObjectSet(value)) { - return value; + case "set": { + if (value instanceof Set) { + const promiseArray = Array.from( + value, + async (innerValue) => + await toDataValueQueries(innerValue, client, desiredType["set"]), + ); + return Promise.all(promiseArray); + } + break; } - if (isObjectSet(value)) { - return getWireObjectSet(value); + case "object": { + if (isOsdkBaseObject(value)) { + return value.$primaryKey; + } + break; + } + case "objectSet": { + // object set (the rid as a string (passes through the last return), or the ObjectSet definition directly) + if (isWireObjectSet(value)) { + return value; + } + if (isObjectSet(value)) { + return getWireObjectSet(value); + } + break; } - } - if (desiredType.type === "struct") { - const structMap: { [key: string]: unknown } = {}; - for (const [key, structValue] of Object.entries(value)) { - structMap[key] = await toDataValueQueries( - structValue, - client, - desiredType["struct"][key], - ); + case "struct": { + if (typeof value === "object") { + const structMap: { [key: string]: unknown } = {}; + for (const [key, structValue] of Object.entries(value)) { + structMap[key] = await toDataValueQueries( + structValue, + client, + desiredType["struct"][key], + ); + } + return structMap; + } } - return structMap; + case "boolean": + case "date": + case "double": + case "float": + case "integer": + case "long": + case "string": + case "timestamp": + return value; } return value; - - // switch (desiredType.type) { - // case "boolean": - // case "date": - // case "double": - // case "float": - // case "integer": - // case "long": - // case "string": - // case "timestamp": - // return value; - // case "attachment": { - // } - // case "twoDimensionalAggregation": { - // } - // case "threeDimensionalAggregation": { - // } - // case "set": { - // } - // case "object": { - // } - // case "objectSet": { - // } - - // case "struct": { - // } - // } } diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index a9c090d9b..550bc1cab 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -23,6 +23,7 @@ import { addOneQueryType, queryTypeAcceptsObjects, queryTypeAcceptsObjectSets, + queryTypeAcceptsTwoDimensionalAggregation, queryTypeReturnsDate, queryTypeReturnsObject, queryTypeReturnsStruct, @@ -131,6 +132,40 @@ export const queryTypeTwoDimensionalAggregationResponse: ExecuteQueryResponse = }, }; +export const queryTypeAcceptsTwoDimensionalAggregationRequest: + ExecuteQueryRequest = { + parameters: { + aggFunction: { + groups: [ + { + key: "testKey1", + value: 1, + }, + { + key: "testKey2", + value: 2, + }, + ], + }, + }, + }; + +export const queryTypeAcceptsTwoDimensionalAggregationResponse: + ExecuteQueryResponse = { + value: { + groups: [ + { + key: "responseKey1", + value: 3, + }, + { + key: "responseKey2", + value: 4, + }, + ], + }, + }; + export const emptyBody: string = JSON.stringify({ parameters: {}, }); @@ -170,4 +205,8 @@ export const queryRequestHandlers: { [JSON.stringify(queryTypeAcceptsObjectSetRequest)]: queryTypeAcceptsObjectSetResponse, }, + [queryTypeAcceptsTwoDimensionalAggregation.apiName]: { + [JSON.stringify(queryTypeAcceptsTwoDimensionalAggregationRequest)]: + queryTypeAcceptsTwoDimensionalAggregationResponse, + }, }; diff --git a/packages/shared.test/src/stubs/queryTypes.ts b/packages/shared.test/src/stubs/queryTypes.ts index ef090e816..f00351bad 100644 --- a/packages/shared.test/src/stubs/queryTypes.ts +++ b/packages/shared.test/src/stubs/queryTypes.ts @@ -190,6 +190,36 @@ export const queryTypeTwoDimensionalAggregation: QueryTypeV2 = { version: "0.11.0", }; +export const queryTypeAcceptsTwoDimensionalAggregation: QueryTypeV2 = { + apiName: "acceptsTwoDimensionalAggregationFunction", + displayName: "acceptsTwoDimensionalAggregation", + parameters: { + aggFunction: { + dataType: { + type: "twoDimensionalAggregation", + keyType: { + type: "string", + }, + valueType: { + type: "double", + }, + }, + }, + }, + output: { + type: "twoDimensionalAggregation", + keyType: { + type: "string", + }, + valueType: { + type: "double", + }, + }, + rid: + "ri.function-registry.main.function.9b55870a-63c7-4d48-8f06-9627c0805968", + version: "0.11.0", +}; + export const queryTypeAcceptsObjects: QueryTypeV2 = { apiName: "queryAcceptsObject", description: "description of the query that takes object types", @@ -245,4 +275,5 @@ export const queryTypes: QueryTypeV2[] = [ queryTypeThreeDimensionalAggregation, queryTypeAcceptsObjects, queryTypeAcceptsObjectSets, + queryTypeAcceptsTwoDimensionalAggregation, ]; From dd29ff36658c0adea6eef9fe4f95c3eefed83b68 Mon Sep 17 00:00:00 2001 From: Saurav Date: Wed, 26 Jun 2024 16:25:35 -0500 Subject: [PATCH 12/21] 3d agg test --- packages/client/src/queries/queries.test.ts | 42 ++++++++++++++ .../client/src/util/toDataValueQueries.ts | 16 ++---- packages/shared.test/src/stubs/queries.ts | 55 +++++++++++++++++++ packages/shared.test/src/stubs/queryTypes.ts | 47 ++++++++++++++++ 4 files changed, 148 insertions(+), 12 deletions(-) diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index 06fb222dc..fa5632136 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -17,6 +17,7 @@ import type { ObjectSet, QuerySignatureFromDef } from "@osdk/client.api"; import type { Employee } from "@osdk/client.test.ontology"; import { + acceptsThreeDimensionalAggregationFunction, acceptsTwoDimensionalAggregationFunction, addOne, incrementPersonAge, @@ -149,4 +150,45 @@ describe("queries", () => { }], }, { key: "Q-AFO", groups: [] }]); }); + + it("three dimensional aggs request/response works", async () => { + const result = await client(acceptsThreeDimensionalAggregationFunction)({ + aggFunction: [ + { + key: "testKey1", + groups: [ + { + key: { + startValue: "2010-10-01T00:00:00Z", + endValue: "2010-10-02T00:00:00Z", + }, + value: 65.0, + }, + ], + }, + { + key: "testKey2", + groups: [], + }, + ], + }); + expect(result).toEqual([ + { + key: "Q-AFN", + groups: [ + { + key: { + startValue: "2010-10-01T00:00:00Z", + endValue: "2010-10-02T00:00:00Z", + }, + value: 65.0, + }, + ], + }, + { + key: "Q-AFO", + groups: [], + }, + ]); + }); }); diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index e470d89a5..7b362dcb4 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -66,21 +66,13 @@ export async function toDataValueQueries( return value; } case "twoDimensionalAggregation": { - if (Array.isArray(value)) { - return { - groups: value, - }; - } + return { + groups: value, + }; } case "threeDimensionalAggregation": { return { - groups: Object.entries(value).map(([key, values]) => ({ - key, - groups: Object.entries(values).map(([key, value]) => ({ - key, - value, - })), - })), + groups: value, }; } diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index 550bc1cab..a966c6c77 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -23,6 +23,7 @@ import { addOneQueryType, queryTypeAcceptsObjects, queryTypeAcceptsObjectSets, + queryTypeAcceptsThreeDimensionalAggregation, queryTypeAcceptsTwoDimensionalAggregation, queryTypeReturnsDate, queryTypeReturnsObject, @@ -166,6 +167,56 @@ export const queryTypeAcceptsTwoDimensionalAggregationResponse: }, }; +export const queryTypeAcceptsThreeDimensionalAggregationRequest: + ExecuteQueryRequest = { + parameters: { + aggFunction: { + groups: [ + { + key: "testKey1", + groups: [ + { + key: { + startValue: "2010-10-01T00:00:00Z", + endValue: "2010-10-02T00:00:00Z", + }, + value: 65.0, + }, + ], + }, + { + key: "testKey2", + groups: [], + }, + ], + }, + }, + }; + +export const queryTypeAcceptsThreeDimensionalAggregationResponse: + ExecuteQueryResponse = { + value: { + groups: [ + { + key: "Q-AFN", + groups: [ + { + key: { + startValue: "2010-10-01T00:00:00Z", + endValue: "2010-10-02T00:00:00Z", + }, + value: 65.0, + }, + ], + }, + { + key: "Q-AFO", + groups: [], + }, + ], + }, + }; + export const emptyBody: string = JSON.stringify({ parameters: {}, }); @@ -209,4 +260,8 @@ export const queryRequestHandlers: { [JSON.stringify(queryTypeAcceptsTwoDimensionalAggregationRequest)]: queryTypeAcceptsTwoDimensionalAggregationResponse, }, + [queryTypeAcceptsThreeDimensionalAggregation.apiName]: { + [JSON.stringify(queryTypeAcceptsThreeDimensionalAggregationRequest)]: + queryTypeAcceptsThreeDimensionalAggregationResponse, + }, }; diff --git a/packages/shared.test/src/stubs/queryTypes.ts b/packages/shared.test/src/stubs/queryTypes.ts index f00351bad..c4f480766 100644 --- a/packages/shared.test/src/stubs/queryTypes.ts +++ b/packages/shared.test/src/stubs/queryTypes.ts @@ -220,6 +220,52 @@ export const queryTypeAcceptsTwoDimensionalAggregation: QueryTypeV2 = { version: "0.11.0", }; +export const queryTypeAcceptsThreeDimensionalAggregation: QueryTypeV2 = { + apiName: "acceptsThreeDimensionalAggregationFunction", + displayName: "acceptsThreeDimensionalAggregation", + parameters: { + aggFunction: { + dataType: { + type: "threeDimensionalAggregation", + keyType: { + type: "string", + }, + valueType: { + keyType: { + type: "range", + subType: { + type: "timestamp", + }, + }, + valueType: { + type: "double", + }, + }, + }, + }, + }, + output: { + type: "threeDimensionalAggregation", + keyType: { + type: "string", + }, + valueType: { + keyType: { + type: "range", + subType: { + type: "timestamp", + }, + }, + valueType: { + type: "double", + }, + }, + }, + rid: + "ri.function-registry.main.function.9b55870a-63c7-4d48-8f06-9627c0805968", + version: "0.11.0", +}; + export const queryTypeAcceptsObjects: QueryTypeV2 = { apiName: "queryAcceptsObject", description: "description of the query that takes object types", @@ -276,4 +322,5 @@ export const queryTypes: QueryTypeV2[] = [ queryTypeAcceptsObjects, queryTypeAcceptsObjectSets, queryTypeAcceptsTwoDimensionalAggregation, + queryTypeAcceptsThreeDimensionalAggregation, ]; From 0008a8bb731bbc691442bdf56d10605c17332de7 Mon Sep 17 00:00:00 2001 From: Saurav Date: Thu, 27 Jun 2024 09:08:24 -0400 Subject: [PATCH 13/21] a little cleanup --- .../queries/queryTakesAllParameterTypes.ts | 2 + packages/client.api/src/index.ts | 1 - .../src/mapping/DataValueMapping.ts | 2 - .../src/queries/queryObjectResponse.ts | 21 --------- packages/client/src/queries/applyQuery.ts | 13 +++--- .../src/v1.1/generatePerQueryDataFiles.ts | 44 +++++-------------- 6 files changed, 19 insertions(+), 64 deletions(-) delete mode 100644 packages/client.api/src/queries/queryObjectResponse.ts diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index d2fa15e99..8e2f36dd9 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -17,12 +17,14 @@ export const queryTakesAllParameterTypes = { string: { type: 'string', nullable: false }, timestamp: { type: 'timestamp', nullable: false }, object: { + description: 'undefined', type: 'object', object: 'Todo', nullable: false, __OsdkTargetType: Todo, }, objectSet: { + description: 'undefined', type: 'objectSet', objectSet: 'Todo', nullable: false, diff --git a/packages/client.api/src/index.ts b/packages/client.api/src/index.ts index dba788fcb..5e5883d76 100644 --- a/packages/client.api/src/index.ts +++ b/packages/client.api/src/index.ts @@ -118,7 +118,6 @@ export type { QueryReturnType, QuerySignatureFromDef, } from "./queries/Queries.js"; -export type { QueryObjectResponse } from "./queries/queryObjectResponse.js"; export type { LinkedType, LinkNames } from "./util/LinkUtils.js"; export type { NOOP } from "./util/NOOP.js"; diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index 5e10e1586..f900d4238 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import type { ObjectSet } from "../index.js"; import type { Attachment, AttachmentUpload } from "../object/Attachment.js"; -import type { QueryObjectResponse } from "../queries/queryObjectResponse.js"; /** * Map from the DataValue type to the typescript type that we return diff --git a/packages/client.api/src/queries/queryObjectResponse.ts b/packages/client.api/src/queries/queryObjectResponse.ts deleted file mode 100644 index 9cdbf0083..000000000 --- a/packages/client.api/src/queries/queryObjectResponse.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 Palantir Technologies, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface QueryObjectResponse { - apiName: N; - objectType: string; - primaryKey: string; -} diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index 81909c9b9..a66b7f3fb 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -23,11 +23,8 @@ import type { QueryParameterDefinition, } from "@osdk/api"; import type { - Attachment, - DataValueWireToClient, OsdkBase, OsdkObjectPrimaryKeyType, - QueryObjectResponse, QueryParameterType, QueryReturnType, } from "@osdk/client.api"; @@ -95,7 +92,8 @@ async function remapQueryParams( async function remapQueryResponse< K extends string, - T extends QueryDataTypeDefinition, + Q extends ObjectTypeDefinition, + T extends QueryDataTypeDefinition, >( client: MinimalClient, responseDataType: T, @@ -151,7 +149,8 @@ async function remapQueryResponse< >; } case "object": { - const def = definitions.get(responseDataType.object); + const def = responseDataType.__OsdkTargetType + ?? definitions.get(responseDataType.object); if (!def) { throw new Error( `Missing definition for ${responseDataType.object}`, @@ -166,7 +165,8 @@ async function remapQueryResponse< } case "objectSet": { - const def = definitions.get(responseDataType.objectSet); + const def = responseDataType.__OsdkTargetType + ?? definitions.get(responseDataType.objectSet); if (!def) { throw new Error( `Missing definition for ${responseDataType.objectSet}`, @@ -311,7 +311,6 @@ function requiresConversion(dataType: QueryDataTypeDefinition) { return true; default: - const _: never = dataType; return false; } } diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index 75f247543..1bf702200 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -66,29 +66,19 @@ export async function generatePerQueryDataFiles( return ` ${name}: ${ parameter.dataType.type === "object" + || parameter.dataType.type === "objectSet" ? `{ - type: "object", - object: "${parameter.dataType.objectTypeApiName}", - nullable: false, - __OsdkTargetType: ${ - getObjectDefIdentifier( - parameter.dataType.objectTypeApiName, - true, - ) - }, - }` - : parameter.dataType.type === "objectSet" - ? `{ - type: "objectSet", - objectSet: "${parameter.dataType.objectTypeApiName}", + description: "${parameter.description}", + type: "${parameter.dataType.type}", + "${parameter.dataType.type}": "${parameter.dataType + .objectTypeApiName!}", nullable: false, __OsdkTargetType: ${ getObjectDefIdentifier( parameter.dataType.objectTypeApiName!, - true, + v2, ) - }, - }` + },}` : JSON.stringify( wireQueryParameterV2ToQueryParameterDefinition(parameter), ) @@ -97,27 +87,15 @@ export async function generatePerQueryDataFiles( }) }}, output: ${ - query.output.type === "object" - ? `{ - type: "object", - object: "${query.output.objectTypeApiName}", - nullable: false, - __OsdkTargetType: ${ - getObjectDefIdentifier( - query.output.objectTypeApiName, - true, - ) - }, - }` - : query.output.type === "objectSet" + query.output.type === "object" || query.output.type === "objectSet" ? `{ - type: "objectSet", - objectSet: "${query.output.objectTypeApiName}", + type: "${query.output.type}", + "${query.output.type}": "${query.output.objectTypeApiName}", nullable: false, __OsdkTargetType: ${ getObjectDefIdentifier( query.output.objectTypeApiName!, - true, + v2, ) }, }` From 5029221c03b78e1d2f782979d371a10929115fda Mon Sep 17 00:00:00 2001 From: Saurav Date: Thu, 27 Jun 2024 09:17:24 -0400 Subject: [PATCH 14/21] fix empty index files --- .../src/generatedNoCheck/ontology/queries/index.ts | 1 + .../todoapp/src/generatedNoCheck2/ontology/queries/index.ts | 1 + packages/generator/src/v1.1/generatePerQueryDataFiles.ts | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts b/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts index e69de29bb..cb0ff5c3b 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/ontology/queries/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts b/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts index e69de29bb..cb0ff5c3b 100644 --- a/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts +++ b/examples-extra/todoapp/src/generatedNoCheck2/ontology/queries/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index 1bf702200..5f820bc3a 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -78,7 +78,8 @@ export async function generatePerQueryDataFiles( parameter.dataType.objectTypeApiName!, v2, ) - },}` + }, + }` : JSON.stringify( wireQueryParameterV2ToQueryParameterDefinition(parameter), ) @@ -137,6 +138,7 @@ export async function generatePerQueryDataFiles( ) .join("\n") } + ${Object.keys(ontology.queryTypes).length === 0 ? "export {};" : ""} `), ); } From 0017f2bb1ccac292530ccdfd4c2c45d354e20f79 Mon Sep 17 00:00:00 2001 From: Saurav Date: Mon, 8 Jul 2024 09:28:47 -0400 Subject: [PATCH 15/21] start addressing PR comments --- .../src/generatedNoCheck/Ontology.ts | 2 +- .../src/generatedNoCheck/ontology/objects.ts | 2 +- .../todoapp/src/generatedNoCheck2/Ontology.ts | 2 +- packages/client/src/queries/applyQuery.ts | 6 ++--- .../client/src/util/isOntologyObjectV2.ts | 6 ----- packages/client/src/util/isOsdkBaseObject.ts | 22 +++++++++++++++++++ .../client/src/util/toDataValueQueries.ts | 2 +- .../tsup.config.bundled_xnzkd6wirio.mjs | 11 ---------- .../tsup.config.bundled_utoam7othn.mjs | 11 ---------- 9 files changed, 29 insertions(+), 35 deletions(-) create mode 100644 packages/client/src/util/isOsdkBaseObject.ts delete mode 100644 packages/client/tsup.config.bundled_xnzkd6wirio.mjs delete mode 100644 packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs diff --git a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts index 04d660fd0..084fec1bd 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts @@ -1,7 +1,7 @@ import type { OntologyDefinition } from '@osdk/api'; -import { OntologyMetadata } from './OntologyMetadata'; import * as Actions from './ontology/actions/index'; import * as Objects from './ontology/objects'; +import { OntologyMetadata } from './OntologyMetadata'; export interface Ontology extends OntologyDefinition<'Employee' | 'equipment' | 'Office' | 'Todo'> { metadata: OntologyMetadata; diff --git a/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts b/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts index 8a6d04e13..c4fae64d1 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts @@ -1,4 +1,4 @@ export * from './objects/Employee'; +export * from './objects/equipment'; export * from './objects/Office'; export * from './objects/Todo'; -export * from './objects/equipment'; diff --git a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts index e9dd49ecd..32afa1451 100644 --- a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts +++ b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts @@ -1,7 +1,7 @@ import type { OntologyDefinition } from '@osdk/api'; -import { OntologyMetadata } from './OntologyMetadata'; import * as Actions from './ontology/actions/index'; import * as Objects from './ontology/objects'; +import { OntologyMetadata } from './OntologyMetadata'; export interface Ontology extends OntologyDefinition<'Todo'> { metadata: OntologyMetadata; diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index a66b7f3fb..ddd453bd9 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -115,7 +115,7 @@ async function remapQueryResponse< ) { const withoutMultiplicity = { ...responseDataType, multiplicity: false }; for (let i = 0; i < responseValue.length; i++) { - responseValue[i] = remapQueryResponse( + responseValue[i] = await remapQueryResponse( responseValue[i], withoutMultiplicity, client, @@ -132,7 +132,7 @@ async function remapQueryResponse< case "set": { for (let i = 0; i < responseValue.length; i++) { - responseValue[i] = remapQueryResponse( + responseValue[i] = await remapQueryResponse( responseValue[i], responseDataType.set, client, @@ -194,7 +194,7 @@ async function remapQueryResponse< // figure out what keys need to be fixed up for (const [key, subtype] of Object.entries(responseDataType.struct)) { if (requiresConversion(subtype)) { - responseValue[key] = remapQueryResponse( + responseValue[key] = await remapQueryResponse( responseValue[key], subtype, client, diff --git a/packages/client/src/util/isOntologyObjectV2.ts b/packages/client/src/util/isOntologyObjectV2.ts index 01fef155f..e9e879c80 100644 --- a/packages/client/src/util/isOntologyObjectV2.ts +++ b/packages/client/src/util/isOntologyObjectV2.ts @@ -14,15 +14,9 @@ * limitations under the License. */ -import type { OsdkBase } from "@osdk/client.api"; import type { OntologyObjectV2 } from "@osdk/internal.foundry"; export function isOntologyObjectV2(o: any): o is OntologyObjectV2 { return o && typeof o === "object" && typeof o.__apiName === "string" && o.__primaryKey != null; } - -export function isOsdkBaseObject(o: any): o is OsdkBase { - return o && typeof o === "object" && typeof o.$apiName === "string" - && o.$primaryKey != null; -} diff --git a/packages/client/src/util/isOsdkBaseObject.ts b/packages/client/src/util/isOsdkBaseObject.ts new file mode 100644 index 000000000..8112c42c4 --- /dev/null +++ b/packages/client/src/util/isOsdkBaseObject.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { OsdkBase } from "@osdk/client.api"; + +export function isOsdkBaseObject(o: any): o is OsdkBase { + return o && typeof o === "object" && typeof o.$apiName === "string" + && o.$primaryKey != null; +} diff --git a/packages/client/src/util/toDataValueQueries.ts b/packages/client/src/util/toDataValueQueries.ts index 7b362dcb4..1f1ad8d5b 100644 --- a/packages/client/src/util/toDataValueQueries.ts +++ b/packages/client/src/util/toDataValueQueries.ts @@ -19,7 +19,7 @@ import { type DataValue, Ontologies } from "@osdk/internal.foundry"; import type { MinimalClient } from "../MinimalClientContext.js"; import { isAttachmentUpload } from "../object/AttachmentUpload.js"; import { getWireObjectSet, isObjectSet } from "../objectSet/createObjectSet.js"; -import { isOsdkBaseObject } from "./isOntologyObjectV2.js"; +import { isOsdkBaseObject } from "./isOsdkBaseObject.js"; import { isWireObjectSet } from "./WireObjectSet.js"; /** diff --git a/packages/client/tsup.config.bundled_xnzkd6wirio.mjs b/packages/client/tsup.config.bundled_xnzkd6wirio.mjs deleted file mode 100644 index dd03ef8b7..000000000 --- a/packages/client/tsup.config.bundled_xnzkd6wirio.mjs +++ /dev/null @@ -1,11 +0,0 @@ -// tsup.config.js -import { defineConfig } from "tsup"; -var tsup_config_default = defineConfig( - async (options) => (await import("mytsup")).default(options, { - esmOnly: true - }) -); -export { - tsup_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHN1cC5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL1ZvbHVtZXMvZ2l0L29zZGstdHMvcGFja2FnZXMvY2xpZW50L3RzdXAuY29uZmlnLmpzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9Wb2x1bWVzL2dpdC9vc2RrLXRzL3BhY2thZ2VzL2NsaWVudFwiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vVm9sdW1lcy9naXQvb3Nkay10cy9wYWNrYWdlcy9jbGllbnQvdHN1cC5jb25maWcuanNcIjsvKlxuICogQ29weXJpZ2h0IDIwMjMgUGFsYW50aXIgVGVjaG5vbG9naWVzLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ0c3VwXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhhc3luYyAob3B0aW9ucykgPT5cbiAgKGF3YWl0IGltcG9ydChcIm15dHN1cFwiKSkuZGVmYXVsdChvcHRpb25zLCB7XG4gICAgZXNtT25seTogdHJ1ZSxcbiAgfSlcbik7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBZ0JBLFNBQVMsb0JBQW9CO0FBRTdCLElBQU8sc0JBQVE7QUFBQSxFQUFhLE9BQU8sYUFDaEMsTUFBTSxPQUFPLFFBQVEsR0FBRyxRQUFRLFNBQVM7QUFBQSxJQUN4QyxTQUFTO0FBQUEsRUFDWCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs b/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs deleted file mode 100644 index 6ec6a3b24..000000000 --- a/packages/foundry-sdk-generator/tsup.config.bundled_utoam7othn.mjs +++ /dev/null @@ -1,11 +0,0 @@ -// tsup.config.js -import { defineConfig } from "tsup"; -var tsup_config_default = defineConfig( - async (options) => (await import("mytsup")).default(options, { - esmOnly: true - }) -); -export { - tsup_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHN1cC5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL1ZvbHVtZXMvZ2l0L29zZGstdHMvcGFja2FnZXMvZm91bmRyeS1zZGstZ2VuZXJhdG9yL3RzdXAuY29uZmlnLmpzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9Wb2x1bWVzL2dpdC9vc2RrLXRzL3BhY2thZ2VzL2ZvdW5kcnktc2RrLWdlbmVyYXRvclwiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vVm9sdW1lcy9naXQvb3Nkay10cy9wYWNrYWdlcy9mb3VuZHJ5LXNkay1nZW5lcmF0b3IvdHN1cC5jb25maWcuanNcIjsvKlxuICogQ29weXJpZ2h0IDIwMjMgUGFsYW50aXIgVGVjaG5vbG9naWVzLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ0c3VwXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyhhc3luYyAob3B0aW9ucykgPT5cbiAgKGF3YWl0IGltcG9ydChcIm15dHN1cFwiKSkuZGVmYXVsdChvcHRpb25zLCB7XG4gICAgZXNtT25seTogdHJ1ZSxcbiAgfSlcbik7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBZ0JBLFNBQVMsb0JBQW9CO0FBRTdCLElBQU8sc0JBQVE7QUFBQSxFQUFhLE9BQU8sYUFDaEMsTUFBTSxPQUFPLFFBQVEsR0FBRyxRQUFRLFNBQVM7QUFBQSxJQUN4QyxTQUFTO0FBQUEsRUFDWCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg== From ba7117e6726c65a7137be9f84ca73735b6b8e081 Mon Sep 17 00:00:00 2001 From: Saurav Date: Tue, 9 Jul 2024 10:16:26 -0400 Subject: [PATCH 16/21] codegen cleanup --- .../ontology/queries/getTodoCount.ts | 2 +- .../queries/queryTakesAllParameterTypes.ts | 94 ++++++++++++------- .../src/generatedNoCheck/Ontology.ts | 2 +- .../src/generatedNoCheck/ontology/objects.ts | 2 +- .../todoapp/src/generatedNoCheck2/Ontology.ts | 2 +- .../wireQueryTypeV2ToSdkQueryDefinition.ts | 4 +- .../src/v1.1/generatePerQueryDataFiles.ts | 71 +++++++------- 7 files changed, 99 insertions(+), 78 deletions(-) diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts index 82df97e10..0660f6be9 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/getTodoCount.ts @@ -5,5 +5,5 @@ export const getTodoCount = { type: 'query', version: '0.1.2', parameters: {}, - output: { type: 'integer', nullable: false }, + output: { nullable: false, type: 'integer' }, } satisfies QueryDefinition<'getTodoCount', never>; diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 8e2f36dd9..99f9d53b2 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -7,67 +7,91 @@ export const queryTakesAllParameterTypes = { type: 'query', version: 'version', parameters: { - double: { description: 'a double parameter', type: 'double', nullable: false }, - float: { type: 'float', nullable: false }, - integer: { type: 'integer', nullable: false }, - long: { type: 'long', nullable: false }, - attachment: { type: 'attachment', nullable: false }, - boolean: { type: 'boolean', nullable: false }, - date: { type: 'date', nullable: false }, - string: { type: 'string', nullable: false }, - timestamp: { type: 'timestamp', nullable: false }, - object: { - description: 'undefined', - type: 'object', - object: 'Todo', + double: { description: 'a double parameter', nullable: false, type: 'double' }, + float: { nullable: false, type: 'float' }, + integer: { nullable: false, type: 'integer' }, + long: { nullable: false, type: 'long' }, + attachment: { nullable: false, type: 'attachment' }, + boolean: { nullable: false, type: 'boolean' }, + date: { nullable: false, type: 'date' }, + string: { nullable: false, type: 'string' }, + timestamp: { nullable: false, type: 'timestamp' }, + object: { nullable: false, object: 'Todo', type: 'object', __OsdkTargetType: Todo }, + objectSet: { nullable: false, objectSet: 'Todo', type: 'objectSet', __OsdkTargetType: Todo }, + array: { description: 'an array of strings', multiplicity: true, nullable: false, type: 'string' }, + set: { + description: 'a set of strings', nullable: false, - __OsdkTargetType: Todo, - }, - objectSet: { - description: 'undefined', - type: 'objectSet', - objectSet: 'Todo', - nullable: false, - __OsdkTargetType: Todo, + set: { + type: 'string', + nullable: false, + }, + type: 'set', }, - array: { description: 'an array of strings', type: 'string', nullable: false, multiplicity: true }, - set: { description: 'a set of strings', type: 'set', set: { type: 'string', nullable: false }, nullable: false }, unionNonNullable: { description: 'a union of strings and integers', + nullable: false, type: 'union', union: [ - { type: 'string', nullable: false }, - { type: 'integer', nullable: false }, + { + type: 'string', + nullable: false, + }, + { + type: 'integer', + nullable: false, + }, ], - nullable: false, }, unionNullable: { description: 'a union of strings and integers but its optional', + nullable: true, type: 'union', union: [ - { type: 'string', nullable: false }, - { type: 'integer', nullable: false }, + { + type: 'string', + nullable: false, + }, + { + type: 'integer', + nullable: false, + }, ], - nullable: true, }, struct: { description: 'a struct with some fields', - type: 'struct', - struct: { name: { type: 'string', nullable: false }, id: { type: 'integer', nullable: false } }, nullable: false, + struct: { + name: { + type: 'string', + nullable: false, + }, + id: { + type: 'integer', + nullable: false, + }, + }, + type: 'struct', }, twoDimensionalAggregation: { + twoDimensionalAggregation: { + keyType: 'string', + valueType: 'double', + }, type: 'twoDimensionalAggregation', - twoDimensionalAggregation: { keyType: 'string', valueType: 'double' }, }, threeDimensionalAggregation: { - type: 'threeDimensionalAggregation', threeDimensionalAggregation: { keyType: 'range', keySubtype: 'date', - valueType: { keyType: 'range', keySubtype: 'timestamp', valueType: 'date' }, + valueType: { + keyType: 'range', + keySubtype: 'timestamp', + valueType: 'date', + }, }, + type: 'threeDimensionalAggregation', }, }, - output: { type: 'string', nullable: false }, + output: { nullable: false, type: 'string' }, } satisfies QueryDefinition<'queryTakesAllParameterTypes', 'Todo'>; diff --git a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts index 084fec1bd..04d660fd0 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/Ontology.ts @@ -1,7 +1,7 @@ import type { OntologyDefinition } from '@osdk/api'; +import { OntologyMetadata } from './OntologyMetadata'; import * as Actions from './ontology/actions/index'; import * as Objects from './ontology/objects'; -import { OntologyMetadata } from './OntologyMetadata'; export interface Ontology extends OntologyDefinition<'Employee' | 'equipment' | 'Office' | 'Todo'> { metadata: OntologyMetadata; diff --git a/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts b/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts index c4fae64d1..8a6d04e13 100644 --- a/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts +++ b/examples-extra/docs_example/src/generatedNoCheck/ontology/objects.ts @@ -1,4 +1,4 @@ export * from './objects/Employee'; -export * from './objects/equipment'; export * from './objects/Office'; export * from './objects/Todo'; +export * from './objects/equipment'; diff --git a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts index 32afa1451..e9dd49ecd 100644 --- a/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts +++ b/examples-extra/todoapp/src/generatedNoCheck2/Ontology.ts @@ -1,7 +1,7 @@ import type { OntologyDefinition } from '@osdk/api'; +import { OntologyMetadata } from './OntologyMetadata'; import * as Actions from './ontology/actions/index'; import * as Objects from './ontology/objects'; -import { OntologyMetadata } from './OntologyMetadata'; export interface Ontology extends OntologyDefinition<'Todo'> { metadata: OntologyMetadata; diff --git a/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts b/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts index de74008f6..468e1ade1 100644 --- a/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts +++ b/packages/generator/src/shared/wireQueryTypeV2ToSdkQueryDefinition.ts @@ -16,7 +16,9 @@ import type { QueryDefinition, QueryParameterDefinition } from "@osdk/api"; import type { QueryParameterV2, QueryTypeV2 } from "@osdk/gateway/types"; -import { wireQueryDataTypeToQueryDataTypeDefinition } from "./wireQueryDataTypeToQueryDataTypeDefinition.js"; +import { + wireQueryDataTypeToQueryDataTypeDefinition, +} from "./wireQueryDataTypeToQueryDataTypeDefinition.js"; export function wireQueryTypeV2ToSdkQueryDefinition( input: QueryTypeV2, diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index 5f820bc3a..68225a322 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -63,53 +63,44 @@ export async function generatePerQueryDataFiles( Object.entries(query.parameters).map(( [name, parameter], ) => { - return ` - ${name}: ${ + return `${name} : {${ + stringify(deleteUndefineds( + wireQueryParameterV2ToQueryParameterDefinition(parameter), + )) + }, + ${ parameter.dataType.type === "object" || parameter.dataType.type === "objectSet" - ? `{ - description: "${parameter.description}", - type: "${parameter.dataType.type}", - "${parameter.dataType.type}": "${parameter.dataType - .objectTypeApiName!}", - nullable: false, - __OsdkTargetType: ${ + ? `__OsdkTargetType: ${ getObjectDefIdentifier( parameter.dataType.objectTypeApiName!, v2, ) - }, - }` - : JSON.stringify( - wireQueryParameterV2ToQueryParameterDefinition(parameter), - ) - } - `; + }` + : `` + }}`; }) }}, - output: ${ + output: {${ + stringify( + deleteUndefineds( + wireQueryDataTypeToQueryDataTypeDefinition(query.output), + ), + ) + }, + ${ query.output.type === "object" || query.output.type === "objectSet" - ? `{ - type: "${query.output.type}", - "${query.output.type}": "${query.output.objectTypeApiName}", - nullable: false, + ? ` __OsdkTargetType: ${ getObjectDefIdentifier( query.output.objectTypeApiName!, v2, ) - }, - }` - : JSON.stringify( - wireQueryDataTypeToQueryDataTypeDefinition(query.output), - ) - }, - - } satisfies QueryDefinition<"${query.apiName}", ${ - objectTypes.length > 0 - ? objectTypes.map(apiName => `"${apiName}"`).join("|") - : "never" - }>;`), + } + ` + : `` + }} + } ${getQueryDefSatisfies(query.apiName, objectTypes)}`), ); } else { await fs.writeFile( @@ -119,11 +110,7 @@ export async function generatePerQueryDataFiles( export const ${query.apiName} = ${ JSON.stringify(wireQueryTypeV2ToSdkQueryDefinition(query)) - } satisfies QueryDefinition<"${query.apiName}", ${ - objectTypes.length > 0 - ? objectTypes.map(apiName => `"${apiName}"`).join("|") - : "never" - }>;`), + } ${getQueryDefSatisfies(query.apiName, objectTypes)}`), ); } }), @@ -209,3 +196,11 @@ function getObjectTypesFromDataType( ); } } + +function getQueryDefSatisfies(apiName: string, objectTypes: string[]): string { + return `satisfies QueryDefinition<"${apiName}", ${ + objectTypes.length > 0 + ? objectTypes.map(apiNameObj => `"${apiNameObj}"`).join("|") + : "never" + }>;`; +} From 73c298834349ced9dfce29e14a74c129e9714ad5 Mon Sep 17 00:00:00 2001 From: Saurav Date: Wed, 10 Jul 2024 08:07:14 -0400 Subject: [PATCH 17/21] only use provider for object defs --- packages/client/src/queries/applyQuery.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index ddd453bd9..9a9671f36 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -149,8 +149,7 @@ async function remapQueryResponse< >; } case "object": { - const def = responseDataType.__OsdkTargetType - ?? definitions.get(responseDataType.object); + const def = definitions.get(responseDataType.object); if (!def) { throw new Error( `Missing definition for ${responseDataType.object}`, @@ -165,8 +164,7 @@ async function remapQueryResponse< } case "objectSet": { - const def = responseDataType.__OsdkTargetType - ?? definitions.get(responseDataType.objectSet); + const def = definitions.get(responseDataType.objectSet); if (!def) { throw new Error( `Missing definition for ${responseDataType.objectSet}`, From e64f0a27944948475df2686453e79cc2777cebaf Mon Sep 17 00:00:00 2001 From: Saurav Date: Wed, 10 Jul 2024 08:30:50 -0400 Subject: [PATCH 18/21] clean up bucket types --- packages/client.api/src/index.ts | 2 ++ .../src/mapping/DataValueMapping.ts | 26 +++++++++---------- packages/client/src/queries/applyQuery.ts | 12 +++++++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/packages/client.api/src/index.ts b/packages/client.api/src/index.ts index 5e5883d76..fa4b6e45d 100644 --- a/packages/client.api/src/index.ts +++ b/packages/client.api/src/index.ts @@ -65,6 +65,8 @@ export type { GroupByRange, } from "./groupby/GroupByClause.js"; export type { + AllowedBucketKeyTypes, + AllowedBucketTypes, DataValueClientToWire, DataValueWireToClient, } from "./mapping/DataValueMapping.js"; diff --git a/packages/client.api/src/mapping/DataValueMapping.ts b/packages/client.api/src/mapping/DataValueMapping.ts index f900d4238..42f47bb63 100644 --- a/packages/client.api/src/mapping/DataValueMapping.ts +++ b/packages/client.api/src/mapping/DataValueMapping.ts @@ -35,12 +35,12 @@ export interface DataValueWireToClient { string: string; timestamp: string; twoDimensionalAggregation: { - key: allowedBucketKeyTypes; - value: allowedBucketTypes; + key: AllowedBucketKeyTypes; + value: AllowedBucketTypes; }[]; threeDimensionalAggregation: { - key: allowedBucketKeyTypes; - groups: { key: allowedBucketKeyTypes; value: allowedBucketTypes }[]; + key: AllowedBucketKeyTypes; + groups: { key: AllowedBucketKeyTypes; value: AllowedBucketTypes }[]; }[]; struct: Record; set: Set; @@ -66,20 +66,20 @@ export interface DataValueClientToWire { timestamp: string; set: Set; twoDimensionalAggregation: { - key: allowedBucketKeyTypes; - value: allowedBucketTypes; + key: AllowedBucketKeyTypes; + value: AllowedBucketTypes; }[]; threeDimensionalAggregation: { - key: allowedBucketKeyTypes; - groups: { key: allowedBucketKeyTypes; value: allowedBucketTypes }[]; + key: AllowedBucketKeyTypes; + groups: { key: AllowedBucketKeyTypes; value: AllowedBucketTypes }[]; }[]; struct: Record; } -type allowedBucketTypes = string | number | boolean; -type allowedBucketKeyTypes = - | allowedBucketTypes +export type AllowedBucketTypes = string | number | boolean; +export type AllowedBucketKeyTypes = + | AllowedBucketTypes | { - startValue: allowedBucketTypes; - endValue: allowedBucketTypes; + startValue: AllowedBucketTypes; + endValue: AllowedBucketTypes; }; diff --git a/packages/client/src/queries/applyQuery.ts b/packages/client/src/queries/applyQuery.ts index 9a9671f36..7900689fd 100644 --- a/packages/client/src/queries/applyQuery.ts +++ b/packages/client/src/queries/applyQuery.ts @@ -23,6 +23,8 @@ import type { QueryParameterDefinition, } from "@osdk/api"; import type { + AllowedBucketKeyTypes, + AllowedBucketTypes, OsdkBase, OsdkObjectPrimaryKeyType, QueryParameterType, @@ -204,7 +206,10 @@ async function remapQueryResponse< return responseValue as QueryReturnType; } case "twoDimensionalAggregation": { - const result: { key: any; value: any }[] = []; + const result: { + key: AllowedBucketKeyTypes; + value: AllowedBucketTypes; + }[] = []; for (const { key, value } of responseValue.groups) { result.push({ key, value }); } @@ -212,7 +217,10 @@ async function remapQueryResponse< } case "threeDimensionalAggregation": { - const result: { key: any; groups: { key: any; value: any }[] }[] = []; + const result: { + key: AllowedBucketKeyTypes; + groups: { key: AllowedBucketKeyTypes; value: AllowedBucketTypes }[]; + }[] = []; for (const { key, groups } of responseValue.groups) { const subresult: { key: any; value: any }[] = []; for (const { key: subkey, value } of groups) { From 5204063b3d9d01f5cb0087495cc99587a9d05d3f Mon Sep 17 00:00:00 2001 From: Saurav Date: Wed, 10 Jul 2024 08:42:55 -0400 Subject: [PATCH 19/21] a little more codegen cleanup --- .../queries/queryTakesAllParameterTypes.ts | 16 +++++++-- .../src/v1.1/generatePerQueryDataFiles.ts | 33 +++++++++++-------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 99f9d53b2..236e3fdf4 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -16,8 +16,20 @@ export const queryTakesAllParameterTypes = { date: { nullable: false, type: 'date' }, string: { nullable: false, type: 'string' }, timestamp: { nullable: false, type: 'timestamp' }, - object: { nullable: false, object: 'Todo', type: 'object', __OsdkTargetType: Todo }, - objectSet: { nullable: false, objectSet: 'Todo', type: 'objectSet', __OsdkTargetType: Todo }, + object: { + nullable: false, + object: 'Todo', + type: 'object', + + __OsdkTargetType: Todo, + }, + objectSet: { + nullable: false, + objectSet: 'Todo', + type: 'objectSet', + + __OsdkTargetType: Todo, + }, array: { description: 'an array of strings', multiplicity: true, nullable: false, type: 'string' }, set: { description: 'a set of strings', diff --git a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts index 68225a322..b94185458 100644 --- a/packages/generator/src/v1.1/generatePerQueryDataFiles.ts +++ b/packages/generator/src/v1.1/generatePerQueryDataFiles.ts @@ -71,12 +71,10 @@ export async function generatePerQueryDataFiles( ${ parameter.dataType.type === "object" || parameter.dataType.type === "objectSet" - ? `__OsdkTargetType: ${ - getObjectDefIdentifier( - parameter.dataType.objectTypeApiName!, - v2, - ) - }` + ? getOsdkTargetTypeIfPresent( + parameter.dataType.objectTypeApiName!, + v2, + ) : `` }}`; }) @@ -90,14 +88,7 @@ export async function generatePerQueryDataFiles( }, ${ query.output.type === "object" || query.output.type === "objectSet" - ? ` - __OsdkTargetType: ${ - getObjectDefIdentifier( - query.output.objectTypeApiName!, - v2, - ) - } - ` + ? getOsdkTargetTypeIfPresent(query.output.objectTypeApiName!, v2) : `` }} } ${getQueryDefSatisfies(query.apiName, objectTypes)}`), @@ -204,3 +195,17 @@ function getQueryDefSatisfies(apiName: string, objectTypes: string[]): string { : "never" }>;`; } + +function getOsdkTargetTypeIfPresent( + objectTypeApiName: string, + v2: boolean, +): string { + return ` + __OsdkTargetType: ${ + getObjectDefIdentifier( + objectTypeApiName, + v2, + ) + } + `; +} From b5ccec34cb4250d38afd68610278da3a687a9101 Mon Sep 17 00:00:00 2001 From: Saurav Date: Sun, 14 Jul 2024 13:54:04 -0400 Subject: [PATCH 20/21] nullable checks --- .../ontology/queries/queryTakesAllParameterTypes.ts | 2 ++ .../ontology/queries/queryTakesAllParameterTypes.ts | 2 ++ packages/client/src/queries/queries.test.ts | 11 +++++++++++ .../wireQueryDataTypeToQueryDataTypeDefinition.ts | 2 ++ packages/shared.test/src/stubs/queries.ts | 7 +++++++ 5 files changed, 24 insertions(+) diff --git a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 236e3fdf4..b9f5e158f 100644 --- a/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/basic/sdk/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -86,6 +86,7 @@ export const queryTakesAllParameterTypes = { type: 'struct', }, twoDimensionalAggregation: { + nullable: false, twoDimensionalAggregation: { keyType: 'string', valueType: 'double', @@ -93,6 +94,7 @@ export const queryTakesAllParameterTypes = { type: 'twoDimensionalAggregation', }, threeDimensionalAggregation: { + nullable: false, threeDimensionalAggregation: { keyType: 'range', keySubtype: 'date', diff --git a/examples-extra/one_dot_one/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts b/examples-extra/one_dot_one/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts index 41487210e..ce3d1c03b 100644 --- a/examples-extra/one_dot_one/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts +++ b/examples-extra/one_dot_one/src/generatedNoCheck/ontology/queries/queryTakesAllParameterTypes.ts @@ -47,6 +47,7 @@ export const queryTakesAllParameterTypes = { twoDimensionalAggregation: { type: 'twoDimensionalAggregation', twoDimensionalAggregation: { keyType: 'string', valueType: 'double' }, + nullable: false, }, threeDimensionalAggregation: { type: 'threeDimensionalAggregation', @@ -55,6 +56,7 @@ export const queryTakesAllParameterTypes = { keySubtype: 'date', valueType: { keyType: 'range', keySubtype: 'timestamp', valueType: 'date' }, }, + nullable: false, }, }, output: { type: 'string', nullable: false }, diff --git a/packages/client/src/queries/queries.test.ts b/packages/client/src/queries/queries.test.ts index fa5632136..97ba1afb7 100644 --- a/packages/client/src/queries/queries.test.ts +++ b/packages/client/src/queries/queries.test.ts @@ -151,6 +151,17 @@ describe("queries", () => { }, { key: "Q-AFO", groups: [] }]); }); + it("throws when response is null and response is non-nullable", async () => { + try { + const result = await client(addOne)({ n: 3 }); + expect.fail("Should not reach here"); + } catch (e) { + expect((e as Error).message).toMatch( + `Got null response when nullable was not allowed`, + ); + } + }); + it("three dimensional aggs request/response works", async () => { const result = await client(acceptsThreeDimensionalAggregationFunction)({ aggFunction: [ diff --git a/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts b/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts index e9c8b31b8..e5455434e 100644 --- a/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts +++ b/packages/generator/src/shared/wireQueryDataTypeToQueryDataTypeDefinition.ts @@ -117,12 +117,14 @@ export function wireQueryDataTypeToQueryDataTypeDefinition< return { type: "twoDimensionalAggregation", twoDimensionalAggregation: get2DQueryAggregationProps(input), + nullable: false, }; case "threeDimensionalAggregation": return { type: "threeDimensionalAggregation", threeDimensionalAggregation: get3DQueryAggregationProps(input), + nullable: false, }; case "null": diff --git a/packages/shared.test/src/stubs/queries.ts b/packages/shared.test/src/stubs/queries.ts index a966c6c77..e0be42930 100644 --- a/packages/shared.test/src/stubs/queries.ts +++ b/packages/shared.test/src/stubs/queries.ts @@ -39,6 +39,12 @@ export const addOneQueryRequest: ExecuteQueryRequest = { }, }; +export const addOneQueryRequestWithNoResponse: ExecuteQueryRequest = { + parameters: { + n: 3, + }, +}; + export const addOneQueryResponse: ExecuteQueryResponse = { value: 3, }; @@ -228,6 +234,7 @@ export const queryRequestHandlers: { } = { [addOneQueryType.apiName]: { [JSON.stringify(addOneQueryRequest)]: addOneQueryResponse, + [JSON.stringify(addOneQueryRequestWithNoResponse)]: { value: undefined }, }, [queryTypeReturnsStruct.apiName]: { [JSON.stringify(queryTypeReturnsStructRequest)]: From 7acba23b76d5a53e5702cd4248e67f0b449e7059 Mon Sep 17 00:00:00 2001 From: Saurav Date: Mon, 15 Jul 2024 10:52:49 -0400 Subject: [PATCH 21/21] add changeset --- .changeset/plenty-berries-add.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/plenty-berries-add.md diff --git a/.changeset/plenty-berries-add.md b/.changeset/plenty-berries-add.md new file mode 100644 index 000000000..4031912bc --- /dev/null +++ b/.changeset/plenty-berries-add.md @@ -0,0 +1,10 @@ +--- +"@osdk/legacy-client": minor +"@osdk/shared.test": minor +"@osdk/client.api": minor +"@osdk/generator": minor +"@osdk/client": minor +"@osdk/api": minor +--- + +Add support for queries in 2.0