feat(namespace): find's own filter builders speak the frozen keys — params.type/subtype/service become system.* index keys at every construction site (three pipelines + the canonical buildMetadataFilter); the where.type→noun alias is dead (bare 'type' belongs to the user now)
Some checks are pending
CI / Node 22 (push) Waiting to run
CI / Node 24 (push) Waiting to run
CI / Bun (latest) (push) Waiting to run

This commit is contained in:
David Snelling 2026-08-03 15:33:01 -07:00
parent 11c724bc86
commit 7a28a94639

View file

@ -6148,20 +6148,18 @@ export class Brainy<T = any> implements BrainyInterface<T> {
// Build filter for metadata index // Build filter for metadata index
let filter: any = {} let filter: any = {}
if (params.where) { if (params.where) {
// Where keys pass through UNTOUCHED — the addressing law parses
// them at the index boundary. The old where.type→noun alias is
// dead: bare 'type' is the user's own field now.
Object.assign(filter, params.where) Object.assign(filter, params.where)
// Alias: where.type → where.noun (storage field name for entity type)
if ('type' in filter && !('noun' in filter)) {
filter.noun = filter.type
delete filter.type
}
} }
if (params.service) filter.service = params.service if (params.service) filter['system.service'] = params.service
// Subtype (top-level standard field — fast path, not metadata fallback). // Subtype (top-level standard field — fast path, not metadata fallback).
// Must be assigned BEFORE the type-array expansion below so the spread // Must be assigned BEFORE the type-array expansion below so the spread
// into each anyOf branch carries it through. // into each anyOf branch carries it through.
if (params.subtype !== undefined) { if (params.subtype !== undefined) {
filter.subtype = Array.isArray(params.subtype) filter['system.subtype'] = Array.isArray(params.subtype)
? { oneOf: params.subtype } ? { oneOf: params.subtype }
: params.subtype : params.subtype
} }
@ -6169,11 +6167,11 @@ export class Brainy<T = any> implements BrainyInterface<T> {
if (params.type) { if (params.type) {
const types = Array.isArray(params.type) ? params.type : [params.type] const types = Array.isArray(params.type) ? params.type : [params.type]
if (types.length === 1) { if (types.length === 1) {
filter.noun = types[0] filter['system.type'] = types[0]
} else { } else {
filter = { filter = {
anyOf: types.map(type => ({ anyOf: types.map(type => ({
noun: type, 'system.type': type,
...filter ...filter
})) }))
} }
@ -11388,27 +11386,26 @@ export class Brainy<T = any> implements BrainyInterface<T> {
if (params.where || params.subtype || params.service) { if (params.where || params.subtype || params.service) {
let filter: any = {} let filter: any = {}
if (params.where) { if (params.where) {
// Where keys pass through UNTOUCHED — the one addressing law
// parses them at the index boundary (bare = user metadata,
// system.* = engine scalars). The old where.type→noun alias is
// dead: a bare 'type' is the user's own field now.
Object.assign(filter, params.where) Object.assign(filter, params.where)
// Alias: where.type → where.noun (storage field name for entity type)
if ('type' in filter && !('noun' in filter)) {
filter.noun = filter.type
delete filter.type
}
} }
if (params.service) filter.service = params.service if (params.service) filter['system.service'] = params.service
if (params.subtype !== undefined) { if (params.subtype !== undefined) {
filter.subtype = Array.isArray(params.subtype) filter['system.subtype'] = Array.isArray(params.subtype)
? { oneOf: params.subtype } ? { oneOf: params.subtype }
: params.subtype : params.subtype
} }
if (params.type) { if (params.type) {
const types = Array.isArray(params.type) ? params.type : [params.type] const types = Array.isArray(params.type) ? params.type : [params.type]
if (types.length === 1) { if (types.length === 1) {
filter.noun = types[0] filter['system.type'] = types[0]
} else { } else {
const baseFilter = { ...filter } const baseFilter = { ...filter }
filter = { filter = {
anyOf: types.map(type => ({ noun: type, ...baseFilter })) anyOf: types.map(type => ({ 'system.type': type, ...baseFilter }))
} }
} }
} }
@ -11458,27 +11455,24 @@ export class Brainy<T = any> implements BrainyInterface<T> {
// Use MetadataIndexManager for efficient filtered streaming // Use MetadataIndexManager for efficient filtered streaming
let filterObj: any = {} let filterObj: any = {}
if (filter.where) { if (filter.where) {
// Where keys pass through — the addressing law parses them at
// the index boundary; the type→noun alias is dead.
Object.assign(filterObj, filter.where) Object.assign(filterObj, filter.where)
// Alias: where.type → where.noun (storage field name for entity type)
if ('type' in filterObj && !('noun' in filterObj)) {
filterObj.noun = filterObj.type
delete filterObj.type
}
} }
if (filter.service) filterObj.service = filter.service if (filter.service) filterObj['system.service'] = filter.service
if (filter.subtype !== undefined) { if (filter.subtype !== undefined) {
filterObj.subtype = Array.isArray(filter.subtype) filterObj['system.subtype'] = Array.isArray(filter.subtype)
? { oneOf: filter.subtype } ? { oneOf: filter.subtype }
: filter.subtype : filter.subtype
} }
if (filter.type) { if (filter.type) {
const types = Array.isArray(filter.type) ? filter.type : [filter.type] const types = Array.isArray(filter.type) ? filter.type : [filter.type]
if (types.length === 1) { if (types.length === 1) {
filterObj.noun = types[0] filterObj['system.type'] = types[0]
} else { } else {
const baseFilterObj = { ...filterObj } const baseFilterObj = { ...filterObj }
filterObj = { filterObj = {
anyOf: types.map(type => ({ noun: type, ...baseFilterObj })) anyOf: types.map(type => ({ 'system.type': type, ...baseFilterObj }))
} }
} }
} }
@ -13605,14 +13599,12 @@ export class Brainy<T = any> implements BrainyInterface<T> {
} }
let filter: any = {} let filter: any = {}
if (params.where) { if (params.where) {
// Where keys pass through UNTOUCHED — the one addressing law parses
// them at the index boundary (bare = user metadata, system.* = engine
// scalars, typed refusal otherwise). The old type→noun alias is dead.
Object.assign(filter, params.where) Object.assign(filter, params.where)
// Alias: where.type → where.noun (storage field name for entity type)
if ('type' in filter && !('noun' in filter)) {
filter.noun = filter.type
delete filter.type
}
} }
if (params.service) filter.service = params.service if (params.service) filter['system.service'] = params.service
if (params.excludeVFS === true) { if (params.excludeVFS === true) {
filter.vfsType = { exists: false } filter.vfsType = { exists: false }
filter.isVFSEntity = { ne: true } filter.isVFSEntity = { ne: true }
@ -13620,14 +13612,14 @@ export class Brainy<T = any> implements BrainyInterface<T> {
// Subtype (top-level standard field — fast path). Assigned BEFORE the type-array // Subtype (top-level standard field — fast path). Assigned BEFORE the type-array
// expansion below so the spread into each anyOf branch carries it through. // expansion below so the spread into each anyOf branch carries it through.
if (params.subtype !== undefined) { if (params.subtype !== undefined) {
filter.subtype = Array.isArray(params.subtype) ? { oneOf: params.subtype } : params.subtype filter['system.subtype'] = Array.isArray(params.subtype) ? { oneOf: params.subtype } : params.subtype
} }
if (params.type) { if (params.type) {
const types = Array.isArray(params.type) ? params.type : [params.type] const types = Array.isArray(params.type) ? params.type : [params.type]
if (types.length === 1) { if (types.length === 1) {
filter.noun = types[0] filter['system.type'] = types[0]
} else { } else {
filter = { anyOf: types.map((type) => ({ noun: type, ...filter })) } filter = { anyOf: types.map((type) => ({ 'system.type': type, ...filter })) }
} }
} }
return filter return filter