@rebasepro/common 0.14.2-canary.gf913b76 → 0.15.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.
@@ -18,6 +18,13 @@ import type { OrderBySpec, OrderByTuple } from "@rebasepro/types";
18
18
  * the same value; the two are told apart by whether the first element is
19
19
  * itself an array, which no field name ever is.
20
20
  *
21
+ * This is also where a {@link RelationAggregateSort} object stops being an
22
+ * object. Above this function a sort key may be either spelling; below it,
23
+ * every key is a string — which is what `OrderByTuple`, the REST parameter, the
24
+ * driver contract and the cursor all already were. Doing it here means the one
25
+ * place that already collapses the two *shapes* of a sort also collapses the
26
+ * two *spellings* of a key, rather than every consumer learning about both.
27
+ *
21
28
  * @returns The keys in order of significance, or `undefined` for no sort. An
22
29
  * empty list also returns `undefined` — "sort by nothing" is no sort, and
23
30
  * letting `[]` through would have every layer below re-deciding what it meant.
package/dist/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ALL_WHERE_FILTER_OPS, ANONYMOUS_USER_ID, ANONYMOUS_USER_IDS, CANONICAL_TO_REST, DEFAULT_DATA_SOURCE_KEY, DEFAULT_LIST_LIMIT, EntityReference, EntityRelation, NULL_OPS, REST_TO_CANONICAL, RLS_ROLES_SQL, RLS_UID_SQL, getDataSourceCapabilities, getDeclaredSubcollections, isAnonymousUid, isManyToMany, isPostgresCollectionConfig, isRelationalCollectionConfig, policy, rewriteLegacyRlsFunctions, toCanonicalOp } from "@rebasepro/types";
1
+ import { ALL_WHERE_FILTER_OPS, ANONYMOUS_USER_ID, ANONYMOUS_USER_IDS, CANONICAL_TO_REST, DEFAULT_DATA_SOURCE_KEY, DEFAULT_LIST_LIMIT, EntityReference, EntityRelation, NULL_OPS, REST_TO_CANONICAL, RLS_ROLES_SQL, RLS_UID_SQL, getDataSourceCapabilities, getDeclaredSubcollections, isAnonymousUid, isManyToMany, isPostgresCollectionConfig, isRelationAggregateSort, isRelationalCollectionConfig, policy, rewriteLegacyRlsFunctions, sortKeyToString, toCanonicalOp } from "@rebasepro/types";
2
2
  import { deepClone, firstFreeKey, generateForeignKeyName, getIn, getPolicyNamesForRules, getPolicyOperations, isDefaultFieldConfigId, mergeDeep, prettifyIdentifier, randomString, removeFunctions, toSnakeCase, toWireKey } from "@rebasepro/utils";
3
3
  import jsonLogic from "json-logic-js";
4
4
  import { deepEqual } from "fast-equals";
@@ -3336,6 +3336,13 @@ var defaultUsersCollection = defineCollection({
3336
3336
  * the same value; the two are told apart by whether the first element is
3337
3337
  * itself an array, which no field name ever is.
3338
3338
  *
3339
+ * This is also where a {@link RelationAggregateSort} object stops being an
3340
+ * object. Above this function a sort key may be either spelling; below it,
3341
+ * every key is a string — which is what `OrderByTuple`, the REST parameter, the
3342
+ * driver contract and the cursor all already were. Doing it here means the one
3343
+ * place that already collapses the two *shapes* of a sort also collapses the
3344
+ * two *spellings* of a key, rather than every consumer learning about both.
3345
+ *
3339
3346
  * @returns The keys in order of significance, or `undefined` for no sort. An
3340
3347
  * empty list also returns `undefined` — "sort by nothing" is no sort, and
3341
3348
  * letting `[]` through would have every layer below re-deciding what it meant.
@@ -3343,7 +3350,8 @@ var defaultUsersCollection = defineCollection({
3343
3350
  function normalizeOrderBy(orderBy) {
3344
3351
  if (!orderBy || orderBy.length === 0) return void 0;
3345
3352
  const list = Array.isArray(orderBy[0]) ? orderBy : [orderBy];
3346
- return list.length > 0 ? list : void 0;
3353
+ if (list.length === 0) return void 0;
3354
+ return list.map(([key, direction]) => [sortKeyToString(key), direction]);
3347
3355
  }
3348
3356
  /**
3349
3357
  * The most significant sort key, for a caller that can only express one —
@@ -3398,14 +3406,16 @@ function parseOrderBySpecStrict(raw, order) {
3398
3406
  if (raw === void 0 || raw === null || raw === "") return void 0;
3399
3407
  if (typeof raw === "string") return normalizeDriverOrderBy(raw, order);
3400
3408
  if (!Array.isArray(raw) || raw.length === 0) throw new OrderBySpecError(`${typeof raw} is not a field name or a list of sort keys`);
3401
- if (typeof raw[0] === "string") return [toStrictTuple(raw, 0)];
3409
+ if (typeof raw[0] === "string" || isRelationAggregateSort(raw[0])) return [toStrictTuple(raw, 0)];
3402
3410
  return raw.map(toStrictTuple);
3403
3411
  }
3404
3412
  function toStrictTuple(raw, index) {
3405
- if (!Array.isArray(raw) || typeof raw[0] !== "string" || raw[0].trim() === "") throw new OrderBySpecError(`entry ${index} has no field name`);
3413
+ if (!Array.isArray(raw)) throw new OrderBySpecError(`entry ${index} has no field name`);
3414
+ const key = isRelationAggregateSort(raw[0]) ? sortKeyToString(raw[0]) : raw[0];
3415
+ if (typeof key !== "string" || key.trim() === "") throw new OrderBySpecError(`entry ${index} has no field name`);
3406
3416
  const direction = raw[1];
3407
3417
  if (direction !== void 0 && direction !== "asc" && direction !== "desc") throw new OrderBySpecError(`entry ${index} has direction '${String(direction)}'`);
3408
- return [raw[0], direction ?? "asc"];
3418
+ return [key, direction ?? "asc"];
3409
3419
  }
3410
3420
  /**
3411
3421
  * Serialize a sort to the wire.