@byline/client 4.17.0 → 4.18.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.
- package/dist/collection-handle.js +3 -1
- package/dist/search.d.ts +3 -1
- package/dist/search.js +16 -0
- package/dist/types.d.ts +4 -0
- package/package.json +5 -5
|
@@ -9,7 +9,7 @@ import { applyAfterRead, assertActorCanPerform, buildSearchDocument, cancelDocum
|
|
|
9
9
|
import { getReadSecurityDomain, resolveReadRequestContext, resolveReadSecurityFilters, } from './read-context.js';
|
|
10
10
|
import { expectedDocumentId } from './read-internals.js';
|
|
11
11
|
import { shapeDocument, shapePopulatedInPlace } from './response.js';
|
|
12
|
-
import { assertSearchQueryLength, finalizeSearchHits } from './search.js';
|
|
12
|
+
import { assertSearchFieldScope, assertSearchQueryLength, finalizeSearchHits } from './search.js';
|
|
13
13
|
function toScheduleInfo(schedule) {
|
|
14
14
|
const { executionToken: _executionToken, executionExpiresAt: _executionExpiresAt, ...info } = schedule;
|
|
15
15
|
return info;
|
|
@@ -148,8 +148,10 @@ export class CollectionHandle {
|
|
|
148
148
|
'see `@byline/search-postgres` → `postgresSearch()` for the built-in driver.',
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
|
+
assertSearchFieldScope(provider, options.fieldScope);
|
|
151
152
|
const results = await provider.search({
|
|
152
153
|
query: options.query,
|
|
154
|
+
fieldScope: options.fieldScope,
|
|
153
155
|
matching: options.matching,
|
|
154
156
|
collectionPath: this.definition.path,
|
|
155
157
|
locale: options.locale ?? this.client.defaultLocale,
|
package/dist/search.d.ts
CHANGED
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
* into shaped `ClientDocument`s in the same query.
|
|
18
18
|
*/
|
|
19
19
|
import type { RequestContext } from '@byline/auth';
|
|
20
|
-
import type { ReadContext, ReadMode, SearchHit } from '@byline/core';
|
|
20
|
+
import type { ReadContext, ReadMode, SearchHit, SearchProvider } from '@byline/core';
|
|
21
21
|
import type { BylineClient } from './client.js';
|
|
22
22
|
import type { ClientSearchResults, HydratedSearchHit, ZoneSearchOptions } from './types.js';
|
|
23
|
+
/** Validate the optional logical body-field scope before calling a provider. */
|
|
24
|
+
export declare function assertSearchFieldScope(provider: SearchProvider, fieldScope: string[] | undefined): void;
|
|
23
25
|
export interface FinalizeSearchHitsParams {
|
|
24
26
|
client: BylineClient<any>;
|
|
25
27
|
requestContext: RequestContext;
|
package/dist/search.js
CHANGED
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { assertActorCanPerform, createReadContext, ERR_VALIDATION, getCollectionAdminConfig, MAX_SEARCH_QUERY_LENGTH, resolveSearchZones, } from '@byline/core';
|
|
9
9
|
import { resolveReadRequestContext, resolveReadSecurityFilters } from './read-context.js';
|
|
10
|
+
/** Validate the optional logical body-field scope before calling a provider. */
|
|
11
|
+
export function assertSearchFieldScope(provider, fieldScope) {
|
|
12
|
+
if (fieldScope == null)
|
|
13
|
+
return;
|
|
14
|
+
if (fieldScope.length === 0 ||
|
|
15
|
+
fieldScope.some((field) => typeof field !== 'string' || field.trim().length === 0)) {
|
|
16
|
+
throw ERR_VALIDATION({ message: 'Search fieldScope must contain one or more field names.' });
|
|
17
|
+
}
|
|
18
|
+
if (!provider.capabilities.fullText.fieldScope) {
|
|
19
|
+
throw ERR_VALIDATION({
|
|
20
|
+
message: 'The registered search provider does not support field-scoped full-text queries.',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
10
24
|
/**
|
|
11
25
|
* Authorise (and optionally hydrate) provider hits, per collection:
|
|
12
26
|
*
|
|
@@ -163,6 +177,7 @@ export async function zoneSearch(client, options) {
|
|
|
163
177
|
if (readable.size === 0) {
|
|
164
178
|
throw firstAbilityError;
|
|
165
179
|
}
|
|
180
|
+
assertSearchFieldScope(provider, options.fieldScope);
|
|
166
181
|
let aggregateRestricted = readable.size !== members.length;
|
|
167
182
|
if (!options._bypassBeforeRead) {
|
|
168
183
|
for (const member of members) {
|
|
@@ -176,6 +191,7 @@ export async function zoneSearch(client, options) {
|
|
|
176
191
|
}
|
|
177
192
|
const results = await provider.search({
|
|
178
193
|
query: options.query,
|
|
194
|
+
fieldScope: options.fieldScope,
|
|
179
195
|
matching: options.matching,
|
|
180
196
|
zone: options.zone,
|
|
181
197
|
locale: options.locale ?? client.defaultLocale,
|
package/dist/types.d.ts
CHANGED
|
@@ -183,6 +183,8 @@ interface StatusControls {
|
|
|
183
183
|
export interface CollectionSearchOptions extends BeforeReadControls {
|
|
184
184
|
/** Free-text query string. */
|
|
185
185
|
query: string;
|
|
186
|
+
/** Restrict full-text matching to named fields from the collection's `search.body`. */
|
|
187
|
+
fieldScope?: string[];
|
|
186
188
|
/** Provider-neutral term and phrase matching semantics. */
|
|
187
189
|
matching?: SearchMatching;
|
|
188
190
|
/** Restrict to a single content locale (defaults to the client default). */
|
|
@@ -217,6 +219,8 @@ export interface CollectionSearchOptions extends BeforeReadControls {
|
|
|
217
219
|
export interface ZoneSearchOptions extends BeforeReadControls {
|
|
218
220
|
/** Free-text query string. */
|
|
219
221
|
query: string;
|
|
222
|
+
/** Restrict full-text matching to body-field names shared by participating collections. */
|
|
223
|
+
fieldScope?: string[];
|
|
220
224
|
/** Provider-neutral term and phrase matching semantics. */
|
|
221
225
|
matching?: SearchMatching;
|
|
222
226
|
/** The zone (named cross-collection scope) to search. */
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/client",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.18.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"uuid": "^14.0.2",
|
|
47
|
-
"@byline/auth": "4.
|
|
48
|
-
"@byline/core": "4.
|
|
47
|
+
"@byline/auth": "4.18.0",
|
|
48
|
+
"@byline/core": "4.18.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@biomejs/biome": "2.5.10",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"tsc-alias": "^1.9.2",
|
|
58
58
|
"typescript": "^7.0.2",
|
|
59
59
|
"vitest": "^4.1.11",
|
|
60
|
-
"@byline/search-postgres": "4.
|
|
61
|
-
"@byline/db-postgres": "4.
|
|
60
|
+
"@byline/search-postgres": "4.18.0",
|
|
61
|
+
"@byline/db-postgres": "4.18.0"
|
|
62
62
|
},
|
|
63
63
|
"publishConfig": {
|
|
64
64
|
"access": "public",
|