@dxos/echo-pipeline 0.8.4-main.dedc0f3 → 0.8.4-main.e098934
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/lib/browser/{chunk-MBMJB3V7.mjs → chunk-KQYT6ADL.mjs} +52 -2
- package/dist/lib/browser/{chunk-MBMJB3V7.mjs.map → chunk-KQYT6ADL.mjs.map} +3 -3
- package/dist/lib/browser/filter/index.mjs +1 -1
- package/dist/lib/browser/index.mjs +20 -10
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/{chunk-XJZTCD4G.mjs → chunk-W4ACY3YC.mjs} +52 -2
- package/dist/lib/node-esm/{chunk-XJZTCD4G.mjs.map → chunk-W4ACY3YC.mjs.map} +3 -3
- package/dist/lib/node-esm/filter/index.mjs +1 -1
- package/dist/lib/node-esm/index.mjs +20 -10
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/filter/filter-match.d.ts.map +1 -1
- package/dist/types/src/query/errors.d.ts +8 -5
- package/dist/types/src/query/errors.d.ts.map +1 -1
- package/dist/types/src/query/query-planner.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -35
- package/src/filter/filter-match.test.ts +21 -1
- package/src/filter/filter-match.ts +69 -1
- package/src/query/errors.ts +2 -0
- package/src/query/query-planner.ts +13 -8
|
@@ -111,6 +111,30 @@ var filterMatchObjectJSON = (filter, obj) => {
|
|
|
111
111
|
return false;
|
|
112
112
|
}
|
|
113
113
|
};
|
|
114
|
+
var structuralMatch = (filterObj, targetObj, strict = true) => {
|
|
115
|
+
if (typeof filterObj !== "object" || filterObj === null) {
|
|
116
|
+
return filterObj === targetObj;
|
|
117
|
+
}
|
|
118
|
+
if (typeof targetObj !== "object" || targetObj === null) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const filterKeys = Object.keys(filterObj);
|
|
122
|
+
const targetKeys = Object.keys(targetObj);
|
|
123
|
+
if (strict && filterKeys.length !== targetKeys.length) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return filterKeys.every((key) => {
|
|
127
|
+
if (!(key in targetObj)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
const filterValue = filterObj[key];
|
|
131
|
+
const targetValue = targetObj[key];
|
|
132
|
+
if (typeof filterValue === "object" && filterValue !== null) {
|
|
133
|
+
return structuralMatch(filterValue, targetValue);
|
|
134
|
+
}
|
|
135
|
+
return filterValue === targetValue;
|
|
136
|
+
});
|
|
137
|
+
};
|
|
114
138
|
var filterMatchValue = (filter, value) => {
|
|
115
139
|
switch (filter.type) {
|
|
116
140
|
case "compare": {
|
|
@@ -134,12 +158,38 @@ var filterMatchValue = (filter, value) => {
|
|
|
134
158
|
return value < compareValue;
|
|
135
159
|
case "lte":
|
|
136
160
|
return value <= compareValue;
|
|
161
|
+
default:
|
|
162
|
+
return false;
|
|
137
163
|
}
|
|
138
|
-
|
|
164
|
+
}
|
|
165
|
+
case "object": {
|
|
166
|
+
if (typeof value !== "object" || value === null) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
if (filter.props) {
|
|
170
|
+
for (const [key, valueFilter] of Object.entries(filter.props)) {
|
|
171
|
+
const nestedValue = value[key];
|
|
172
|
+
if (!filterMatchValue(valueFilter, nestedValue)) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
139
178
|
}
|
|
140
179
|
case "in": {
|
|
141
180
|
return filter.values.includes(value);
|
|
142
181
|
}
|
|
182
|
+
case "contains": {
|
|
183
|
+
if (!Array.isArray(value)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return value.some((element) => {
|
|
187
|
+
if (typeof filter.value === "object" && filter.value !== null && !Array.isArray(filter.value)) {
|
|
188
|
+
return structuralMatch(filter.value, element);
|
|
189
|
+
}
|
|
190
|
+
return element === filter.value;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
143
193
|
case "range": {
|
|
144
194
|
return value >= filter.from && value <= filter.to;
|
|
145
195
|
}
|
|
@@ -179,4 +229,4 @@ export {
|
|
|
179
229
|
filterMatchObjectJSON,
|
|
180
230
|
filterMatchValue
|
|
181
231
|
};
|
|
182
|
-
//# sourceMappingURL=chunk-
|
|
232
|
+
//# sourceMappingURL=chunk-KQYT6ADL.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/filter/filter-match.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type ObjectStructure, type QueryAST, decodeReference, isEncodedReference } from '@dxos/echo-protocol';\nimport { EXPANDO_TYPENAME, type ObjectJSON } from '@dxos/echo-schema';\nimport { DXN, type ObjectId, type SpaceId } from '@dxos/keys';\n\nexport type MatchedObject = {\n id: ObjectId;\n spaceId: SpaceId;\n doc: ObjectStructure;\n};\n\n/**\n * Matches an object against a filter AST.\n * @param obj object structure as stored in automerge.\n */\nexport const filterMatchObject = (filter: QueryAST.Filter, obj: MatchedObject): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj.doc.system?.type?.['/']) {\n // Objects with no type are considered to be expando objects\n const expectedDXN = DXN.parse(filter.typename).asTypeDXN();\n if (expectedDXN?.type !== EXPANDO_TYPENAME) {\n return false;\n }\n } else {\n const actualDXN = DXN.parse(obj.doc.system.type['/']);\n const expectedDXN = DXN.parse(filter.typename);\n\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n const value = obj.doc.data[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj.doc.meta.keys.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'text-search': {\n // TODO: Implement text search\n return false;\n }\n\n case 'not': {\n return !filterMatchObject(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObject(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObject(f, obj));\n }\n\n default:\n return false;\n }\n};\n\nexport const filterMatchObjectJSON = (filter: QueryAST.Filter, obj: ObjectJSON): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj['@type']) {\n // Objects with no type are considered to be expando objects\n const expectedDXN = DXN.parse(filter.typename).asTypeDXN();\n if (expectedDXN?.type !== EXPANDO_TYPENAME) {\n return false;\n }\n } else {\n const actualDXN = DXN.parse(obj['@type']);\n const expectedDXN = DXN.parse(filter.typename);\n\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n if (key.startsWith('@')) {\n // ignore meta properties\n continue;\n }\n const value = (obj as any)[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj['@meta']?.keys?.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'text-search': {\n // TODO: Implement text search\n return false;\n }\n\n case 'not': {\n return !filterMatchObjectJSON(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObjectJSON(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObjectJSON(f, obj));\n }\n\n default:\n return false;\n }\n};\n\nexport const filterMatchValue = (filter: QueryAST.Filter, value: unknown): boolean => {\n switch (filter.type) {\n case 'compare': {\n const compareValue = filter.value as any;\n switch (filter.operator) {\n case 'eq':\n if (isEncodedReference(compareValue)) {\n if (!isEncodedReference(value)) {\n return false;\n }\n return DXN.equals(decodeReference(value).toDXN(), decodeReference(compareValue).toDXN());\n }\n return value === compareValue;\n case 'neq':\n return value !== compareValue;\n case 'gt':\n return (value as any) > compareValue;\n case 'gte':\n return (value as any) >= compareValue;\n case 'lt':\n return (value as any) < compareValue;\n case 'lte':\n return (value as any) <= compareValue;\n }\n
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["decodeReference", "isEncodedReference", "EXPANDO_TYPENAME", "DXN", "filterMatchObject", "filter", "obj", "type", "typename", "doc", "system", "expectedDXN", "DXN", "parse", "asTypeDXN", "EXPANDO_TYPENAME", "actualDXN", "compareTypename", "id", "length", "includes", "props", "key", "valueFilter", "Object", "entries", "value", "data", "filterMatchValue", "foreignKeys", "hasMatchingKey", "some", "filterKey", "meta", "keys", "objKey", "source", "filters", "every", "f", "filterMatchObjectJSON", "startsWith", "compareValue", "operator", "isEncodedReference", "equals", "decodeReference", "toDXN", "values", "from", "to", "expectedTypeDXN", "actualTypeDXN", "version", "undefined"]
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type ObjectStructure, type QueryAST, decodeReference, isEncodedReference } from '@dxos/echo-protocol';\nimport { EXPANDO_TYPENAME, type ObjectJSON } from '@dxos/echo-schema';\nimport { DXN, type ObjectId, type SpaceId } from '@dxos/keys';\n\nexport type MatchedObject = {\n id: ObjectId;\n spaceId: SpaceId;\n doc: ObjectStructure;\n};\n\n/**\n * Matches an object against a filter AST.\n * @param obj object structure as stored in automerge.\n */\nexport const filterMatchObject = (filter: QueryAST.Filter, obj: MatchedObject): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj.doc.system?.type?.['/']) {\n // Objects with no type are considered to be expando objects\n const expectedDXN = DXN.parse(filter.typename).asTypeDXN();\n if (expectedDXN?.type !== EXPANDO_TYPENAME) {\n return false;\n }\n } else {\n const actualDXN = DXN.parse(obj.doc.system.type['/']);\n const expectedDXN = DXN.parse(filter.typename);\n\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n const value = obj.doc.data[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj.doc.meta.keys.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'text-search': {\n // TODO: Implement text search\n return false;\n }\n\n case 'not': {\n return !filterMatchObject(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObject(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObject(f, obj));\n }\n\n default:\n return false;\n }\n};\n\nexport const filterMatchObjectJSON = (filter: QueryAST.Filter, obj: ObjectJSON): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj['@type']) {\n // Objects with no type are considered to be expando objects\n const expectedDXN = DXN.parse(filter.typename).asTypeDXN();\n if (expectedDXN?.type !== EXPANDO_TYPENAME) {\n return false;\n }\n } else {\n const actualDXN = DXN.parse(obj['@type']);\n const expectedDXN = DXN.parse(filter.typename);\n\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n if (key.startsWith('@')) {\n // ignore meta properties\n continue;\n }\n const value = (obj as any)[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj['@meta']?.keys?.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'text-search': {\n // TODO: Implement text search\n return false;\n }\n\n case 'not': {\n return !filterMatchObjectJSON(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObjectJSON(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObjectJSON(f, obj));\n }\n\n default:\n return false;\n }\n};\n\n/**\n * Performs structural matching between a filter object and a target object.\n * This handles nested object comparison for array matching scenarios.\n */\n// TODO(wittjosiah): Add ast support for non-strict matching.\nconst structuralMatch = (filterObj: any, targetObj: any, strict = true): boolean => {\n if (typeof filterObj !== 'object' || filterObj === null) {\n return filterObj === targetObj;\n }\n\n if (typeof targetObj !== 'object' || targetObj === null) {\n return false;\n }\n\n // Prohibit extra keys in targetObj.\n const filterKeys = Object.keys(filterObj);\n const targetKeys = Object.keys(targetObj);\n if (strict && filterKeys.length !== targetKeys.length) {\n return false;\n }\n\n return filterKeys.every((key) => {\n if (!(key in targetObj)) {\n return false;\n }\n const filterValue = filterObj[key];\n const targetValue = targetObj[key];\n\n if (typeof filterValue === 'object' && filterValue !== null) {\n return structuralMatch(filterValue, targetValue);\n }\n\n return filterValue === targetValue;\n });\n};\n\nexport const filterMatchValue = (filter: QueryAST.Filter, value: unknown): boolean => {\n switch (filter.type) {\n case 'compare': {\n const compareValue = filter.value as any;\n switch (filter.operator) {\n case 'eq':\n if (isEncodedReference(compareValue)) {\n if (!isEncodedReference(value)) {\n return false;\n }\n return DXN.equals(decodeReference(value).toDXN(), decodeReference(compareValue).toDXN());\n }\n return value === compareValue;\n case 'neq':\n return value !== compareValue;\n case 'gt':\n return (value as any) > compareValue;\n case 'gte':\n return (value as any) >= compareValue;\n case 'lt':\n return (value as any) < compareValue;\n case 'lte':\n return (value as any) <= compareValue;\n default:\n return false;\n }\n }\n case 'object': {\n // Handle nested object filters for property matching\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n const nestedValue = (value as any)[key];\n if (!filterMatchValue(valueFilter, nestedValue)) {\n return false;\n }\n }\n }\n\n return true;\n }\n case 'in': {\n return filter.values.includes(value);\n }\n case 'contains': {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.some((element) => {\n if (typeof filter.value === 'object' && filter.value !== null && !Array.isArray(filter.value)) {\n return structuralMatch(filter.value, element);\n }\n\n return element === filter.value;\n });\n }\n case 'range': {\n return (value as any) >= filter.from && (value as any) <= filter.to;\n }\n case 'not': {\n return !filterMatchValue(filter.filter, value);\n }\n case 'and': {\n return filter.filters.every((f) => filterMatchValue(f, value));\n }\n case 'or': {\n return filter.filters.some((f) => filterMatchValue(f, value));\n }\n default:\n return false;\n }\n};\n\n/**\n * Compares typename DXNs.\n * @returns true if they match\n *\n * Compares typename string.\n * Missing version (on either actual or expected) matches any version.\n * non `type` DXNs are compared exactly.\n *\n * Examples: (expected) (actual)\n *\n * dxn:type:example.org/type/Task !== dxn:type:example.org/type/Contact\n * dxn:type:example.org/type/Task === dxn:type:example.org/type/Task\n * dxn:type:example.org/type/Task:0.1.0 !== dxn:type:example.org/type/Task:0.2.0\n * dxn:type:example.org/type/Task === dxn:type:example.org/type/Task:0.1.0\n * dxn:type:example.org/type/Task:0.1.0 === dxn:type:example.org/type/Task\n *\n */\nconst compareTypename = (expectedDXN: DXN, actualDXN: DXN): boolean => {\n const expectedTypeDXN = expectedDXN.asTypeDXN();\n if (expectedTypeDXN) {\n const actualTypeDXN = actualDXN.asTypeDXN();\n if (!actualTypeDXN) {\n return false;\n }\n if (\n actualTypeDXN.type !== expectedTypeDXN.type ||\n (expectedTypeDXN.version !== undefined &&\n actualTypeDXN.version !== undefined &&\n actualTypeDXN.version !== expectedTypeDXN.version)\n ) {\n return false;\n }\n } else {\n if (!DXN.equals(actualDXN, expectedDXN)) {\n return false;\n }\n }\n return true;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["decodeReference", "isEncodedReference", "EXPANDO_TYPENAME", "DXN", "filterMatchObject", "filter", "obj", "type", "typename", "doc", "system", "expectedDXN", "DXN", "parse", "asTypeDXN", "EXPANDO_TYPENAME", "actualDXN", "compareTypename", "id", "length", "includes", "props", "key", "valueFilter", "Object", "entries", "value", "data", "filterMatchValue", "foreignKeys", "hasMatchingKey", "some", "filterKey", "meta", "keys", "objKey", "source", "filters", "every", "f", "filterMatchObjectJSON", "startsWith", "structuralMatch", "filterObj", "targetObj", "strict", "filterKeys", "targetKeys", "filterValue", "targetValue", "compareValue", "operator", "isEncodedReference", "equals", "decodeReference", "toDXN", "nestedValue", "values", "Array", "isArray", "element", "from", "to", "expectedTypeDXN", "actualTypeDXN", "version", "undefined"]
|
|
7
7
|
}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
filterMatchObject,
|
|
4
4
|
filterMatchObjectJSON,
|
|
5
5
|
filterMatchValue
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KQYT6ADL.mjs";
|
|
7
7
|
import {
|
|
8
8
|
AuthExtension,
|
|
9
9
|
AuthStatus,
|
|
@@ -2937,6 +2937,8 @@ import { invariant as invariant9 } from "@dxos/invariant";
|
|
|
2937
2937
|
import { BaseError } from "@dxos/errors";
|
|
2938
2938
|
var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
2939
2939
|
};
|
|
2940
|
+
var InvalidQueryError = class extends QueryError.extend("INVALID_QUERY") {
|
|
2941
|
+
};
|
|
2940
2942
|
|
|
2941
2943
|
// src/query/plan.ts
|
|
2942
2944
|
(function(QueryPlan2) {
|
|
@@ -3011,7 +3013,8 @@ var QueryPlanner = class {
|
|
|
3011
3013
|
case "order":
|
|
3012
3014
|
return this._generateOrderClause(query, context);
|
|
3013
3015
|
default:
|
|
3014
|
-
throw new QueryError(
|
|
3016
|
+
throw new QueryError({
|
|
3017
|
+
message: `Unsupported query type: ${query.type}`,
|
|
3015
3018
|
context: {
|
|
3016
3019
|
query: context.originalQuery
|
|
3017
3020
|
}
|
|
@@ -3047,7 +3050,8 @@ var QueryPlanner = class {
|
|
|
3047
3050
|
]);
|
|
3048
3051
|
}
|
|
3049
3052
|
if (context.selectionInverted) {
|
|
3050
|
-
throw new QueryError(
|
|
3053
|
+
throw new QueryError({
|
|
3054
|
+
message: "Query too complex",
|
|
3051
3055
|
context: {
|
|
3052
3056
|
query: context.originalQuery
|
|
3053
3057
|
}
|
|
@@ -3128,19 +3132,22 @@ var QueryPlanner = class {
|
|
|
3128
3132
|
]);
|
|
3129
3133
|
}
|
|
3130
3134
|
case "compare":
|
|
3131
|
-
throw new QueryError(
|
|
3135
|
+
throw new QueryError({
|
|
3136
|
+
message: "Query too complex",
|
|
3132
3137
|
context: {
|
|
3133
3138
|
query: context.originalQuery
|
|
3134
3139
|
}
|
|
3135
3140
|
});
|
|
3136
3141
|
case "in":
|
|
3137
|
-
throw new QueryError(
|
|
3142
|
+
throw new QueryError({
|
|
3143
|
+
message: "Query too complex",
|
|
3138
3144
|
context: {
|
|
3139
3145
|
query: context.originalQuery
|
|
3140
3146
|
}
|
|
3141
3147
|
});
|
|
3142
3148
|
case "range":
|
|
3143
|
-
throw new QueryError(
|
|
3149
|
+
throw new QueryError({
|
|
3150
|
+
message: "Query too complex",
|
|
3144
3151
|
context: {
|
|
3145
3152
|
query: context.originalQuery
|
|
3146
3153
|
}
|
|
@@ -3151,7 +3158,8 @@ var QueryPlanner = class {
|
|
|
3151
3158
|
selectionInverted: !context.selectionInverted
|
|
3152
3159
|
});
|
|
3153
3160
|
case "and":
|
|
3154
|
-
throw new QueryError(
|
|
3161
|
+
throw new QueryError({
|
|
3162
|
+
message: "Query too complex",
|
|
3155
3163
|
context: {
|
|
3156
3164
|
query: context.originalQuery
|
|
3157
3165
|
}
|
|
@@ -3161,7 +3169,7 @@ var QueryPlanner = class {
|
|
|
3161
3169
|
const typenames = filter.filters.map((f) => {
|
|
3162
3170
|
invariant9(f.type === "object" && f.typename !== null, void 0, {
|
|
3163
3171
|
F: __dxlog_file10,
|
|
3164
|
-
L:
|
|
3172
|
+
L: 199,
|
|
3165
3173
|
S: this,
|
|
3166
3174
|
A: [
|
|
3167
3175
|
"f.type === 'object' && f.typename !== null",
|
|
@@ -3183,14 +3191,16 @@ var QueryPlanner = class {
|
|
|
3183
3191
|
...this._generateDeletedHandlingSteps(context)
|
|
3184
3192
|
]);
|
|
3185
3193
|
} else {
|
|
3186
|
-
throw new QueryError(
|
|
3194
|
+
throw new QueryError({
|
|
3195
|
+
message: "Query too complex",
|
|
3187
3196
|
context: {
|
|
3188
3197
|
query: context.originalQuery
|
|
3189
3198
|
}
|
|
3190
3199
|
});
|
|
3191
3200
|
}
|
|
3192
3201
|
default:
|
|
3193
|
-
throw new QueryError(
|
|
3202
|
+
throw new QueryError({
|
|
3203
|
+
message: `Unsupported filter type: ${filter.type}`,
|
|
3194
3204
|
context: {
|
|
3195
3205
|
query: context.originalQuery
|
|
3196
3206
|
}
|