turbine-orm 0.39.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -177,10 +177,21 @@ export type TypedWithClause<R extends object = {}> = [keyof R] extends [never] ?
177
177
  * `{}` (no relation suggestions) for callers that use the unparameterized
178
178
  * {@link WithClause}.
179
179
  */
180
+ /**
181
+ * A single relation-`with` orderBy object: field → direction / sort spec /
182
+ * JSON-path ordering / relation ordering. The Prisma-style array form on
183
+ * {@link WithOptions.orderBy} is `WithOrderByObject[]`.
184
+ */
185
+ export type WithOrderByObject = Record<string, OrderDirection | OrderBySpec | JsonPathOrderBy | RelationOrderBy>;
180
186
  export interface WithOptions<NestedR extends object = {}> {
181
187
  with?: TypedWithClause<NestedR>;
182
188
  where?: Record<string, unknown>;
183
- orderBy?: Record<string, OrderDirection | OrderBySpec | JsonPathOrderBy | RelationOrderBy>;
189
+ /**
190
+ * Order the related rows. Accepts a single object (`{ a: 'asc', b: 'desc' }`)
191
+ * or a Prisma-style array of objects (`[{ a: 'asc' }, { b: 'desc' }]`, whose
192
+ * element order is the authoritative multi-key sort precedence).
193
+ */
194
+ orderBy?: WithOrderByObject | WithOrderByObject[];
184
195
  limit?: number;
185
196
  /** Only include these fields from the relation */
186
197
  select?: Record<string, boolean>;
@@ -740,13 +751,75 @@ export interface GroupByArgs<T> {
740
751
  * (`_count`, or `_sum`/`_avg`/`_min`/`_max` mapping a requested field/alias to
741
752
  * its direction). Every value supports {@link OrderBySpec} for NULLS
742
753
  * placement. See {@link GroupByOrderBy}.
754
+ *
755
+ * Accepts a single object or a Prisma-style array of objects
756
+ * (`[{ region: 'asc' }, { _count: 'desc' }]`, array order authoritative).
757
+ */
758
+ orderBy?: GroupByOrderBy | GroupByOrderBy[];
759
+ /**
760
+ * Cap the number of result groups (`LIMIT`, applied after `ORDER BY`). Useful
761
+ * for "top N groups" queries; pair with `orderBy` for a deterministic set.
762
+ */
763
+ limit?: number;
764
+ /**
765
+ * Skip this many result groups (`OFFSET`, applied after `ORDER BY`). Paginates
766
+ * grouped results; combine with `limit` and a deterministic `orderBy`.
743
767
  */
744
- orderBy?: GroupByOrderBy;
768
+ offset?: number;
745
769
  /** Query timeout in milliseconds. Rejects with an error if exceeded. */
746
770
  timeout?: number;
747
771
  /** Opt out of configured {@link GlobalFilters}. See {@link SkipGlobalFilters}. */
748
772
  skipGlobalFilters?: SkipGlobalFilters;
749
773
  }
774
+ /** The by-key union of a groupBy args type (array element type of `by`). */
775
+ type GroupByKeys<A> = A extends {
776
+ by: infer BY;
777
+ } ? (BY extends readonly unknown[] ? BY[number] : never) : never;
778
+ /** The subset of `by` keys that are plain string field names on the entity `T`. */
779
+ type GroupByFieldKeys<T, A> = Extract<GroupByKeys<A>, keyof T & string>;
780
+ /**
781
+ * `_sum` / `_avg` result block: every requested key maps to `number | null`
782
+ * (an aggregate over zero matching rows is null). Present only when the args
783
+ * actually requested the block. A JSON-path aggregate target keys by its arg
784
+ * key (the alias), so `keyof S` covers both plain columns and JSON aliases.
785
+ */
786
+ type GroupBySumAvgPart<A, Key extends '_sum' | '_avg'> = A extends {
787
+ [P in Key]: infer S;
788
+ } ? [S] extends [object] ? {
789
+ [P in Key]: {
790
+ [K in keyof S & string]: number | null;
791
+ };
792
+ } : unknown : unknown;
793
+ /**
794
+ * `_min` / `_max` result block: a requested key that is a real entity field
795
+ * carries that field's own type; a JSON-path alias (or unknown key) carries
796
+ * `unknown`.
797
+ */
798
+ type GroupByMinMaxPart<T, A, Key extends '_min' | '_max'> = A extends {
799
+ [P in Key]: infer S;
800
+ } ? [S] extends [object] ? {
801
+ [P in Key]: {
802
+ [K in keyof S & string]: K extends keyof T ? T[K] : unknown;
803
+ };
804
+ } : unknown : unknown;
805
+ /**
806
+ * The typed result-row shape of a `groupBy(args)` call, computed from the args
807
+ * literal `A` (Prisma / Drizzle parity). Each `by` field carries the entity's
808
+ * field type; `_count` is always present (a group always has a row count); and
809
+ * each requested `_sum` / `_avg` / `_min` / `_max` block maps its selected
810
+ * fields to properly typed values.
811
+ *
812
+ * JSON-path group keys (objects in `by`) resolve to a runtime alias that is not
813
+ * knowable at the type level, so they are not projected onto the row type: cast
814
+ * the result when grouping by a JSON path. Intersections with `unknown` (an
815
+ * absent aggregate block) collapse away, so an args literal with no aggregates
816
+ * yields exactly `{ [byField]: T[field] } & { _count: number }`.
817
+ */
818
+ export type GroupByResult<T, A> = {
819
+ [K in GroupByFieldKeys<T, A>]: T[K];
820
+ } & {
821
+ _count: number;
822
+ } & GroupBySumAvgPart<A, '_sum'> & GroupBySumAvgPart<A, '_avg'> & GroupByMinMaxPart<T, A, '_min'> & GroupByMinMaxPart<T, A, '_max'>;
750
823
  /** Arguments for the standalone aggregate method */
751
824
  export interface AggregateArgs<T> {
752
825
  where?: WhereClause<T>;
@@ -1044,7 +1117,7 @@ export interface RelationPickOrderBy {
1044
1117
  plan?: 'subquery' | 'lateral';
1045
1118
  }
1046
1119
  /**
1047
- * An orderBy clause maps each key to one of:
1120
+ * A single orderBy object: maps each key to one of:
1048
1121
  * - a plain direction (`'asc'` / `'desc'`),
1049
1122
  * - an {@link OrderBySpec} (`{ sort, nulls }`) for NULLS placement,
1050
1123
  * - for json/jsonb columns, a JSON-path ordering ({@link JsonPathOrderBy}),
@@ -1053,5 +1126,14 @@ export interface RelationPickOrderBy {
1053
1126
  * target column for to-one) or a pick-row ordering
1054
1127
  * ({@link RelationPickOrderBy}, hasMany only).
1055
1128
  */
1056
- export type OrderByClause = Record<string, OrderDirection | OrderBySpec | JsonPathOrderBy | VectorOrderBy | RelationOrderBy | RelationPickOrderBy>;
1129
+ export type OrderByObject = Record<string, OrderDirection | OrderBySpec | JsonPathOrderBy | VectorOrderBy | RelationOrderBy | RelationPickOrderBy>;
1130
+ /**
1131
+ * An orderBy clause. Either a single {@link OrderByObject}
1132
+ * (`{ a: 'asc', b: 'desc' }`, insertion order authoritative) or a Prisma-style
1133
+ * array of them (`[{ a: 'asc' }, { b: 'desc' }]`, array order authoritative).
1134
+ * The array form makes multi-key ordering independent of JS object key
1135
+ * iteration order. Both forms flatten through `orderByEntries` so build,
1136
+ * param-collect, and cache-fingerprint paths stay in lockstep.
1137
+ */
1138
+ export type OrderByClause = OrderByObject | OrderByObject[];
1057
1139
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turbine-orm",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
4
4
  "description": "Postgres-native TypeScript ORM — runs on Neon, Vercel Postgres, Cloudflare, Supabase. Streaming cursors, typed errors, single-query nested relations. One dependency, no WASM engine",
5
5
  "type": "module",
6
6
  "exports": {
@@ -103,8 +103,8 @@
103
103
  "@size-limit/esbuild": "^12.1.0",
104
104
  "@size-limit/file": "^12.1.0",
105
105
  "@types/node": "^26.1.0",
106
- "@zvndev/powdb-client": "^0.17.0",
107
- "@zvndev/powdb-embedded": "^0.17.0",
106
+ "@zvndev/powdb-client": "^0.18.1",
107
+ "@zvndev/powdb-embedded": "^0.18.1",
108
108
  "c8": "^11.0.0",
109
109
  "husky": "^9.1.7",
110
110
  "lint-staged": "^17.0.8",