/** * This Source Code is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) Infonomic Company Limited */ /** * `buildSearchDocument` — the document-grain assembler for the * `SearchProvider` seam. Walks a collection's role-based `search` config * against one locale-resolved document and emits a single, type-enriched * `SearchDocument` for a driver to index. See * `docs/06-search/04-provider-contract.md`. * * Role-based and explicit: only the fields named in `search.{body,facets, * filters}` are projected — nothing is auto-pulled, so unindexed content * never leaks into the index. Core derives each field's `SearchFieldType` * from the schema (the "type enrichment") so a driver can map it onto its * own index without re-inspecting the collection definition. * * Pure and synchronous, like `documentToMarkdown`: the rich-text plain-text * extractor is the editor-agnostic `toText` seam passed via options, and * relation targets are resolved through a caller-supplied definition * resolver — no globals, no DB reads. The caller is responsible for handing * in a document whose `facets` relation fields are already populated (depth * 1) with the target's identity + counter fields. * * `search.{facets,filters}` name **top-level** fields. `search.body` may name * a top-level field of any kind: scalar / `richText` leaves index directly, * and container fields (`blocks` / `array` / `group`) are walked recursively — * every nested `richText` and text (`text` / `textArea`) leaf is flattened and * concatenated into one searchable body string. Nested non-text leaves * (`select`, `relation`, numbers, booleans, dates, files) are skipped so block * configuration never pollutes the index — the same "content, not * configuration" rule the markdown assembler follows. */ import { type CollectionDefinition, type RichTextToTextFn, type SearchDocument } from '../@types/index.js'; /** A locale-resolved document fed to the assembler — one locale's view. */ export interface SearchSourceDocument { /** Stable document id (shared across versions and locales). */ documentId: string; /** Content locale this view represents. */ locale: string; /** Lifecycle status of the indexed version. */ status: string; /** URL path, or null when the collection has none. */ path?: string | null; /** * Locale-resolved, camelCase field data (the `ClientDocument.fields` * shape). Relation fields named in `search.facets` must be populated. */ fields: Record; /** Timestamp of the indexed version. */ updatedAt?: Date | string; } export interface BuildSearchDocumentOptions { /** * Rich-text plain-text extractor (`ServerConfig.fields.richText.toText`). * Required for `richText` fields named in `search.body`; without it those * fields are skipped. */ richTextToText?: RichTextToTextFn; /** * Resolve a target collection definition by path — used to find a facet * target's identity field (the term) and `counter` field (the id). */ resolveTargetDefinition?: (collectionPath: string) => CollectionDefinition | null; /** Content locale, for defensive locale-envelope resolution. */ locale?: string; } /** * Assemble one type-enriched `SearchDocument` from a locale-resolved * document and its collection's role-based `search` config. */ /** * Resolve the zone set a collection indexes into, or `null` when the * collection doesn't opt into search at all. A collection with a `search` * config but no explicit `zones` belongs to a single implicit zone equal to * its own path. Shared by the assembler (below) and the client's * cross-collection `search({ zone })` membership check so the two can't * drift. */ export declare function resolveSearchZones(definition: CollectionDefinition): string[] | null; export declare function buildSearchDocument(doc: SearchSourceDocument, definition: CollectionDefinition, options?: BuildSearchDocumentOptions): SearchDocument;