@memberjunction/search-engine 5.49.0 → 5.50.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/generic/EntitySearchProvider.d.ts +17 -3
- package/dist/generic/EntitySearchProvider.d.ts.map +1 -1
- package/dist/generic/EntitySearchProvider.js +23 -6
- package/dist/generic/EntitySearchProvider.js.map +1 -1
- package/dist/generic/ExternalHitMapper.d.ts +48 -0
- package/dist/generic/ExternalHitMapper.d.ts.map +1 -0
- package/dist/generic/ExternalHitMapper.js +88 -0
- package/dist/generic/ExternalHitMapper.js.map +1 -0
- package/dist/generic/FullTextSearchProvider.d.ts +9 -1
- package/dist/generic/FullTextSearchProvider.d.ts.map +1 -1
- package/dist/generic/FullTextSearchProvider.js +11 -3
- package/dist/generic/FullTextSearchProvider.js.map +1 -1
- package/dist/generic/ScopeDimensionResolver.d.ts +146 -0
- package/dist/generic/ScopeDimensionResolver.d.ts.map +1 -0
- package/dist/generic/ScopeDimensionResolver.js +464 -0
- package/dist/generic/ScopeDimensionResolver.js.map +1 -0
- package/dist/generic/ScopeExplanation.d.ts +141 -0
- package/dist/generic/ScopeExplanation.d.ts.map +1 -0
- package/dist/generic/ScopeExplanation.js +72 -0
- package/dist/generic/ScopeExplanation.js.map +1 -0
- package/dist/generic/ScopeFilterGuard.d.ts +127 -0
- package/dist/generic/ScopeFilterGuard.d.ts.map +1 -0
- package/dist/generic/ScopeFilterGuard.js +290 -0
- package/dist/generic/ScopeFilterGuard.js.map +1 -0
- package/dist/generic/ScopeTemplateRenderer.d.ts +12 -2
- package/dist/generic/ScopeTemplateRenderer.d.ts.map +1 -1
- package/dist/generic/ScopeTemplateRenderer.js +25 -5
- package/dist/generic/ScopeTemplateRenderer.js.map +1 -1
- package/dist/generic/ScopeValueEscaper.d.ts +112 -0
- package/dist/generic/ScopeValueEscaper.d.ts.map +1 -0
- package/dist/generic/ScopeValueEscaper.js +152 -0
- package/dist/generic/ScopeValueEscaper.js.map +1 -0
- package/dist/generic/SearchEngine.d.ts +188 -8
- package/dist/generic/SearchEngine.d.ts.map +1 -1
- package/dist/generic/SearchEngine.js +600 -35
- package/dist/generic/SearchEngine.js.map +1 -1
- package/dist/generic/VectorSearchProvider.d.ts +2 -1
- package/dist/generic/VectorSearchProvider.d.ts.map +1 -1
- package/dist/generic/VectorSearchProvider.js +23 -26
- package/dist/generic/VectorSearchProvider.js.map +1 -1
- package/dist/generic/search.types.d.ts +160 -0
- package/dist/generic/search.types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/permissions/SearchScopePermissionResolver.d.ts +37 -2
- package/dist/permissions/SearchScopePermissionResolver.d.ts.map +1 -1
- package/dist/permissions/SearchScopePermissionResolver.js +74 -2
- package/dist/permissions/SearchScopePermissionResolver.js.map +1 -1
- package/dist/providers/AzureAISearchProvider.d.ts.map +1 -1
- package/dist/providers/AzureAISearchProvider.js +24 -6
- package/dist/providers/AzureAISearchProvider.js.map +1 -1
- package/dist/providers/ElasticsearchSearchProvider.d.ts.map +1 -1
- package/dist/providers/ElasticsearchSearchProvider.js +17 -5
- package/dist/providers/ElasticsearchSearchProvider.js.map +1 -1
- package/dist/providers/OpenSearchSearchProvider.d.ts.map +1 -1
- package/dist/providers/OpenSearchSearchProvider.js +16 -5
- package/dist/providers/OpenSearchSearchProvider.js.map +1 -1
- package/dist/providers/TypesenseSearchProvider.d.ts.map +1 -1
- package/dist/providers/TypesenseSearchProvider.js +17 -6
- package/dist/providers/TypesenseSearchProvider.js.map +1 -1
- package/package.json +8 -8
|
@@ -18,11 +18,25 @@ import { SearchSource, SearchFilters, SearchResultItem, ScopeConstraints } from
|
|
|
18
18
|
export declare class EntitySearchProvider extends BaseSearchProvider {
|
|
19
19
|
readonly SourceType: SearchSource;
|
|
20
20
|
/**
|
|
21
|
-
* Minimum trimmed term length we accept.
|
|
22
|
-
*
|
|
23
|
-
* full-database scan with negligible relevance, so we early-return for those.
|
|
21
|
+
* Minimum trimmed term length we accept. A single-character substring against a
|
|
22
|
+
* `LIKE '%term%'` pattern across every searchable entity is essentially a
|
|
23
|
+
* full-database scan with negligible relevance, so we early-return for those. Set to 2
|
|
24
|
+
* (was 3) so legitimate short queries — product codes, initials, "US", "AI" — are not
|
|
25
|
+
* silently dropped (bug C3: users couldn't find records that exist).
|
|
24
26
|
*/
|
|
25
27
|
private static readonly MIN_TERM_LENGTH;
|
|
28
|
+
/**
|
|
29
|
+
* How many rows to fetch PER ENTITY as the relevance-ranking candidate pool. This is
|
|
30
|
+
* DELIBERATELY decoupled from the global `topK` budget (bug C3): previously the per-entity
|
|
31
|
+
* limit was `topK / entityCount` floored at 3, so with ~150 searchable entities each entity
|
|
32
|
+
* returned only ~3 arbitrary rows and real matches beyond row 3 were never fetched — and
|
|
33
|
+
* enabling MORE entities starved each one further. Now each entity contributes up to this
|
|
34
|
+
* many candidates; the engine still trims the fused, relevance-sorted result set back to
|
|
35
|
+
* `topK`, so the returned count is unchanged — we only widen the candidate pool per entity.
|
|
36
|
+
* Public + static so a deployment can tune it at startup (larger entity counts may lower it
|
|
37
|
+
* to bound the row-materialization cost of the parallel fan-out).
|
|
38
|
+
*/
|
|
39
|
+
static PerEntityFetchDepth: number;
|
|
26
40
|
/**
|
|
27
41
|
* Per-entity hard timeout. If one entity's RunView is taking longer than this,
|
|
28
42
|
* we drop its results rather than hold the entire fan-out hostage. The query
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntitySearchProvider.d.ts","sourceRoot":"","sources":["../../src/generic/EntitySearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAmD,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAoB,gBAAgB,EAAyB,MAAM,gBAAgB,CAAC;AAE1I;;;;GAIG;AACH,qBACa,oBAAqB,SAAQ,kBAAkB;IACxD,SAAgB,UAAU,EAAE,YAAY,CAAY;IAEpD
|
|
1
|
+
{"version":3,"file":"EntitySearchProvider.d.ts","sourceRoot":"","sources":["../../src/generic/EntitySearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAmD,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAoB,gBAAgB,EAAyB,MAAM,gBAAgB,CAAC;AAE1I;;;;GAIG;AACH,qBACa,oBAAqB,SAAQ,kBAAkB;IACxD,SAAgB,UAAU,EAAE,YAAY,CAAY;IAEpD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAK;IAE5C;;;;;;;;;;OAUG;IACH,OAAc,mBAAmB,SAAM;IAEvC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAEvD;;;;;;;;OAQG;IACU,MAAM,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,WAAW,EAAE,QAAQ,EACrB,gBAAgB,CAAC,EAAE,gBAAgB,GACpC,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAoF9B;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;;;;;;;OASG;YACW,eAAe;YAsBf,kBAAkB;IA8BhC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAwDtB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,wBAAwB;CAGnC"}
|
|
@@ -29,11 +29,25 @@ let EntitySearchProvider = class EntitySearchProvider extends BaseSearchProvider
|
|
|
29
29
|
}
|
|
30
30
|
static { EntitySearchProvider_1 = this; }
|
|
31
31
|
/**
|
|
32
|
-
* Minimum trimmed term length we accept.
|
|
33
|
-
*
|
|
34
|
-
* full-database scan with negligible relevance, so we early-return for those.
|
|
32
|
+
* Minimum trimmed term length we accept. A single-character substring against a
|
|
33
|
+
* `LIKE '%term%'` pattern across every searchable entity is essentially a
|
|
34
|
+
* full-database scan with negligible relevance, so we early-return for those. Set to 2
|
|
35
|
+
* (was 3) so legitimate short queries — product codes, initials, "US", "AI" — are not
|
|
36
|
+
* silently dropped (bug C3: users couldn't find records that exist).
|
|
35
37
|
*/
|
|
36
|
-
static { this.MIN_TERM_LENGTH =
|
|
38
|
+
static { this.MIN_TERM_LENGTH = 2; }
|
|
39
|
+
/**
|
|
40
|
+
* How many rows to fetch PER ENTITY as the relevance-ranking candidate pool. This is
|
|
41
|
+
* DELIBERATELY decoupled from the global `topK` budget (bug C3): previously the per-entity
|
|
42
|
+
* limit was `topK / entityCount` floored at 3, so with ~150 searchable entities each entity
|
|
43
|
+
* returned only ~3 arbitrary rows and real matches beyond row 3 were never fetched — and
|
|
44
|
+
* enabling MORE entities starved each one further. Now each entity contributes up to this
|
|
45
|
+
* many candidates; the engine still trims the fused, relevance-sorted result set back to
|
|
46
|
+
* `topK`, so the returned count is unchanged — we only widen the candidate pool per entity.
|
|
47
|
+
* Public + static so a deployment can tune it at startup (larger entity counts may lower it
|
|
48
|
+
* to bound the row-materialization cost of the parallel fan-out).
|
|
49
|
+
*/
|
|
50
|
+
static { this.PerEntityFetchDepth = 15; }
|
|
37
51
|
/**
|
|
38
52
|
* Per-entity hard timeout. If one entity's RunView is taking longer than this,
|
|
39
53
|
* we drop its results rather than hold the entire fan-out hostage. The query
|
|
@@ -93,8 +107,11 @@ let EntitySearchProvider = class EntitySearchProvider extends BaseSearchProvider
|
|
|
93
107
|
LogStatus(` Entity "${e.EntityName}": ${searchFields.length} searchable fields [${searchFields.slice(0, 5).map(f => f.Name).join(', ')}${searchFields.length > 5 ? '...' : ''}]`);
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
|
-
//
|
|
97
|
-
|
|
110
|
+
// Per-entity candidate depth — decoupled from the global topK budget so widening the
|
|
111
|
+
// entity fan-out never starves any single entity (bug C3). Each entity contributes up to
|
|
112
|
+
// PerEntityFetchDepth candidates (but never more than topK, since the final result set is
|
|
113
|
+
// capped at topK anyway); the fused set is relevance-sorted and sliced to topK below.
|
|
114
|
+
const perEntityLimit = Math.min(topK, Math.max(EntitySearchProvider_1.PerEntityFetchDepth, Math.ceil(topK / Math.max(1, scoped.length))));
|
|
98
115
|
// Search all entities in parallel, threading per-entity ExtraFilter + UserSearchString
|
|
99
116
|
// override; each call is gated by a hard PER_ENTITY_TIMEOUT_MS timeout (next PR #2532)
|
|
100
117
|
// so a slow entity cannot hold up the whole fan-out — partial results from the other
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntitySearchProvider.js","sourceRoot":"","sources":["../../src/generic/EntitySearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;;;;AAEH,OAAO,EAAqB,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAY,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD;;;;GAIG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,kBAAkB;IAArD;;QACa,eAAU,GAAiB,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"EntitySearchProvider.js","sourceRoot":"","sources":["../../src/generic/EntitySearchProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared field mapping for external search indexes.
|
|
3
|
+
*
|
|
4
|
+
* @module @memberjunction/search-engine
|
|
5
|
+
*/
|
|
6
|
+
/** A document returned by an external search index. */
|
|
7
|
+
export type ExternalSearchDocument = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Chunk-level provenance recovered from an external index document.
|
|
10
|
+
*
|
|
11
|
+
* External indexes are populated outside MemberJunction, so these fields are present only
|
|
12
|
+
* when the indexing pipeline chose to emit them. Every field is optional by construction.
|
|
13
|
+
*/
|
|
14
|
+
export interface ExternalChunkProvenance {
|
|
15
|
+
/** `MJ: Content Item Chunks` row id, when the indexed unit is a chunk rather than a whole item. */
|
|
16
|
+
ChunkID?: string;
|
|
17
|
+
/** Parent `MJ: Content Items` id. */
|
|
18
|
+
ContentItemID?: string;
|
|
19
|
+
/** Chunk modality — text, image, audio, video, or multimodal. */
|
|
20
|
+
Modality?: string;
|
|
21
|
+
/** Start of the chunk's time window, in ms, for audio/video. */
|
|
22
|
+
StartMs?: number;
|
|
23
|
+
/** End of the chunk's time window, in ms. */
|
|
24
|
+
EndMs?: number;
|
|
25
|
+
/** One-based page number for paginated sources. */
|
|
26
|
+
PageNumber?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a document's snippet text, preferring an explicitly configured field.
|
|
30
|
+
*
|
|
31
|
+
* @param doc - the raw hit document
|
|
32
|
+
* @param preferredField - deployment-configured field name, checked before the defaults
|
|
33
|
+
*/
|
|
34
|
+
export declare function ResolveHitSnippet(doc: ExternalSearchDocument, preferredField?: string): string;
|
|
35
|
+
/** Resolve a document's title, falling back to the supplied default. */
|
|
36
|
+
export declare function ResolveHitTitle(doc: ExternalSearchDocument, fallback: string, preferredField?: string): string;
|
|
37
|
+
/** Resolve a document's identifier, falling back to the supplied default. */
|
|
38
|
+
export declare function ResolveHitID(doc: ExternalSearchDocument, fallback: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Extract chunk provenance from a hit.
|
|
41
|
+
*
|
|
42
|
+
* This is what lets a search result deep-link to a moment in a recording or a page in a
|
|
43
|
+
* PDF rather than just naming the asset. Absent fields are simply omitted.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ExtractChunkProvenance(doc: ExternalSearchDocument): ExternalChunkProvenance;
|
|
46
|
+
/** True when any provenance field was found. */
|
|
47
|
+
export declare function HasChunkProvenance(provenance: ExternalChunkProvenance): boolean;
|
|
48
|
+
//# sourceMappingURL=ExternalHitMapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExternalHitMapper.d.ts","sourceRoot":"","sources":["../../src/generic/ExternalHitMapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uDAAuD;AACvD,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACpC,mGAAmG;IACnG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,sBAAsB,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9F;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,GAAG,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9G;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,sBAAsB,GAAG,uBAAuB,CAS3F;AAED,gDAAgD;AAChD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAE/E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared field mapping for external search indexes.
|
|
3
|
+
*
|
|
4
|
+
* @module @memberjunction/search-engine
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Field names checked, in order, when looking for a document's readable body.
|
|
8
|
+
*
|
|
9
|
+
* `transcript` and `description` matter for multimodal corpora: a media chunk carries no
|
|
10
|
+
* body text of its own, and these are the columns that make it findable and readable. They
|
|
11
|
+
* sit after `content` so a conventional text document is unaffected.
|
|
12
|
+
*/
|
|
13
|
+
const SNIPPET_FIELDS = ['content', 'body', 'text', 'description', 'transcript', 'summary'];
|
|
14
|
+
/** Field names checked, in order, when looking for a document's title. */
|
|
15
|
+
const TITLE_FIELDS = ['title', 'name', 'Name', 'segmentTitle', 'SegmentTitle', 'heading'];
|
|
16
|
+
/** Field names checked, in order, when looking for a document's id. */
|
|
17
|
+
const ID_FIELDS = ['id', 'Id', 'ID', 'recordId', 'RecordID'];
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a document's snippet text, preferring an explicitly configured field.
|
|
20
|
+
*
|
|
21
|
+
* @param doc - the raw hit document
|
|
22
|
+
* @param preferredField - deployment-configured field name, checked before the defaults
|
|
23
|
+
*/
|
|
24
|
+
export function ResolveHitSnippet(doc, preferredField) {
|
|
25
|
+
const candidates = preferredField ? [preferredField, ...SNIPPET_FIELDS] : SNIPPET_FIELDS;
|
|
26
|
+
return firstString(doc, candidates) ?? '';
|
|
27
|
+
}
|
|
28
|
+
/** Resolve a document's title, falling back to the supplied default. */
|
|
29
|
+
export function ResolveHitTitle(doc, fallback, preferredField) {
|
|
30
|
+
const candidates = preferredField ? [preferredField, ...TITLE_FIELDS] : TITLE_FIELDS;
|
|
31
|
+
return firstString(doc, candidates) ?? fallback;
|
|
32
|
+
}
|
|
33
|
+
/** Resolve a document's identifier, falling back to the supplied default. */
|
|
34
|
+
export function ResolveHitID(doc, fallback) {
|
|
35
|
+
return firstString(doc, ID_FIELDS) ?? fallback;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Extract chunk provenance from a hit.
|
|
39
|
+
*
|
|
40
|
+
* This is what lets a search result deep-link to a moment in a recording or a page in a
|
|
41
|
+
* PDF rather than just naming the asset. Absent fields are simply omitted.
|
|
42
|
+
*/
|
|
43
|
+
export function ExtractChunkProvenance(doc) {
|
|
44
|
+
const provenance = {};
|
|
45
|
+
assignString(provenance, 'ChunkID', doc, ['chunkId', 'ChunkID', 'chunk_id']);
|
|
46
|
+
assignString(provenance, 'ContentItemID', doc, ['contentItemId', 'ContentItemID', 'content_item_id']);
|
|
47
|
+
assignString(provenance, 'Modality', doc, ['modality', 'Modality']);
|
|
48
|
+
assignNumber(provenance, 'StartMs', doc, ['startMs', 'StartMs', 'start_ms']);
|
|
49
|
+
assignNumber(provenance, 'EndMs', doc, ['endMs', 'EndMs', 'end_ms']);
|
|
50
|
+
assignNumber(provenance, 'PageNumber', doc, ['pageNumber', 'PageNumber', 'page_number']);
|
|
51
|
+
return provenance;
|
|
52
|
+
}
|
|
53
|
+
/** True when any provenance field was found. */
|
|
54
|
+
export function HasChunkProvenance(provenance) {
|
|
55
|
+
return Object.keys(provenance).length > 0;
|
|
56
|
+
}
|
|
57
|
+
// ─────────────────────────────────────────────
|
|
58
|
+
// Helpers
|
|
59
|
+
// ─────────────────────────────────────────────
|
|
60
|
+
/** First non-empty string value among the candidate keys. */
|
|
61
|
+
function firstString(doc, keys) {
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const value = doc[key];
|
|
64
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
/** Copy the first matching string field onto the provenance object. */
|
|
71
|
+
function assignString(target, field, doc, keys) {
|
|
72
|
+
const value = firstString(doc, keys);
|
|
73
|
+
if (value !== undefined) {
|
|
74
|
+
target[field] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Copy the first matching numeric field onto the provenance object. */
|
|
78
|
+
function assignNumber(target, field, doc, keys) {
|
|
79
|
+
for (const key of keys) {
|
|
80
|
+
const value = doc[key];
|
|
81
|
+
const numeric = typeof value === 'number' ? value : typeof value === 'string' ? Number(value) : NaN;
|
|
82
|
+
if (Number.isFinite(numeric)) {
|
|
83
|
+
target[field] = numeric;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=ExternalHitMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExternalHitMapper.js","sourceRoot":"","sources":["../../src/generic/ExternalHitMapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,9 +20,17 @@ export declare class FullTextSearchProvider extends BaseSearchProvider {
|
|
|
20
20
|
readonly SourceType: SearchSource;
|
|
21
21
|
/**
|
|
22
22
|
* Minimum trimmed term length we accept. SQL Server FTS treats single
|
|
23
|
-
* characters as noise; rejecting them matches the EntitySearchProvider guard.
|
|
23
|
+
* characters as noise; rejecting them matches the EntitySearchProvider guard. Set to 2
|
|
24
|
+
* (was 3) so legitimate short queries aren't silently dropped (bug C3).
|
|
24
25
|
*/
|
|
25
26
|
private static readonly MIN_TERM_LENGTH;
|
|
27
|
+
/**
|
|
28
|
+
* Rows to fetch PER ENTITY as the ranking candidate pool — decoupled from the global `topK`
|
|
29
|
+
* budget (bug C3). Previously `topK / 10`, which capped every FTS entity to a tiny arbitrary
|
|
30
|
+
* slice regardless of how many entities matched. The engine still trims the fused set to topK.
|
|
31
|
+
* Public + static so a deployment can tune it at startup. Mirrors EntitySearchProvider.
|
|
32
|
+
*/
|
|
33
|
+
static PerEntityFetchDepth: number;
|
|
26
34
|
private enricher;
|
|
27
35
|
/** Set the enricher instance. Called by SearchEngine after construction. */
|
|
28
36
|
SetEnricher(enricher: SearchEnricher): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullTextSearchProvider.d.ts","sourceRoot":"","sources":["../../src/generic/FullTextSearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAA8B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAoB,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,qBACa,sBAAuB,SAAQ,kBAAkB;IAC1D,SAAgB,UAAU,EAAE,YAAY,CAAc;IAEtD
|
|
1
|
+
{"version":3,"file":"FullTextSearchProvider.d.ts","sourceRoot":"","sources":["../../src/generic/FullTextSearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAA8B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAoB,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,qBACa,sBAAuB,SAAQ,kBAAkB;IAC1D,SAAgB,UAAU,EAAE,YAAY,CAAc;IAEtD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAK;IAE5C;;;;;OAKG;IACH,OAAc,mBAAmB,SAAM;IAEvC,OAAO,CAAC,QAAQ,CAA+B;IAE/C,4EAA4E;IACrE,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIlD;;;;;;;;OAQG;IACU,MAAM,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,WAAW,EAAE,QAAQ,EACrB,gBAAgB,CAAC,EAAE,gBAAgB,GACpC,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAgEjC"}
|
|
@@ -31,9 +31,17 @@ let FullTextSearchProvider = class FullTextSearchProvider extends BaseSearchProv
|
|
|
31
31
|
static { FullTextSearchProvider_1 = this; }
|
|
32
32
|
/**
|
|
33
33
|
* Minimum trimmed term length we accept. SQL Server FTS treats single
|
|
34
|
-
* characters as noise; rejecting them matches the EntitySearchProvider guard.
|
|
34
|
+
* characters as noise; rejecting them matches the EntitySearchProvider guard. Set to 2
|
|
35
|
+
* (was 3) so legitimate short queries aren't silently dropped (bug C3).
|
|
35
36
|
*/
|
|
36
|
-
static { this.MIN_TERM_LENGTH =
|
|
37
|
+
static { this.MIN_TERM_LENGTH = 2; }
|
|
38
|
+
/**
|
|
39
|
+
* Rows to fetch PER ENTITY as the ranking candidate pool — decoupled from the global `topK`
|
|
40
|
+
* budget (bug C3). Previously `topK / 10`, which capped every FTS entity to a tiny arbitrary
|
|
41
|
+
* slice regardless of how many entities matched. The engine still trims the fused set to topK.
|
|
42
|
+
* Public + static so a deployment can tune it at startup. Mirrors EntitySearchProvider.
|
|
43
|
+
*/
|
|
44
|
+
static { this.PerEntityFetchDepth = 15; }
|
|
37
45
|
/** Set the enricher instance. Called by SearchEngine after construction. */
|
|
38
46
|
SetEnricher(enricher) {
|
|
39
47
|
this.enricher = enricher;
|
|
@@ -71,7 +79,7 @@ let FullTextSearchProvider = class FullTextSearchProvider extends BaseSearchProv
|
|
|
71
79
|
const ftsResult = await md.FullTextSearch({
|
|
72
80
|
SearchText: effectiveQuery,
|
|
73
81
|
EntityNames: restrictedEntityNames,
|
|
74
|
-
MaxRowsPerEntity: Math.max(
|
|
82
|
+
MaxRowsPerEntity: Math.min(topK, Math.max(FullTextSearchProvider_1.PerEntityFetchDepth, Math.ceil(topK / 10)))
|
|
75
83
|
}, contextUser);
|
|
76
84
|
if (!ftsResult.Success) {
|
|
77
85
|
LogError(`FullTextSearchProvider: FTS error: ${ftsResult.ErrorMessage}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullTextSearchProvider.js","sourceRoot":"","sources":["../../src/generic/FullTextSearchProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;;;;;;;AAEH,OAAO,EAAoB,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAI7E;;;GAGG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,kBAAkB;IAAvD;;QACa,eAAU,GAAiB,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"FullTextSearchProvider.js","sourceRoot":"","sources":["../../src/generic/FullTextSearchProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Resolves a scope's declared Search Context dimensions.
|
|
3
|
+
*
|
|
4
|
+
* `SearchScope.SearchContextConfig` has always documented `dimensions[]`,
|
|
5
|
+
* `inheritanceMode` and `strictValidation` — but nothing read it. Dimensions therefore
|
|
6
|
+
* arrived as a free-form bag that **any** caller could author, including an LLM writing a
|
|
7
|
+
* tool call: `parseSecondaryScopes` type-cleaned the JSON and handed it straight to the
|
|
8
|
+
* template renderer. A value anyone in the call chain can set is a narrowing convenience,
|
|
9
|
+
* not an access bound, which is why apps that encoded a boundary as a dimension were doing
|
|
10
|
+
* something the platform could not honour.
|
|
11
|
+
*
|
|
12
|
+
* This resolver makes the declaration enforceable:
|
|
13
|
+
*
|
|
14
|
+
* - **`trust: 'ServerDerived'` ⇒ caller values for that key are DISCARDED**, and the value
|
|
15
|
+
* is derived by the engine (an approved `MJ: Queries` row, or a declared default). This is
|
|
16
|
+
* the anti-spoof rule and the reason a dimension can now carry an access decision.
|
|
17
|
+
* - **`valueType` is enforced.** A value failing its grammar REJECTS the search rather than
|
|
18
|
+
* being coerced or silently dropped.
|
|
19
|
+
* - **`freetext` is forbidden on a restricting dimension** — free text interpolated into a
|
|
20
|
+
* filter cannot be made safe by validation; it belongs in the query, not the bound.
|
|
21
|
+
* - **`narrowingOf` is a lattice meet**, so a caller can only ever narrow a server-derived
|
|
22
|
+
* dimension. Never widen.
|
|
23
|
+
* - **`strictValidation` has teeth** — an undeclared caller key rejects the search.
|
|
24
|
+
*
|
|
25
|
+
* Backwards compatibility is the design constraint: a scope whose `SearchContextConfig` is
|
|
26
|
+
* null or has no dimensions is returned **untouched**, so every existing scope behaves
|
|
27
|
+
* exactly as before.
|
|
28
|
+
*
|
|
29
|
+
* @module @memberjunction/search-engine
|
|
30
|
+
*/
|
|
31
|
+
import { UserInfo } from '@memberjunction/core';
|
|
32
|
+
import { MJSearchScopeEntity } from '@memberjunction/core-entities';
|
|
33
|
+
import { SearchContext, SecondaryScopeValue, ScopeSearchContextConfig, ScopeSecondaryDimension, DimensionProvenance, DimensionExplanation, ScopePrincipals, ScopeSupersessionRule } from './search.types.js';
|
|
34
|
+
/** Inputs needed to resolve one scope's dimensions for one search. */
|
|
35
|
+
export interface DimensionResolutionInput {
|
|
36
|
+
Scope: MJSearchScopeEntity;
|
|
37
|
+
/** The context as supplied by the caller — trusted only where a dimension says so. */
|
|
38
|
+
CallerContext: SearchContext | undefined;
|
|
39
|
+
ContextUser: UserInfo;
|
|
40
|
+
/** Principals available to bind into an expansion query. */
|
|
41
|
+
Principals?: ScopePrincipals;
|
|
42
|
+
}
|
|
43
|
+
/** Result of resolving a scope's dimensions. */
|
|
44
|
+
export interface DimensionResolutionResult {
|
|
45
|
+
/** Effective context. For a declared scope this contains RESOLVED dimensions only. */
|
|
46
|
+
Context: SearchContext | undefined;
|
|
47
|
+
/** Human-readable notes (discarded spoof attempts, applied defaults, …) for audit. */
|
|
48
|
+
Diagnostics: string[];
|
|
49
|
+
/**
|
|
50
|
+
* Per-dimension provenance — the structured form of `Diagnostics`.
|
|
51
|
+
*
|
|
52
|
+
* `Diagnostics` is prose for a human reading a log; this is the same information as data,
|
|
53
|
+
* so the explainer and the execution-log writer can record WHO decided each value without
|
|
54
|
+
* re-parsing sentences. Empty for an undeclared scope, which resolves nothing.
|
|
55
|
+
*/
|
|
56
|
+
Provenance: DimensionExplanation[];
|
|
57
|
+
}
|
|
58
|
+
/** Internal outcome of resolving one dimension, carrying its provenance alongside its value. */
|
|
59
|
+
interface DimensionOutcome {
|
|
60
|
+
Value: SecondaryScopeValue | undefined;
|
|
61
|
+
Provenance: DimensionProvenance;
|
|
62
|
+
Note?: string;
|
|
63
|
+
}
|
|
64
|
+
/** Thrown when resolution cannot proceed safely. Callers must fail the search closed. */
|
|
65
|
+
export declare class ScopeDimensionError extends Error {
|
|
66
|
+
constructor(message: string);
|
|
67
|
+
}
|
|
68
|
+
export declare class ScopeDimensionResolver {
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the effective Search Context for a scope.
|
|
71
|
+
*
|
|
72
|
+
* @throws {ScopeDimensionError} when a declared dimension cannot be resolved safely —
|
|
73
|
+
* the caller MUST fail the search rather than proceed with a partial bound.
|
|
74
|
+
*/
|
|
75
|
+
Resolve(input: DimensionResolutionInput): Promise<DimensionResolutionResult>;
|
|
76
|
+
/** Parse the scope's declaration; a malformed config fails closed rather than being ignored. */
|
|
77
|
+
protected parseConfig(scope: MJSearchScopeEntity): ScopeSearchContextConfig | null;
|
|
78
|
+
/**
|
|
79
|
+
* Validate the DECLARATION itself, before any dimension is dispatched.
|
|
80
|
+
*
|
|
81
|
+
* This has to run here rather than inside per-dimension resolution. `advisory` routes to a
|
|
82
|
+
* fail-soft path that deliberately swallows errors, so a contradiction checked *inside* that path
|
|
83
|
+
* would be swallowed too — and the failure mode was the worst available one: a dimension
|
|
84
|
+
* declaring `restricts: true` alongside `advisory: true` was silently given the advisory
|
|
85
|
+
* posture, i.e. a declared boundary quietly became droppable. Found by a test, not by review.
|
|
86
|
+
*/
|
|
87
|
+
protected validateDeclaration(config: ScopeSearchContextConfig, scope: MJSearchScopeEntity): void;
|
|
88
|
+
/** `strictValidation` with teeth — previously this only warned and used the value anyway. */
|
|
89
|
+
protected rejectUndeclaredKeys(config: ScopeSearchContextConfig, declared: Map<string, ScopeSecondaryDimension>, callerScopes: Record<string, SecondaryScopeValue>, scope: MJSearchScopeEntity): void;
|
|
90
|
+
/** Resolve `narrowingOf` targets before their dependents; otherwise declaration order. */
|
|
91
|
+
protected orderByDependency(dimensions: ScopeSecondaryDimension[]): ScopeSecondaryDimension[];
|
|
92
|
+
/**
|
|
93
|
+
* Resolve an advisory (§5.12 supersession) dimension. Never throws.
|
|
94
|
+
*
|
|
95
|
+
* Every failure path here degrades to "no supersession" rather than to a refused search. That
|
|
96
|
+
* asymmetry with {@link resolveOne} is the entire point of the section: entitlement composes by
|
|
97
|
+
* intersection and fails closed; supersession only subtracts and fails soft.
|
|
98
|
+
*/
|
|
99
|
+
protected resolveAdvisory(dim: ScopeSecondaryDimension, callerScopes: Record<string, SecondaryScopeValue>, alreadyResolved: Record<string, SecondaryScopeValue>, input: DimensionResolutionInput, diagnostics: string[]): Promise<DimensionOutcome>;
|
|
100
|
+
/**
|
|
101
|
+
* First rule whose every `when` entry matches. Order in the array IS the precedence order.
|
|
102
|
+
*
|
|
103
|
+
* A set-valued resolved dimension matches by MEMBERSHIP, so an author writes
|
|
104
|
+
* `when: { ActiveSkillIDs: '<exam-writer>' }` without needing to know whether the dimension is
|
|
105
|
+
* scalar or a set. Comparison is case-insensitive: MJ UUID casing is inconsistent, and a rule
|
|
106
|
+
* that never fires because of letter case would be effectively undebuggable.
|
|
107
|
+
*/
|
|
108
|
+
protected firstMatchingRule(rules: ScopeSupersessionRule[], resolved: Record<string, SecondaryScopeValue>): ScopeSupersessionRule | undefined;
|
|
109
|
+
/** Resolve a single dimension, enforcing trust, grammar, narrowing and required-ness. */
|
|
110
|
+
protected resolveOne(dim: ScopeSecondaryDimension, callerScopes: Record<string, SecondaryScopeValue>, alreadyResolved: Record<string, SecondaryScopeValue>, input: DimensionResolutionInput, diagnostics: string[]): Promise<DimensionOutcome>;
|
|
111
|
+
/**
|
|
112
|
+
* Produce a value according to the dimension's TRUST, which is the whole security hinge.
|
|
113
|
+
*
|
|
114
|
+
* `ServerDerived` never merges a caller value — it discards it and derives its own. The discard
|
|
115
|
+
* also wins the provenance label even when a server value replaced it, because an audit needs to
|
|
116
|
+
* see that someone tried; a successful override would otherwise look identical to a quiet run.
|
|
117
|
+
*/
|
|
118
|
+
protected resolveByTrust(dim: ScopeSecondaryDimension, trust: 'CallerSupplied' | 'ServerDerived', callerScopes: Record<string, SecondaryScopeValue>, input: DimensionResolutionInput, diagnostics: string[]): Promise<DimensionOutcome>;
|
|
119
|
+
/**
|
|
120
|
+
* Apply a declared `defaultValue` when nothing resolved.
|
|
121
|
+
*
|
|
122
|
+
* A default may NOT stand in for a restricting dimension: for a bound, "absent" has to mean
|
|
123
|
+
* deny. Allowing a default there would let an author turn a failed derivation into a silent
|
|
124
|
+
* grant, which is the inverse of what the bound is for.
|
|
125
|
+
*/
|
|
126
|
+
protected applyDefaultValue(dim: ScopeSecondaryDimension, restricts: boolean, value: SecondaryScopeValue | undefined, provenance: DimensionProvenance, diagnostics: string[]): DimensionOutcome;
|
|
127
|
+
/** Derive a ServerDerived value: an approved `MJ: Queries` row, else nothing. */
|
|
128
|
+
protected deriveServerValue(dim: ScopeSecondaryDimension, input: DimensionResolutionInput): Promise<SecondaryScopeValue | undefined>;
|
|
129
|
+
/**
|
|
130
|
+
* Meet a caller value against a SET-valued server bound.
|
|
131
|
+
*
|
|
132
|
+
* A scalar caller value is a MEMBERSHIP test — "pick one of the allowed values" — not equality
|
|
133
|
+
* against the set. An earlier version compared the scalar to a stringified array and therefore
|
|
134
|
+
* rejected every legitimate pick, which is why the two shapes are handled apart here.
|
|
135
|
+
*/
|
|
136
|
+
protected meetAgainstSet(dim: ScopeSecondaryDimension, callerValue: SecondaryScopeValue, serverSet: string[], callerIsSet: boolean, widened: (detail: string) => ScopeDimensionError): SecondaryScopeValue;
|
|
137
|
+
/** Enforce the declared grammar. A failure REJECTS — never coerce, never drop-and-continue. */
|
|
138
|
+
protected validateGrammar(dim: ScopeSecondaryDimension, raw: SecondaryScopeValue): SecondaryScopeValue;
|
|
139
|
+
/**
|
|
140
|
+
* Lattice meet — a caller may only NARROW. `set` intersects; `scalar` must match exactly;
|
|
141
|
+
* `opaque` forbids narrowing entirely.
|
|
142
|
+
*/
|
|
143
|
+
protected meet(dim: ScopeSecondaryDimension, callerValue: SecondaryScopeValue, serverValue: SecondaryScopeValue | undefined): SecondaryScopeValue;
|
|
144
|
+
}
|
|
145
|
+
export {};
|
|
146
|
+
//# sourceMappingURL=ScopeDimensionResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeDimensionResolver.d.ts","sourceRoot":"","sources":["../../src/generic/ScopeDimensionResolver.ts"],"names":[],"mappings":"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"}
|