@byline/core 1.11.1 → 1.12.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.
@@ -179,23 +179,6 @@ export interface CollectionAdminConfig<T = any> {
179
179
  slug: string;
180
180
  /** Group name for organising collections in the admin sidebar. */
181
181
  group?: string;
182
- /**
183
- * When true, documents in this collection carry a fractional-index
184
- * `order_key` and the list view sorts by it ascending by default, with
185
- * drag-to-reorder enabled in the admin UI.
186
- *
187
- * Storage: `byline_documents.order_key` — admin metadata, never per-version
188
- * and never EAV. Reordering writes the single column and does NOT mint a
189
- * new document version.
190
- *
191
- * Backfill: existing rows in newly-`orderable` collections start with
192
- * `order_key = NULL`. They sort to the bottom (NULLS LAST) until the
193
- * editor drags them into position.
194
- *
195
- * Orthogonal to `hasMany` array order. Use this for top-level order
196
- * inside a collection (bios, team members, FAQ items, sections).
197
- */
198
- orderable?: boolean;
199
182
  /** Column definitions for the collection list view. */
200
183
  columns?: ColumnDefinition<T>[];
201
184
  /**
@@ -578,8 +578,8 @@ export interface AfterReadContext {
578
578
  * - `collectionPath` — the collection being queried (useful when the
579
579
  * same hook function is reused across collections).
580
580
  *
581
- * See `docs/AUTHN-AUTHZ.md` for the strategic rationale and
582
- * `docs/ACCESS-CONTROL-RECIPES.md` for worked examples.
581
+ * See `docs/AUTHN-AUTHZ.md` for the strategic rationale; the Quick
582
+ * Reference there carries six worked recipes.
583
583
  */
584
584
  export interface BeforeReadContext {
585
585
  collectionPath: string;
@@ -655,8 +655,8 @@ export interface CollectionHooks {
655
655
  * that the query layer ANDs onto the caller's `where` to enforce
656
656
  * read-side row scoping (multi-tenant, owner-only-drafts, soft-delete
657
657
  * hide, etc). Returning `void` applies no scoping. Multiple functions
658
- * combine with implicit AND. See
659
- * `docs/ACCESS-CONTROL-RECIPES.md`.
658
+ * combine with implicit AND. See `docs/AUTHN-AUTHZ.md` (Read-side
659
+ * scoping + Quick Reference recipes).
660
660
  */
661
661
  beforeRead?: BeforeReadHookSlot;
662
662
  /**
@@ -725,6 +725,28 @@ export interface CollectionDefinition {
725
725
  * on every landing-page load, so opt in deliberately.
726
726
  */
727
727
  showStats?: boolean;
728
+ /**
729
+ * When `true`, documents in this collection carry a fractional-index
730
+ * `order_key` and the list view sorts by it ascending by default, with
731
+ * drag-to-reorder enabled in the admin UI.
732
+ *
733
+ * Storage: `byline_documents.order_key` — system metadata, never per-version
734
+ * and never EAV. Reordering writes the single column and does NOT mint a
735
+ * new document version.
736
+ *
737
+ * Backfill: existing rows in newly-`orderable` collections start with
738
+ * `order_key = NULL`. They sort to the bottom (NULLS LAST) until the
739
+ * editor drags them into position.
740
+ *
741
+ * Lives on the schema (not admin config) because it has structural
742
+ * consequences across layers — `document-lifecycle` appends a key on
743
+ * create, the reorder server fn gates on it, and the `@byline/client`
744
+ * SDK can default-sort on it without crossing into presentation config.
745
+ *
746
+ * Orthogonal to `hasMany` array order. Use this for top-level order
747
+ * inside a collection (bios, team members, FAQ items, sections).
748
+ */
749
+ orderable?: boolean;
728
750
  /**
729
751
  * Optional explicit version pin. When omitted, the startup bootstrap
730
752
  * auto-increments the collection's stored version any time the schema
@@ -231,7 +231,7 @@ export interface IDocumentCommands {
231
231
  * Only set on the initial create (when `documentId` is undefined) for
232
232
  * collections with `orderable: true`. Ignored on subsequent versions of
233
233
  * an existing document — order is admin metadata on the logical document,
234
- * not per-version content. See docs/ORDERABLE.md.
234
+ * not per-version content. See docs/COLLECTIONS.md (Orderable collections).
235
235
  */
236
236
  orderKey?: string;
237
237
  }): Promise<{
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { isArrayField, isBlocksField, isGroupField, normalizeCollectionHook, } from '../@types/index.js';
9
9
  import { assertActorCanPerform } from '../auth/assert-actor-can-perform.js';
10
- import { getCollectionAdminConfig } from '../config/config.js';
10
+ import { getCollectionDefinition } from '../config/config.js';
11
11
  import { ERR_CONFLICT, ERR_INVALID_TRANSITION, ERR_NOT_FOUND, ERR_PATCH_FAILED, ERR_PATH_CONFLICT, ERR_VALIDATION, ErrorCodes, } from '../lib/errors.js';
12
12
  import { generateKeyBetween } from '../lib/fractional-index.js';
13
13
  import { withLogContext } from '../lib/logger.js';
@@ -31,15 +31,15 @@ async function invokeHook(hook, ctx) {
31
31
  }
32
32
  }
33
33
  /**
34
- * For collections with `orderable: true` in their admin config, compute an
35
- * append-at-end fractional-index key for a newly-inserted document.
36
- * Returns `undefined` when the collection hasn't opted in (or has no admin
37
- * config registered, e.g. in unit-test environments), so the storage row
34
+ * For collections with `orderable: true` on their schema definition, compute
35
+ * an append-at-end fractional-index key for a newly-inserted document.
36
+ * Returns `undefined` when the collection hasn't opted in (or has no
37
+ * definition registered, e.g. in unit-test environments), so the storage row
38
38
  * gets `order_key = NULL` and the existing "no ordering" behavior holds.
39
39
  */
40
40
  async function maybeAppendOrderKey(ctx, collectionPath) {
41
- const adminConfig = getCollectionAdminConfig(collectionPath);
42
- if (adminConfig?.orderable !== true)
41
+ const definition = getCollectionDefinition(collectionPath);
42
+ if (definition?.orderable !== true)
43
43
  return undefined;
44
44
  const last = await ctx.db.queries.documents.getLastOrderKey({
45
45
  collection_id: ctx.collectionId,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@byline/core",
3
3
  "private": false,
4
4
  "license": "MPL-2.0",
5
- "version": "1.11.1",
5
+ "version": "1.12.0",
6
6
  "engines": {
7
7
  "node": ">=20.9.0"
8
8
  },
@@ -79,7 +79,7 @@
79
79
  "sharp": "^0.34.5",
80
80
  "uuid": "^14.0.0",
81
81
  "zod": "^4.4.3",
82
- "@byline/auth": "1.11.1"
82
+ "@byline/auth": "1.12.0"
83
83
  },
84
84
  "devDependencies": {
85
85
  "@biomejs/biome": "2.4.15",
@@ -98,7 +98,7 @@
98
98
  "scripts": {
99
99
  "dev": "chokidar 'src/**/*' -c 'npm-run-all build'",
100
100
  "build": "tsc -p tsconfig.json && tsc-alias",
101
- "clean": "rimraf node_modules dist build .turbo",
101
+ "clean": "node scripts/clean.js node_modules dist build .turbo",
102
102
  "lint": "biome check --write --unsafe --diagnostic-level=error",
103
103
  "skip": "tsx ./scripts/task-watch.js",
104
104
  "test": "vitest run --mode=node",