@tablecraft/engine 0.1.4 → 0.1.5
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/core/cursorPagination.d.ts +7 -1
- package/dist/core/cursorPagination.d.ts.map +1 -1
- package/dist/core/cursorPagination.js +77 -12
- package/dist/core/cursorPagination.js.map +1 -1
- package/dist/core/fieldSelector.d.ts.map +1 -1
- package/dist/core/fieldSelector.js +7 -1
- package/dist/core/fieldSelector.js.map +1 -1
- package/dist/core/filterBuilder.d.ts.map +1 -1
- package/dist/core/filterBuilder.js +2 -41
- package/dist/core/filterBuilder.js.map +1 -1
- package/dist/core/inputValidator.d.ts.map +1 -1
- package/dist/core/inputValidator.js +11 -25
- package/dist/core/inputValidator.js.map +1 -1
- package/dist/core/metadataBuilder.d.ts.map +1 -1
- package/dist/core/metadataBuilder.js +9 -4
- package/dist/core/metadataBuilder.js.map +1 -1
- package/dist/core/sortBuilder.d.ts +2 -1
- package/dist/core/sortBuilder.d.ts.map +1 -1
- package/dist/core/sortBuilder.js +29 -12
- package/dist/core/sortBuilder.js.map +1 -1
- package/dist/core/subqueryBuilder.d.ts +7 -1
- package/dist/core/subqueryBuilder.d.ts.map +1 -1
- package/dist/core/subqueryBuilder.js +25 -7
- package/dist/core/subqueryBuilder.js.map +1 -1
- package/dist/define.d.ts +9 -0
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +47 -10
- package/dist/define.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +26 -3
- package/dist/engine.js.map +1 -1
- package/dist/utils/joinUtils.d.ts +7 -0
- package/dist/utils/joinUtils.d.ts.map +1 -1
- package/dist/utils/joinUtils.js +33 -0
- package/dist/utils/joinUtils.js.map +1 -1
- package/package.json +9 -9
- package/LICENSE +0 -21
|
@@ -11,10 +11,14 @@ export interface CursorMeta {
|
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Cursor-based pagination.
|
|
14
|
-
* Uses the sort column
|
|
14
|
+
* Uses the sort column values as the cursor instead of OFFSET.
|
|
15
15
|
* O(1) performance regardless of page depth.
|
|
16
16
|
*
|
|
17
17
|
* Cursor format: base64({ field: value, field2: value2 })
|
|
18
|
+
*
|
|
19
|
+
* Multi-column sort: the WHERE clause uses ALL sort fields in a
|
|
20
|
+
* row-value comparison to avoid duplicate/skipped rows when rows
|
|
21
|
+
* share the same primary sort value.
|
|
18
22
|
*/
|
|
19
23
|
export declare class CursorPaginationBuilder {
|
|
20
24
|
private schema;
|
|
@@ -25,6 +29,8 @@ export declare class CursorPaginationBuilder {
|
|
|
25
29
|
build(config: TableConfig, cursor: string | undefined, pageSize: number, sort?: SortConfig[], sqlExpressions?: Map<string, SQL>): CursorResult;
|
|
26
30
|
/**
|
|
27
31
|
* From the fetched data (with 1 extra row), determine next cursor.
|
|
32
|
+
* The cursor encodes ALL sort field values from the last row so the
|
|
33
|
+
* compound WHERE condition can be reconstructed on the next request.
|
|
28
34
|
*/
|
|
29
35
|
buildMeta(data: Record<string, unknown>[], pageSize: number, sort?: SortConfig[]): {
|
|
30
36
|
data: Record<string, unknown>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursorPagination.d.ts","sourceRoot":"","sources":["../../src/core/cursorPagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"cursorPagination.d.ts","sourceRoot":"","sources":["../../src/core/cursorPagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,EAAmD,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,GAAG,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAuB;IACtB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;OAEG;IACH,KAAK,CACH,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,UAAU,EAAE,EACnB,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAChC,YAAY;IA2Gf;;;;OAIG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,UAAU,EAAE,GAClB;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE;CAuBzD;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAO3E"}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getTableColumns, gt, lt, eq, and, or, asc, desc } from 'drizzle-orm';
|
|
2
|
+
import { FieldError } from '../errors';
|
|
2
3
|
/**
|
|
3
4
|
* Cursor-based pagination.
|
|
4
|
-
* Uses the sort column
|
|
5
|
+
* Uses the sort column values as the cursor instead of OFFSET.
|
|
5
6
|
* O(1) performance regardless of page depth.
|
|
6
7
|
*
|
|
7
8
|
* Cursor format: base64({ field: value, field2: value2 })
|
|
9
|
+
*
|
|
10
|
+
* Multi-column sort: the WHERE clause uses ALL sort fields in a
|
|
11
|
+
* row-value comparison to avoid duplicate/skipped rows when rows
|
|
12
|
+
* share the same primary sort value.
|
|
8
13
|
*/
|
|
9
14
|
export class CursorPaginationBuilder {
|
|
10
15
|
schema;
|
|
@@ -26,7 +31,8 @@ export class CursorPaginationBuilder {
|
|
|
26
31
|
: config.defaultSort?.length
|
|
27
32
|
? config.defaultSort
|
|
28
33
|
: [{ field: 'id', order: 'asc' }];
|
|
29
|
-
// Build ORDER BY
|
|
34
|
+
// Build ORDER BY — throw a FieldError for unknown fields instead of
|
|
35
|
+
// injecting unvalidated raw SQL identifiers.
|
|
30
36
|
const orderBy = sortFields.map((s) => {
|
|
31
37
|
const col = columns[s.field];
|
|
32
38
|
if (col) {
|
|
@@ -36,19 +42,69 @@ export class CursorPaginationBuilder {
|
|
|
36
42
|
const expr = sqlExpressions.get(s.field);
|
|
37
43
|
return s.order === 'desc' ? desc(expr) : asc(expr);
|
|
38
44
|
}
|
|
39
|
-
|
|
45
|
+
// Previously fell back to sql.identifier(s.field) — an unvalidated raw
|
|
46
|
+
// SQL identifier that bypasses all whitelist checks. Throw instead so
|
|
47
|
+
// the developer gets a clear, actionable error rather than a DB crash.
|
|
48
|
+
throw new FieldError(s.field, `cannot be used for cursor pagination: not a known column or SQL expression`);
|
|
40
49
|
});
|
|
41
50
|
// Decode cursor and build WHERE
|
|
51
|
+
// Uses ALL sort fields (compound cursor) so that rows sharing the same
|
|
52
|
+
// primary sort value are not duplicated or skipped across pages.
|
|
53
|
+
//
|
|
54
|
+
// For ORDER BY col1 ASC, col2 ASC with cursor (v1, v2), the correct
|
|
55
|
+
// continuation is a lexicographic OR-expansion:
|
|
56
|
+
//
|
|
57
|
+
// (col1 > v1)
|
|
58
|
+
// OR (col1 = v1 AND col2 > v2)
|
|
59
|
+
// OR (col1 = v1 AND col2 = v2 AND col3 > v3)
|
|
60
|
+
// ...
|
|
61
|
+
//
|
|
62
|
+
// A flat AND (col1 > v1 AND col2 > v2) is WRONG — it would skip rows
|
|
63
|
+
// where col1 = v1 and col2 > v2 (same primary sort value, later secondary).
|
|
42
64
|
let whereCondition;
|
|
43
65
|
if (cursor) {
|
|
44
66
|
const decoded = decodeCursor(cursor);
|
|
45
67
|
if (decoded && sortFields.length > 0) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
// Collect resolvable sort fields from base columns OR sqlExpressions
|
|
69
|
+
// (computed/subquery sort fields can participate in cursor continuation)
|
|
70
|
+
const resolvable = sortFields
|
|
71
|
+
.map((s) => {
|
|
72
|
+
const col = columns[s.field];
|
|
73
|
+
const expr = sqlExpressions?.get(s.field);
|
|
74
|
+
return { s, col, expr };
|
|
75
|
+
})
|
|
76
|
+
.filter(({ s, col, expr }) => (col !== undefined || expr !== undefined) && decoded[s.field] != null);
|
|
77
|
+
if (resolvable.length === 1) {
|
|
78
|
+
// Single field — simple gt/lt
|
|
79
|
+
const { s, col, expr } = resolvable[0];
|
|
80
|
+
const target = col ?? expr;
|
|
81
|
+
whereCondition = s.order === 'desc'
|
|
82
|
+
? lt(target, decoded[s.field])
|
|
83
|
+
: gt(target, decoded[s.field]);
|
|
84
|
+
}
|
|
85
|
+
else if (resolvable.length > 1) {
|
|
86
|
+
// Multi-field: build the lexicographic OR-expansion
|
|
87
|
+
// Each "arm" of the OR is: (prefix equality conditions) AND (advance condition)
|
|
88
|
+
const orArms = [];
|
|
89
|
+
for (let i = 0; i < resolvable.length; i++) {
|
|
90
|
+
const { s, col, expr } = resolvable[i];
|
|
91
|
+
const target = col ?? expr;
|
|
92
|
+
const advance = s.order === 'desc'
|
|
93
|
+
? lt(target, decoded[s.field])
|
|
94
|
+
: gt(target, decoded[s.field]);
|
|
95
|
+
if (i === 0) {
|
|
96
|
+
// First arm: just the advance condition on col1
|
|
97
|
+
orArms.push(advance);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Remaining arms: prefix equality on cols 0..i-1, advance on col i
|
|
101
|
+
const prefixEqs = resolvable
|
|
102
|
+
.slice(0, i)
|
|
103
|
+
.map(({ s: ps, col: pc, expr: pe }) => eq(pc ?? pe, decoded[ps.field]));
|
|
104
|
+
orArms.push(and(...prefixEqs, advance));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
whereCondition = or(...orArms);
|
|
52
108
|
}
|
|
53
109
|
}
|
|
54
110
|
}
|
|
@@ -61,6 +117,8 @@ export class CursorPaginationBuilder {
|
|
|
61
117
|
}
|
|
62
118
|
/**
|
|
63
119
|
* From the fetched data (with 1 extra row), determine next cursor.
|
|
120
|
+
* The cursor encodes ALL sort field values from the last row so the
|
|
121
|
+
* compound WHERE condition can be reconstructed on the next request.
|
|
64
122
|
*/
|
|
65
123
|
buildMeta(data, pageSize, sort) {
|
|
66
124
|
const hasMore = data.length > pageSize;
|
|
@@ -68,8 +126,15 @@ export class CursorPaginationBuilder {
|
|
|
68
126
|
let nextCursor = null;
|
|
69
127
|
if (hasMore && trimmed.length > 0) {
|
|
70
128
|
const lastRow = trimmed[trimmed.length - 1];
|
|
71
|
-
|
|
72
|
-
|
|
129
|
+
// Encode ALL sort field values so the compound cursor WHERE is complete
|
|
130
|
+
const sortFields = sort?.length ? sort : [{ field: 'id', order: 'asc' }];
|
|
131
|
+
const cursorValues = {};
|
|
132
|
+
for (const s of sortFields) {
|
|
133
|
+
if (lastRow[s.field] != null) {
|
|
134
|
+
cursorValues[s.field] = lastRow[s.field];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
nextCursor = encodeCursor(cursorValues);
|
|
73
138
|
}
|
|
74
139
|
return {
|
|
75
140
|
data: trimmed,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursorPagination.js","sourceRoot":"","sources":["../../src/core/cursorPagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,
|
|
1
|
+
{"version":3,"file":"cursorPagination.js","sourceRoot":"","sources":["../../src/core/cursorPagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldSelector.d.ts","sourceRoot":"","sources":["../../src/core/fieldSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"fieldSelector.d.ts","sourceRoot":"","sources":["../../src/core/fieldSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C;;;GAGG;AACH,qBAAa,aAAa;IACxB;;;OAGG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,EACvC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,MAAM,EAAE,WAAW,GAClB,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC;IAiC/B;;;OAGG;IACH,oBAAoB,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;CAe7B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { collectSelectableJoinFields } from '../utils/joinUtils';
|
|
1
2
|
/**
|
|
2
3
|
* Filters the selection to only include requested fields.
|
|
3
4
|
* Supports `?select=id,name,email` from URL.
|
|
@@ -10,8 +11,13 @@ export class FieldSelector {
|
|
|
10
11
|
applyFieldSelection(selection, requestedFields, config) {
|
|
11
12
|
if (!requestedFields?.length)
|
|
12
13
|
return selection;
|
|
13
|
-
// Build a whitelist of allowed (non-hidden) fields
|
|
14
|
+
// Build a whitelist of allowed (non-hidden) fields — base columns first
|
|
14
15
|
const allowed = new Set(config.columns.filter((c) => !c.hidden).map((c) => c.name));
|
|
16
|
+
// Also allow selectable fields from joined tables so that
|
|
17
|
+
// ?select=joinColumn correctly includes them in the SQL selection.
|
|
18
|
+
if (config.joins?.length) {
|
|
19
|
+
collectSelectableJoinFields(config.joins, allowed);
|
|
20
|
+
}
|
|
15
21
|
const filtered = {};
|
|
16
22
|
for (const field of requestedFields) {
|
|
17
23
|
if (allowed.has(field) && selection[field]) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldSelector.js","sourceRoot":"","sources":["../../src/core/fieldSelector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fieldSelector.js","sourceRoot":"","sources":["../../src/core/fieldSelector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB;;;OAGG;IACH,mBAAmB,CACjB,SAAuC,EACvC,eAAqC,EACrC,MAAmB;QAEnB,IAAI,CAAC,eAAe,EAAE,MAAM;YAAE,OAAO,SAAS,CAAC;QAE/C,wEAAwE;QACxE,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC3D,CAAC;QAEF,0DAA0D;QAC1D,mEAAmE;QACnE,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YACzB,2BAA2B,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,QAAQ,GAAiC,EAAE,CAAC;QAElD,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3C,QAAQ,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,0EAA0E;QAC1E,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC1D,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC3B,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAClB,IAA+B,EAC/B,eAAqC;QAErC,IAAI,CAAC,eAAe,EAAE,MAAM;YAAE,OAAO,IAAI,CAAC;QAE1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;QAE1C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACtB,MAAM,QAAQ,GAA4B,EAAE,CAAC;YAC7C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;oBACjB,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterBuilder.d.ts","sourceRoot":"","sources":["../../src/core/filterBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,EAGJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAA4B,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"filterBuilder.d.ts","sourceRoot":"","sources":["../../src/core/filterBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,EAGJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAA4B,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAa9C,qBAAa,aAAa;IACZ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;OAGG;IACH,YAAY,CACV,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC,GAClD,GAAG,GAAG,SAAS;IA0ElB;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,GAAG,SAAS;IA6BxD;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAqCrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA+B1B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getTableColumns, and, } from 'drizzle-orm';
|
|
2
2
|
import { applyOperator } from '../utils/operators';
|
|
3
3
|
import { isDatePreset, buildDatePresetCondition } from './datePresets';
|
|
4
|
+
import { collectFilterableJoinFields, isJoinColumnInJoins } from '../utils/joinUtils';
|
|
4
5
|
export class FilterBuilder {
|
|
5
6
|
schema;
|
|
6
7
|
constructor(schema) {
|
|
@@ -88,7 +89,7 @@ export class FilterBuilder {
|
|
|
88
89
|
for (const filter of config.filters) {
|
|
89
90
|
if (filter.type !== 'static' || filter.value === undefined)
|
|
90
91
|
continue;
|
|
91
|
-
const isJoinField =
|
|
92
|
+
const isJoinField = isJoinColumnInJoins(config.joins ?? [], filter.field);
|
|
92
93
|
const resolved = this.resolveColumn(config, baseColumns, filter.field, isJoinField);
|
|
93
94
|
if (!resolved) {
|
|
94
95
|
console.warn(`[FilterBuilder] Static filter: could not resolve column "${filter.field}" — skipped`);
|
|
@@ -168,44 +169,4 @@ export class FilterBuilder {
|
|
|
168
169
|
return undefined;
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
// ---------------------------------------------------------------------------
|
|
172
|
-
// Module-level helpers (pure, no `this` dependency)
|
|
173
|
-
// ---------------------------------------------------------------------------
|
|
174
|
-
/**
|
|
175
|
-
* Recursively populates `out` with filterable field names from all join configs.
|
|
176
|
-
*/
|
|
177
|
-
function collectFilterableJoinFields(joins, out) {
|
|
178
|
-
for (const join of joins) {
|
|
179
|
-
if (join.columns) {
|
|
180
|
-
for (const col of join.columns) {
|
|
181
|
-
if (col.filterable !== false) {
|
|
182
|
-
out.add(col.name);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
if (join.joins) {
|
|
187
|
-
collectFilterableJoinFields(join.joins, out);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Returns true if `fieldName` is defined in any join config (recursively).
|
|
193
|
-
* Used to prevent base-table columns from shadowing join columns.
|
|
194
|
-
*/
|
|
195
|
-
function isJoinColumn(config, fieldName) {
|
|
196
|
-
if (!config.joins)
|
|
197
|
-
return false;
|
|
198
|
-
return isJoinColumnInJoins(config.joins, fieldName);
|
|
199
|
-
}
|
|
200
|
-
function isJoinColumnInJoins(joins, fieldName) {
|
|
201
|
-
for (const join of joins) {
|
|
202
|
-
if (join.columns?.some(c => c.name === fieldName)) {
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
if (join.joins && isJoinColumnInJoins(join.joins, fieldName)) {
|
|
206
|
-
return true;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
172
|
//# sourceMappingURL=filterBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterBuilder.js","sourceRoot":"","sources":["../../src/core/filterBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,EACf,GAAG,GACJ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"filterBuilder.js","sourceRoot":"","sources":["../../src/core/filterBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputValidator.d.ts","sourceRoot":"","sources":["../../src/core/inputValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"inputValidator.d.ts","sourceRoot":"","sources":["../../src/core/inputValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAC;AAI5D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAI7E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ValidationError, FieldError } from '../errors';
|
|
2
|
+
import { collectSortableJoinFields, collectSelectableJoinFields } from '../utils/joinUtils';
|
|
2
3
|
/**
|
|
3
4
|
* Validates request params against the table config BEFORE hitting the database.
|
|
4
5
|
* Catches type mismatches, invalid fields, and bad values early.
|
|
@@ -11,14 +12,15 @@ export function validateInput(params, config) {
|
|
|
11
12
|
function validateSelectFields(params, config) {
|
|
12
13
|
if (!params.select?.length)
|
|
13
14
|
return;
|
|
14
|
-
|
|
15
|
+
// Build valid set from base columns (non-hidden only)
|
|
16
|
+
const validNames = new Set(config.columns.filter((c) => !c.hidden).map((c) => c.name));
|
|
17
|
+
// Also allow selectable fields from joined tables
|
|
18
|
+
if (config.joins?.length) {
|
|
19
|
+
collectSelectableJoinFields(config.joins, validNames);
|
|
20
|
+
}
|
|
15
21
|
for (const field of params.select) {
|
|
16
22
|
if (!validNames.has(field)) {
|
|
17
|
-
throw new FieldError(field, 'does not exist. Available: ' + [...validNames].join(', '));
|
|
18
|
-
}
|
|
19
|
-
const col = config.columns.find((c) => c.name === field);
|
|
20
|
-
if (col?.hidden) {
|
|
21
|
-
throw new FieldError(field, 'is not accessible');
|
|
23
|
+
throw new FieldError(field, 'does not exist or is not accessible. Available: ' + [...validNames].join(', '));
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
}
|
|
@@ -113,31 +115,15 @@ function validateSortFields(params, config) {
|
|
|
113
115
|
const sortable = new Set(config.columns.filter((c) => c.sortable !== false).map((c) => c.name));
|
|
114
116
|
// Also collect sortable fields from joins (same pattern as FilterBuilder
|
|
115
117
|
// uses collectFilterableJoinFields for filterable fields)
|
|
116
|
-
|
|
118
|
+
if (config.joins?.length) {
|
|
119
|
+
collectSortableJoinFields(config.joins, sortable);
|
|
120
|
+
}
|
|
117
121
|
for (const s of params.sort) {
|
|
118
122
|
if (!sortable.has(s.field)) {
|
|
119
123
|
throw new FieldError(s.field, 'is not sortable. Sortable: ' + [...sortable].join(', '));
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
}
|
|
123
|
-
/** Recursively collects sortable column names from join configs. */
|
|
124
|
-
function collectSortableJoinFields(joins, sortable) {
|
|
125
|
-
if (!joins?.length)
|
|
126
|
-
return;
|
|
127
|
-
for (const join of joins) {
|
|
128
|
-
if (join.columns) {
|
|
129
|
-
for (const col of join.columns) {
|
|
130
|
-
if (col.sortable !== false) {
|
|
131
|
-
sortable.add(col.name);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
// Recurse into nested joins
|
|
136
|
-
if (join.joins) {
|
|
137
|
-
collectSortableJoinFields(join.joins, sortable);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
127
|
function isValidUUID(str) {
|
|
142
128
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(str);
|
|
143
129
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputValidator.js","sourceRoot":"","sources":["../../src/core/inputValidator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"inputValidator.js","sourceRoot":"","sources":["../../src/core/inputValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadataBuilder.d.ts","sourceRoot":"","sources":["../../src/core/metadataBuilder.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"metadataBuilder.d.ts","sourceRoot":"","sources":["../../src/core/metadataBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,15 +22,20 @@ export function buildMetadata(config, context) {
|
|
|
22
22
|
if (config.subqueries) {
|
|
23
23
|
for (const sub of config.subqueries) {
|
|
24
24
|
// Subqueries produce a virtual column with the alias name
|
|
25
|
-
// Only add if not already in allColumns (
|
|
25
|
+
// Only add if not already in allColumns (define.ts builder always pre-populates
|
|
26
|
+
// via .subquery(), but raw TableConfig JSON objects bypass the builder).
|
|
26
27
|
if (!allColumns.some(c => c.name === sub.alias)) {
|
|
28
|
+
// 'first' mode returns row_to_json() — non-scalar JSON object.
|
|
29
|
+
// 'count' returns integer, 'exists' returns boolean.
|
|
30
|
+
// filterable: false matches define.ts to keep both paths consistent.
|
|
31
|
+
const subqueryType = sub.type === 'exists' ? 'boolean' : sub.type === 'count' ? 'number' : 'json';
|
|
27
32
|
allColumns.push({
|
|
28
33
|
name: sub.alias,
|
|
29
|
-
type:
|
|
34
|
+
type: subqueryType,
|
|
30
35
|
label: sub.alias,
|
|
31
36
|
hidden: false,
|
|
32
|
-
sortable:
|
|
33
|
-
filterable:
|
|
37
|
+
sortable: sub.type !== 'first',
|
|
38
|
+
filterable: false,
|
|
34
39
|
computed: true,
|
|
35
40
|
_source: 'subquery',
|
|
36
41
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadataBuilder.js","sourceRoot":"","sources":["../../src/core/metadataBuilder.ts"],"names":[],"mappings":"AA+EA;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAmB,EACnB,OAAuB;IAEvB,MAAM,SAAS,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;IAE7C,8CAA8C;IAE9C,MAAM,UAAU,GAAiE,EAAE,CAAC;IAEpF,0EAA0E;IAC1E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,UAAU,CAAC,IAAI,CAAC;YACd,GAAG,GAAG;YACN,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;SACrC,CAAC,CAAC;IACZ,CAAC;IAED,mDAAmD;IACnD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,2BAA2B,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,8BAA8B;IAC9B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,0DAA0D;YAC1D,
|
|
1
|
+
{"version":3,"file":"metadataBuilder.js","sourceRoot":"","sources":["../../src/core/metadataBuilder.ts"],"names":[],"mappings":"AA+EA;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAmB,EACnB,OAAuB;IAEvB,MAAM,SAAS,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;IAE7C,8CAA8C;IAE9C,MAAM,UAAU,GAAiE,EAAE,CAAC;IAEpF,0EAA0E;IAC1E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,UAAU,CAAC,IAAI,CAAC;YACd,GAAG,GAAG;YACN,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;SACrC,CAAC,CAAC;IACZ,CAAC;IAED,mDAAmD;IACnD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,2BAA2B,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,8BAA8B;IAC9B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,0DAA0D;YAC1D,gFAAgF;YAChF,yEAAyE;YACzE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChD,+DAA+D;gBAC/D,qDAAqD;gBACrD,qEAAqE;gBACrE,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;gBAClG,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,GAAG,CAAC,KAAK;oBACf,IAAI,EAAE,YAAY;oBAClB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,MAAM,EAAE,KAAK;oBACb,QAAQ,EAAE,GAAG,CAAC,IAAI,KAAK,OAAO;oBAC9B,UAAU,EAAE,KAAK;oBACjB,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE,UAAU;iBACb,CAAC,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,wCAAwC;IAExC,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/C,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC7B,MAAM,SAAS,GAAI,GAAW,CAAC,SAAiC,CAAC;QACjE,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,8BAA8B;IAE9B,MAAM,OAAO,GAAqB,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3D,MAAM,MAAM,GAAI,GAAW,CAAC,OAA6B,CAAC;QAC1D,MAAM,SAAS,GAAI,GAAW,CAAC,UAAgC,CAAC;QAEhE,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI;YAC5B,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;YAC9B,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI;YAClC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,KAAK;YAC/B,MAAM,EAAE,CAAC,MAAM,IAAI,MAAM,CAA8C;YACvE,GAAG,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC/B,MAAM,EAAG,GAAW,CAAC,MAAM;YAC3B,KAAK,EAAG,GAAW,CAAC,KAAK;YACzB,KAAK,EAAG,GAAW,CAAC,KAAK;YACzB,QAAQ,EAAG,GAAW,CAAC,QAAQ;YAC/B,QAAQ,EAAG,GAAW,CAAC,QAAQ;YAC/B,OAAO,EAAG,GAAW,CAAC,OAAO;YAC7B,WAAW,EAAG,GAAW,CAAC,WAAW;YACrC,SAAS,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;SACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAEhE,MAAM,OAAO,GAAqB,cAAc;SAC7C,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;SAC/B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACb,KAAK,EAAE,GAAG,CAAC,IAAI;QACf,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI;QAC5B,SAAS,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;QACxC,OAAO,EAAG,GAAW,CAAC,OAAO;QAC7B,WAAW,EAAG,GAAW,CAAC,WAAW;KACtC,CAAC,CAAC,CAAC;IAEN,mCAAmC;IAEnC,MAAM,YAAY,GAA0B,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClF,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC,CAAC;IAEJ,kDAAkD;IAElD,MAAM,QAAQ,GAAsB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAErF,8EAA8E;IAE9E,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC1C,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,MAAM,WAAW,GAAG,UAAU;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;SAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpB,IAAI,eAAe,GAAkB,IAAI,CAAC;IAE1C,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,eAAe,CAAC,CAAC;QACvE,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC3E,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,eAAe,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC7F,IAAI,YAAY,EAAE,CAAC;YACjB,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,YAAY,CAAC,IAAI,IAAI,CAAC;QAC3F,CAAC;aAAM,CAAC;YACN,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,eAAe;QACf,WAAW;QACX,OAAO;QACP,YAAY,EAAE;YACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK;YACvC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE;YACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI;YACtC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;YACxD,UAAU,EAAE;gBACV,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI;gBAC3C,eAAe,EAAE,MAAM,CAAC,UAAU,EAAE,eAAe,IAAI,EAAE;gBACzD,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,IAAI,GAAG;gBAClD,MAAM,EAAE,IAAI;aACb;YACD,IAAI,EAAE;gBACJ,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAC/C,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAChD,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK;iBACxB,CAAC,CAAC;aACJ;YACD,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;YAC3C,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE;YAC3C,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS;SAC9B;QACD,OAAO;QACP,YAAY;QACZ,QAAQ;QACR,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,2BAA2B,CAClC,KAAmB,EACnB,GAAiE;IAEjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC/B,2EAA2E;gBAC3E,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxC,GAAG,CAAC,IAAI,CAAC;wBACP,GAAG,GAAG;wBACN,OAAO,EAAE,MAAM;wBACf,UAAU,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;qBAC9B,CAAC,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QACD,4BAA4B;QAC5B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,2BAA2B,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,GAAQ;IACpC,MAAM,IAAI,GAAoB;QAC5B,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC;IACF,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM;QAAE,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IACpD,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEpD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3F,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACzE,KAAK,MAAM;YACT,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,KAAK,SAAS;YACZ,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC9C;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -23,7 +23,8 @@ export declare class SortBuilder {
|
|
|
23
23
|
*
|
|
24
24
|
* Note: This implements a "first-match-wins" strategy. If multiple joins
|
|
25
25
|
* expose a column with the same name, the first one encountered in a
|
|
26
|
-
* depth-first traversal of the join tree will be used.
|
|
26
|
+
* depth-first traversal of the join tree will be used, and a console.warn
|
|
27
|
+
* is emitted to help developers detect and resolve the collision.
|
|
27
28
|
*/
|
|
28
29
|
private resolveJoinColumn;
|
|
29
30
|
private getDefaultSort;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortBuilder.d.ts","sourceRoot":"","sources":["../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAKJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,qBAAa,WAAW;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE;
|
|
1
|
+
{"version":3,"file":"sortBuilder.d.ts","sourceRoot":"","sources":["../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAKJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,qBAAa,WAAW;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE;IAiF9F;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IAkDzB,OAAO,CAAC,cAAc;CAQvB"}
|
package/dist/core/sortBuilder.js
CHANGED
|
@@ -25,7 +25,10 @@ export class SortBuilder {
|
|
|
25
25
|
if (!table)
|
|
26
26
|
return [];
|
|
27
27
|
const baseColumns = getTableColumns(table);
|
|
28
|
-
// Build a whitelist of sortable fields from base columns AND join columns
|
|
28
|
+
// Build a whitelist of sortable fields from base columns AND join columns.
|
|
29
|
+
// sortable: undefined is treated as sortable (same as true) — only an
|
|
30
|
+
// explicit sortable: false disables it. This matches the introspect.ts
|
|
31
|
+
// default of sortable: true for auto-detected columns.
|
|
29
32
|
const sortableFields = new Set();
|
|
30
33
|
for (const col of config.columns) {
|
|
31
34
|
if (col.sortable !== false) {
|
|
@@ -89,31 +92,45 @@ export class SortBuilder {
|
|
|
89
92
|
*
|
|
90
93
|
* Note: This implements a "first-match-wins" strategy. If multiple joins
|
|
91
94
|
* expose a column with the same name, the first one encountered in a
|
|
92
|
-
* depth-first traversal of the join tree will be used.
|
|
95
|
+
* depth-first traversal of the join tree will be used, and a console.warn
|
|
96
|
+
* is emitted to help developers detect and resolve the collision.
|
|
93
97
|
*/
|
|
94
98
|
resolveJoinColumn(config, fieldName) {
|
|
95
99
|
if (!config.joins)
|
|
96
100
|
return undefined;
|
|
101
|
+
// Collect all matches (table name + Column) across all joins (depth-first)
|
|
102
|
+
const matches = [];
|
|
97
103
|
for (const join of config.joins) {
|
|
98
104
|
const joinColConfig = join.columns?.find((c) => c.name === fieldName);
|
|
99
105
|
if (joinColConfig) {
|
|
100
106
|
const joinedTable = this.schema[join.table];
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
if (joinedTable) {
|
|
108
|
+
const joinedCols = getTableColumns(joinedTable);
|
|
109
|
+
const dbCol = joinColConfig.field ?? fieldName;
|
|
110
|
+
const column = joinedCols[dbCol];
|
|
111
|
+
if (column) {
|
|
112
|
+
matches.push({ table: join.table, column });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
108
115
|
}
|
|
109
116
|
// Recurse into nested joins
|
|
110
117
|
if (join.joins) {
|
|
111
118
|
const nested = this.resolveJoinColumn({ joins: join.joins }, fieldName);
|
|
112
|
-
if (nested)
|
|
113
|
-
|
|
119
|
+
if (nested) {
|
|
120
|
+
// Treat nested match as a candidate (table name not relevant for warning)
|
|
121
|
+
matches.push({ table: join.table + '(nested)', column: nested });
|
|
122
|
+
}
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
|
-
|
|
125
|
+
if (matches.length === 0)
|
|
126
|
+
return undefined;
|
|
127
|
+
if (matches.length > 1) {
|
|
128
|
+
console.warn(`[TableCraft] Sort field '${fieldName}' exists in multiple joins ` +
|
|
129
|
+
`(${matches.map((m) => m.table).join(', ')}). ` +
|
|
130
|
+
`Using first match. ` +
|
|
131
|
+
`Use dot-syntax (e.g. '${matches[0].table}.${fieldName}') to be explicit.`);
|
|
132
|
+
}
|
|
133
|
+
return matches[0].column;
|
|
117
134
|
}
|
|
118
135
|
getDefaultSort(config) {
|
|
119
136
|
if (!config.defaultSort || config.defaultSort.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortBuilder.js","sourceRoot":"","sources":["../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EACf,GAAG,EACH,IAAI,GAEL,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,MAAM,OAAO,WAAW;IACF;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,MAAmB,EAAE,MAAoB,EAAE,cAAiC;QACpF,MAAM,UAAU,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAErE,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEtD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QAChD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAEtB,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAE3C,
|
|
1
|
+
{"version":3,"file":"sortBuilder.js","sourceRoot":"","sources":["../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EACf,GAAG,EACH,IAAI,GAEL,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,MAAM,OAAO,WAAW;IACF;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,MAAmB,EAAE,MAAoB,EAAE,cAAiC;QACpF,MAAM,UAAU,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAErE,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEtD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QAChD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAEtB,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAE3C,2EAA2E;QAC3E,sEAAsE;QACtE,uEAAuE;QACvE,uDAAuD;QACvD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAC3B,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,yBAAyB,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,OAAO,GAAU,EAAE,CAAC;QAE1B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;gBAAE,SAAS;YAE5C,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;YAChE,MAAM,WAAW,GAAG,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC;YAEjD,IAAI,GAAuB,CAAC;YAE5B,0DAA0D;YAC1D,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpD,kDAAkD;gBAClD,IAAI,eAAe,GAAG,SAAS,CAAC;gBAChC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;oBAClE,IAAI,WAAW,EAAE,CAAC;wBAChB,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC;oBACtC,CAAC;gBACH,CAAC;gBAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAsB,CAAC;gBACtE,IAAI,WAAW,EAAE,CAAC;oBACd,GAAG,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC;gBAChD,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACL,6EAA6E;gBAC7E,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;gBACtE,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;gBACjC,CAAC;YACJ,CAAC;YAED,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzD,SAAS;YACX,CAAC;YAED,mDAAmD;YACnD,MAAM,OAAO,GAAG,cAAc,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,cAAc,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;YAClF,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBACjE,SAAS;YACX,CAAC;YAED,wDAAwD;YACxD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YACzD,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB,CACvB,MAAgC,EAChC,SAAiB;QAEjB,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAEpC,2EAA2E;QAC3E,MAAM,OAAO,GAA6C,EAAE,CAAC;QAE7D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC5B,CAAC;YAEF,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAsB,CAAC;gBACjE,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,UAAU,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;oBAChD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAI,SAAS,CAAC;oBAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;oBACjC,IAAI,MAAM,EAAE,CAAC;wBACX,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC9C,CAAC;gBACH,CAAC;YACH,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;gBACxE,IAAI,MAAM,EAAE,CAAC;oBACX,0EAA0E;oBAC1E,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAE3C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CACV,4BAA4B,SAAS,6BAA6B;gBAClE,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBAC/C,qBAAqB;gBACrB,yBAAyB,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,SAAS,oBAAoB,CAC3E,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3B,CAAC;IAEO,cAAc,CAAC,MAAmB;QACxC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAE7E,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK;SACxB,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
|