@object-ui/data-objectstack 16.0.0 → 17.1.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/CHANGELOG.md +711 -0
- package/README.md +63 -0
- package/dist/index.cjs +1425 -949
- package/dist/index.d.cts +319 -19
- package/dist/index.d.ts +319 -19
- package/dist/index.js +1420 -949
- package/package.json +5 -4
- package/src/aggregate-capability.test.ts +177 -0
- package/src/exportDownload.test.ts +51 -3
- package/src/filter-entry-translation.test.ts +360 -0
- package/src/filter-operator-ast-parity.test.ts +71 -0
- package/src/index.ts +984 -220
- package/src/integration.ts +8 -0
- package/src/listViews.test.ts +97 -0
- package/src/metadata-client.test.ts +8 -0
- package/src/metadata-client.ts +9 -0
- package/src/onMutation.test.ts +296 -31
- package/src/onWriteWarning.test.ts +172 -0
- package/src/orderby-serialization.test.ts +115 -0
- package/src/queryDataset.test.ts +50 -1
- package/src/searchAll.test.ts +120 -0
- package/src/userState.test.ts +25 -4
- package/src/userState.ts +10 -6
- package/src/validation-error.test.ts +94 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Adapter operator table → filter-AST parity (#2901, objectstack#3948).
|
|
11
|
+
*
|
|
12
|
+
* `FILTER_OPERATOR_ALIASES` is the last translation a filter passes through
|
|
13
|
+
* before it goes on the wire, and `normalizeFilterOperator` ends in `?? op` —
|
|
14
|
+
* an unmapped operator is emitted verbatim. The server then rejects the shape
|
|
15
|
+
* at `isFilterAST()`, passes the array through unconverted, and driver-sql
|
|
16
|
+
* skips it entirely: **no WHERE clause, no error, every row returned.**
|
|
17
|
+
*
|
|
18
|
+
* So a missing row in this table is not a validation failure, it is an
|
|
19
|
+
* unfiltered query. `before`/`after` — canonical members of the spec's
|
|
20
|
+
* `VIEW_FILTER_OPERATORS` — were missing, which is exactly how a stored
|
|
21
|
+
* "close_date before X" view came back unfiltered.
|
|
22
|
+
*
|
|
23
|
+
* These tests pin the table against the spec vocabularies in both directions.
|
|
24
|
+
*/
|
|
25
|
+
import { describe, it, expect } from 'vitest';
|
|
26
|
+
import { VALID_AST_OPERATORS } from '@objectstack/spec/data';
|
|
27
|
+
import { VIEW_FILTER_OPERATORS } from '@objectstack/spec/ui';
|
|
28
|
+
import { FILTER_OPERATOR_ALIASES } from './index';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* View operators this adapter is not the bridge for — the value-shape ones the
|
|
32
|
+
* view layer resolves to a null comparison before an operator is ever emitted.
|
|
33
|
+
*/
|
|
34
|
+
const NOT_THIS_ADAPTERS_JOB = new Set(['is_empty', 'is_not_empty']);
|
|
35
|
+
|
|
36
|
+
describe('FILTER_OPERATOR_ALIASES lands inside the spec AST vocabulary', () => {
|
|
37
|
+
it('reads both vocabularies from the spec', () => {
|
|
38
|
+
expect(VIEW_FILTER_OPERATORS.length).toBeGreaterThan(0);
|
|
39
|
+
expect(VALID_AST_OPERATORS.size).toBeGreaterThan(0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('every alias target is an operator the AST gate accepts', () => {
|
|
43
|
+
const bad = Object.entries(FILTER_OPERATOR_ALIASES)
|
|
44
|
+
.filter(([, target]) => !VALID_AST_OPERATORS.has(String(target).toLowerCase()))
|
|
45
|
+
.map(([alias, target]) => `${alias} → ${target}`);
|
|
46
|
+
expect(
|
|
47
|
+
bad,
|
|
48
|
+
'these aliases translate to operators VALID_AST_OPERATORS rejects, so the '
|
|
49
|
+
+ 'server drops the filter silently instead of erroring',
|
|
50
|
+
).toEqual([]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('covers every canonical view operator the spec defines', () => {
|
|
54
|
+
const uncovered = VIEW_FILTER_OPERATORS
|
|
55
|
+
.filter((op) => !NOT_THIS_ADAPTERS_JOB.has(op))
|
|
56
|
+
.filter((op) => {
|
|
57
|
+
const target = FILTER_OPERATOR_ALIASES[op] ?? op;
|
|
58
|
+
return !VALID_AST_OPERATORS.has(String(target).toLowerCase());
|
|
59
|
+
});
|
|
60
|
+
expect(
|
|
61
|
+
uncovered,
|
|
62
|
+
'an author can declare these on a ViewFilterRule and the spec validates them, '
|
|
63
|
+
+ 'but they reach the wire unmapped and the filter is silently dropped',
|
|
64
|
+
).toEqual([]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('maps the date comparisons that regressed', () => {
|
|
68
|
+
expect(FILTER_OPERATOR_ALIASES.before).toBe('<');
|
|
69
|
+
expect(FILTER_OPERATOR_ALIASES.after).toBe('>');
|
|
70
|
+
});
|
|
71
|
+
});
|