diff --git a/.changeset/silent-carpets-kick.md b/.changeset/silent-carpets-kick.md new file mode 100644 index 000000000..d9bef10d7 --- /dev/null +++ b/.changeset/silent-carpets-kick.md @@ -0,0 +1,8 @@ +--- +"@osdk/e2e.generated.1.1.x": minor +"@osdk/legacy-client": minor +"@osdk/shared.test": minor +"@osdk/generator": minor +--- + +Fix long aggregations in legacy-client diff --git a/packages/e2e.generated.1.1.x/src/generatedNoCheck/ontology/objects/ObjectTypeWithAllPropertyTypes.ts b/packages/e2e.generated.1.1.x/src/generatedNoCheck/ontology/objects/ObjectTypeWithAllPropertyTypes.ts index cc11f4bed..3e02f3334 100644 --- a/packages/e2e.generated.1.1.x/src/generatedNoCheck/ontology/objects/ObjectTypeWithAllPropertyTypes.ts +++ b/packages/e2e.generated.1.1.x/src/generatedNoCheck/ontology/objects/ObjectTypeWithAllPropertyTypes.ts @@ -5,6 +5,7 @@ import type { GeoShape, LocalDate, OntologyObject, + StringLong, TimeSeries, Timestamp, } from '@osdk/legacy-client'; @@ -42,8 +43,8 @@ export interface ObjectTypeWithAllPropertyTypes extends OntologyObject { readonly id: number | undefined; readonly integer: number | undefined; readonly integerArray: number[] | undefined; - readonly long: string | undefined; - readonly longArray: string[] | undefined; + readonly long: StringLong | undefined; + readonly longArray: StringLong[] | undefined; readonly numericTimeseries: TimeSeries | undefined; readonly short: number | undefined; readonly shortArray: number[] | undefined; diff --git a/packages/generator/src/v1.1/wireObjectTypeV2ToV1ObjectInterfaceString.ts b/packages/generator/src/v1.1/wireObjectTypeV2ToV1ObjectInterfaceString.ts index 0ea2c6215..b2e070055 100644 --- a/packages/generator/src/v1.1/wireObjectTypeV2ToV1ObjectInterfaceString.ts +++ b/packages/generator/src/v1.1/wireObjectTypeV2ToV1ObjectInterfaceString.ts @@ -29,7 +29,7 @@ export function wireObjectTypeV2ToObjectInterfaceStringV1( a !== objectTypeWithLinks.objectType.apiName ), ); - return `import type { OntologyObject, LocalDate, Timestamp, GeoShape, GeoPoint, Attachment, TimeSeries, MultiLink, SingleLink } from "@osdk/legacy-client"; + return `import type { OntologyObject, LocalDate, Timestamp, GeoShape, GeoPoint, Attachment, TimeSeries, MultiLink, SingleLink, StringLong } from "@osdk/legacy-client"; ${ Array.from(uniqueLinkTargets).map(linkTarget => `import type { ${linkTarget} } from "./${linkTarget}${importExt}";` @@ -128,7 +128,7 @@ function wirePropertyTypeV2ToTypeScriptType( case "geoshape": return "GeoShape"; case "long": - return "string"; + return "StringLong"; case "short": return "number"; case "timestamp": diff --git a/packages/legacy-client/src/client/OsdkLegacyObject.ts b/packages/legacy-client/src/client/OsdkLegacyObject.ts index f7f842b09..0575d3b26 100644 --- a/packages/legacy-client/src/client/OsdkLegacyObject.ts +++ b/packages/legacy-client/src/client/OsdkLegacyObject.ts @@ -36,6 +36,7 @@ import type { Timestamp, } from "./baseTypes/index.js"; import type { reservedKeywordsList } from "./utils/reservedKeywords.js"; +import type { StringLong } from "./utils/StringLong.js"; export interface ValidLegacyPropertyTypes { string: string; @@ -45,7 +46,7 @@ export interface ValidLegacyPropertyTypes { integer: number; timestamp: Timestamp; short: number; - long: string; + long: StringLong; float: number; decimal: string; byte: number; diff --git a/packages/legacy-client/src/client/interfaces/aggregations.test.ts b/packages/legacy-client/src/client/interfaces/aggregations.test.ts index 41270344d..772abd7ce 100644 --- a/packages/legacy-client/src/client/interfaces/aggregations.test.ts +++ b/packages/legacy-client/src/client/interfaces/aggregations.test.ts @@ -42,6 +42,7 @@ describe("Aggregations", () => { class: StringGroupBy<"class">; class_: StringGroupBy<"class_">; tags: StringGroupBy<"tags">; + unixTimestamp: NumericGroupBy<"unixTimestamp">; }>().toMatchTypeOf>(); expectTypeOf<{ @@ -51,6 +52,7 @@ describe("Aggregations", () => { points: AggregatableProperty; class: AggregatableProperty; class_: AggregatableProperty; + unixTimestamp: AggregatableProperty; }>().toMatchTypeOf>(); expectTypeOf<{ @@ -61,6 +63,7 @@ describe("Aggregations", () => { class: ApproximateDistinctCountAggregatableProperty; class_: ApproximateDistinctCountAggregatableProperty; count: () => CountOperation; + unixTimestamp: MultipleAggregatableProperty; }>().toMatchTypeOf>(); }); }); diff --git a/packages/legacy-client/src/client/interfaces/aggregations.ts b/packages/legacy-client/src/client/interfaces/aggregations.ts index 32e8d6f64..17722de87 100644 --- a/packages/legacy-client/src/client/interfaces/aggregations.ts +++ b/packages/legacy-client/src/client/interfaces/aggregations.ts @@ -34,6 +34,7 @@ import type { StringGroupBy, TimestampGroupBy, } from "../objectSets/aggregations/index.js"; +import type { StringLong } from "../utils/StringLong.js"; import type { OmitMetadataProperties } from "./utils/OmitProperties.js"; export declare type ObjectTypesGroupByFunction< @@ -111,15 +112,17 @@ export type GroupByFromType = NonNullable extends number : T extends Array ? GroupByFromType : never; -export type AggregationFromType = NonNullable extends number +export type AggregationFromType = NonNullable extends StringLong ? AggregatableProperty + : NonNullable extends number ? AggregatableProperty : NonNullable extends boolean ? AggregatableProperty : NonNullable extends LocalDate ? AggregatableProperty : NonNullable extends Timestamp ? AggregatableProperty : AggregatableProperty; -export type MultipleAggregationFromType = NonNullable extends number +export type MultipleAggregationFromType = NonNullable extends StringLong ? MultipleAggregatableProperty + : NonNullable extends number ? MultipleAggregatableProperty : NonNullable extends boolean ? MultipleAggregatableProperty : NonNullable extends LocalDate ? MultipleAggregatableProperty : NonNullable extends Timestamp ? MultipleAggregatableProperty diff --git a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts index a7a3f232e..a6e923c54 100644 --- a/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts +++ b/packages/legacy-client/src/client/objectSets/OsdkObjectSet.test.ts @@ -174,6 +174,20 @@ describe("OsdkObjectSet", () => { ); }); + it("creates the max aggregation for a long property", async () => { + const os = createBaseObjectSet(client, "Todo"); + mockAggregateResponse({ data: [], accuracy: "ACCURATE" }); + await os.max(s => s.unixTimestamp).compute(); + expect(fetch).toHaveBeenCalledOnce(); + expect(fetch).toHaveBeenCalledWith( + ...expectedJestResponse("Ontology/objectSets/aggregate", { + objectSet: { type: "base", objectType: "Todo" }, + groupBy: [], + aggregation: [{ type: "max", name: "max", field: "unixTimestamp" }], + }), + ); + }); + it("creates the groupBy clauses", async () => { const os = createBaseObjectSet(client, "Todo"); mockAggregateResponse({ data: [], accuracy: "ACCURATE" }); @@ -198,17 +212,20 @@ describe("OsdkObjectSet", () => { await (os.aggregate(b => ({ foo: b.complete.approximateDistinct(), bar: b.body.approximateDistinct(), + baz: b.unixTimestamp.avg(), + qux: b.unixTimestamp.approximateDistinct(), })).compute()); expect(fetch).toHaveBeenCalledOnce(); expect(fetch).toHaveBeenCalledWith( ...expectedJestResponse("Ontology/objectSets/aggregate", { objectSet: { type: "base", objectType: "Todo" }, groupBy: [], - aggregation: [{ - type: "approximateDistinct", - name: "foo", - field: "complete", - }, { type: "approximateDistinct", name: "bar", field: "body" }], + aggregation: [ + { type: "approximateDistinct", name: "foo", field: "complete" }, + { type: "approximateDistinct", name: "bar", field: "body" }, + { type: "avg", name: "baz", field: "unixTimestamp" }, + { type: "approximateDistinct", name: "qux", field: "unixTimestamp" }, + ], }), ); }); diff --git a/packages/legacy-client/src/client/utils/StringLong.ts b/packages/legacy-client/src/client/utils/StringLong.ts new file mode 100644 index 000000000..2d3981c77 --- /dev/null +++ b/packages/legacy-client/src/client/utils/StringLong.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +declare const representsLong: unique symbol; + +/** Represents a long property value converted to a string. We use a + * tagged type to distinguish from a regular string property value. + * This type is not used in `ValidLegacyBaseQueryDataTypes` or + * `ValidLegacyActionParameterTypes` because it is just for result + * long values, not long values that are passed into queries and actions. */ +export type StringLong = string & { [representsLong]: true }; diff --git a/packages/legacy-client/src/client/utils/index.ts b/packages/legacy-client/src/client/utils/index.ts index 062fcd258..29ce61727 100644 --- a/packages/legacy-client/src/client/utils/index.ts +++ b/packages/legacy-client/src/client/utils/index.ts @@ -17,4 +17,5 @@ export type { IsEmptyRecord } from "./IsEmptyRecord.js"; export type { NonNullableKeys, NullableKeys } from "./NullableKeys.js"; export type { reservedKeywordsList } from "./reservedKeywords.js"; +export type { StringLong } from "./StringLong.js"; export type { ValuesOfMap } from "./ValuesOfMap.js"; diff --git a/packages/legacy-client/src/index.ts b/packages/legacy-client/src/index.ts index e06e6223f..8a6519250 100644 --- a/packages/legacy-client/src/index.ts +++ b/packages/legacy-client/src/index.ts @@ -342,6 +342,7 @@ export type { SingleLink, StartsWithWhereClause, StaticObjectSetDefinition, + StringLong, SubtractObjectSetDefinition, ThreeDimensionalAggregation, ThreeDimensionalAggregationType, diff --git a/packages/legacy-client/src/util/test/ObjectTypeWithAllPropertyTypes.ts b/packages/legacy-client/src/util/test/ObjectTypeWithAllPropertyTypes.ts index 8e840f92e..49fb61cb1 100644 --- a/packages/legacy-client/src/util/test/ObjectTypeWithAllPropertyTypes.ts +++ b/packages/legacy-client/src/util/test/ObjectTypeWithAllPropertyTypes.ts @@ -22,6 +22,7 @@ import type { OntologyObject, Timestamp, } from "../../client/baseTypes/index.js"; +import type { StringLong } from "../../client/index.js"; export interface ObjectTypeWithAllPropertyTypes extends OntologyObject { readonly __apiName: "ObjectTypeWithAllPropertyTypes"; @@ -33,7 +34,7 @@ export interface ObjectTypeWithAllPropertyTypes extends OntologyObject { readonly dateTime: Timestamp | undefined; readonly decimal: string | undefined; readonly integer: number | undefined; - readonly long: string | undefined; + readonly long: StringLong | undefined; readonly short: number | undefined; readonly float: number | undefined; readonly double: number | undefined; diff --git a/packages/legacy-client/src/util/test/TodoObject.ts b/packages/legacy-client/src/util/test/TodoObject.ts index 49bd09ca0..285d03c6b 100644 --- a/packages/legacy-client/src/util/test/TodoObject.ts +++ b/packages/legacy-client/src/util/test/TodoObject.ts @@ -18,6 +18,7 @@ import type { OntologyObject, SingleLink, } from "../../client/baseTypes/index.js"; +import type { StringLong } from "../../client/index.js"; import type { Task } from "./TaskObject.js"; /** @@ -42,4 +43,5 @@ export interface Todo extends OntologyObject { readonly points: number | undefined; readonly tags: string[] | undefined; readonly linkedTask: SingleLink; + readonly unixTimestamp: StringLong | undefined; } diff --git a/packages/shared.test/src/mock-ontology/mockOntology.ts b/packages/shared.test/src/mock-ontology/mockOntology.ts index dfebdc89a..a674b0f08 100644 --- a/packages/shared.test/src/mock-ontology/mockOntology.ts +++ b/packages/shared.test/src/mock-ontology/mockOntology.ts @@ -60,6 +60,7 @@ const Todo: TodoDef = { complete: { type: "boolean", nullable: true }, tags: { type: "string", multiplicity: true, nullable: true }, points: { type: "integer", nullable: true }, + unixTimestamp: { type: "long", nullable: true }, }, links: { linkedTask: { @@ -83,6 +84,7 @@ interface TodoDef extends ObjectTypeDefinition<"Todo">, VersionBound<"0.15.0"> { complete: { type: "boolean"; nullable: true }; tags: { type: "string"; multiplicity: true; nullable: true }; points: { type: "integer"; nullable: true }; + unixTimestamp: { type: "long"; nullable: true }; }; links: { linkedTask: ObjectTypeLinkDefinition;