@byline/core 6.9.0 → 6.10.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.
@@ -167,6 +167,24 @@ export interface SearchMatching {
167
167
  }
168
168
  /** Maximum UTF-16 length accepted for one full-text query. */
169
169
  export declare const MAX_SEARCH_QUERY_LENGTH = 1024;
170
+ /** Maximum `ceil((end - start) / gap)` for one range-facet request. */
171
+ export declare const MAX_RANGE_FACET_BUCKETS = 200;
172
+ /** One numeric range-facet request over an integer `search.filters` field. */
173
+ export interface SearchRangeFacetRequest {
174
+ field: string;
175
+ /** Inclusive lower edge of the first bucket. */
176
+ start: number;
177
+ /** Exclusive upper edge of the last bucket. */
178
+ end: number;
179
+ /** Bucket width; must be finite and greater than zero. */
180
+ gap: number;
181
+ }
182
+ /** One range bucket: `[start, end)` and its match count. */
183
+ export interface SearchRangeFacetBucket {
184
+ start: number;
185
+ end: number;
186
+ count: number;
187
+ }
170
188
  /**
171
189
  * A search request. Either collection-scoped (`collectionPath`) for
172
190
  * homogeneous results, or zone-scoped (`zone`) for heterogeneous
@@ -201,6 +219,8 @@ export interface SearchQuery {
201
219
  where?: QueryPredicate;
202
220
  /** Field names to compute facet buckets for (driver-capability gated). */
203
221
  facets?: string[];
222
+ /** Integer range aggregates; requires `capabilities.rangeFacets: true`. */
223
+ rangeFacets?: SearchRangeFacetRequest[];
204
224
  /** Restrict to a single content locale. */
205
225
  locale?: string;
206
226
  /**
@@ -254,6 +274,12 @@ export interface SearchResults {
254
274
  * driver supports them.
255
275
  */
256
276
  facets?: Record<string, SearchFacetBucket[]>;
277
+ /**
278
+ * Contiguous ascending buckets keyed by field, including zero counts.
279
+ * Cover exactly the requested `[start, end)`, truncating the final bucket.
280
+ * Counts respect the query, where, locale, status, and collection/zone scope.
281
+ */
282
+ rangeFacets?: Record<string, SearchRangeFacetBucket[]>;
257
283
  }
258
284
  /**
259
285
  * What a given driver can actually do. Lets consumers (the admin UI, the
@@ -266,6 +292,14 @@ export interface SearchResults {
266
292
  export interface SearchCapabilities {
267
293
  /** Faceted aggregation over indexed fields. */
268
294
  facets: boolean;
295
+ /** Integer range aggregation. Omission means false; unsupported requests must fail. */
296
+ rangeFacets?: boolean;
297
+ /**
298
+ * Applies `SearchQuery.where`. Omission means false. Advertise-only: the
299
+ * client still forwards `where` when absent. Providers may support a
300
+ * documented subset, but must reject unsupported fields or operators.
301
+ */
302
+ structuredFilters?: boolean;
269
303
  /** Fuzzy / typo-tolerant matching (e.g. `pg_trgm`). */
270
304
  typoTolerance: boolean;
271
305
  /** Vector / semantic / hybrid retrieval. */
@@ -7,3 +7,5 @@
7
7
  */
8
8
  /** Maximum UTF-16 length accepted for one full-text query. */
9
9
  export const MAX_SEARCH_QUERY_LENGTH = 1_024;
10
+ /** Maximum `ceil((end - start) / gap)` for one range-facet request. */
11
+ export const MAX_RANGE_FACET_BUCKETS = 200;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { expect, it } from 'vitest';
9
+ import { MAX_RANGE_FACET_BUCKETS } from '../index.js';
10
+ it('exports the range-facet contract and bucket cap from the public core entry point', () => {
11
+ const request = { field: 'year', start: 2000, end: 2003, gap: 2 };
12
+ const buckets = [
13
+ { start: 2000, end: 2002, count: 0 },
14
+ { start: 2002, end: 2003, count: 1 },
15
+ ];
16
+ const query = { query: '', rangeFacets: [request] };
17
+ const result = { hits: [], total: 1, rangeFacets: { year: buckets } };
18
+ expect(MAX_RANGE_FACET_BUCKETS).toBe(200);
19
+ expect(query.rangeFacets).toEqual([request]);
20
+ expect(result.rangeFacets?.year).toEqual(buckets);
21
+ });
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": "6.9.0",
5
+ "version": "6.10.0",
6
6
  "engines": {
7
7
  "node": ">=22.22.2"
8
8
  },
@@ -82,7 +82,7 @@
82
82
  "dist"
83
83
  ],
84
84
  "dependencies": {
85
- "@byline/auth": "6.9.0",
85
+ "@byline/auth": "6.10.0",
86
86
  "dotenv": "^18.0.8",
87
87
  "pino": "^10.4.0",
88
88
  "sharp": "^0.35.5",
@@ -90,15 +90,15 @@
90
90
  "zod": "^4.6.7"
91
91
  },
92
92
  "devDependencies": {
93
- "@biomejs/biome": "2.5.15",
93
+ "@biomejs/biome": "2.6.2",
94
94
  "@types/node": "^26.6.5",
95
- "chokidar": "^5.0.0",
95
+ "chokidar": "^6.0.0",
96
96
  "chokidar-cli": "^3.0.0",
97
97
  "npm-run-all": "^4.1.5",
98
- "tsc-alias": "^1.9.7",
98
+ "tsc-alias": "^1.9.8",
99
99
  "tsx": "^4.23.15",
100
100
  "typescript": "^7.0.2",
101
- "vitest": "^5.0.4"
101
+ "vitest": "^5.0.5"
102
102
  },
103
103
  "publishConfig": {
104
104
  "access": "public",