@teleporthq/teleport-plugin-next-data-source 0.43.63 → 0.43.64
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/__tests__/filter-groups.test.ts +174 -0
- package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
- package/dist/cjs/fetchers/airtable.js +1 -1
- package/dist/cjs/fetchers/airtable.js.map +1 -1
- package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/cjs/fetchers/clickhouse.js +1 -1
- package/dist/cjs/fetchers/clickhouse.js.map +1 -1
- package/dist/cjs/fetchers/csv-file.d.ts.map +1 -1
- package/dist/cjs/fetchers/csv-file.js +3 -3
- package/dist/cjs/fetchers/csv-file.js.map +1 -1
- package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
- package/dist/cjs/fetchers/firestore.js +1 -1
- package/dist/cjs/fetchers/firestore.js.map +1 -1
- package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -1
- package/dist/cjs/fetchers/google-sheets.js +1 -1
- package/dist/cjs/fetchers/google-sheets.js.map +1 -1
- package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
- package/dist/cjs/fetchers/javascript.js +1 -1
- package/dist/cjs/fetchers/javascript.js.map +1 -1
- package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mariadb.js +1 -1
- package/dist/cjs/fetchers/mariadb.js.map +1 -1
- package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mongodb.js +1 -1
- package/dist/cjs/fetchers/mongodb.js.map +1 -1
- package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
- package/dist/cjs/fetchers/mysql.js +1 -1
- package/dist/cjs/fetchers/mysql.js.map +1 -1
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +1 -1
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/redis.d.ts.map +1 -1
- package/dist/cjs/fetchers/redis.js +1 -1
- package/dist/cjs/fetchers/redis.js.map +1 -1
- package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
- package/dist/cjs/fetchers/redshift.js +2 -2
- package/dist/cjs/fetchers/redshift.js.map +1 -1
- package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
- package/dist/cjs/fetchers/rest-api.js +2 -2
- package/dist/cjs/fetchers/rest-api.js.map +1 -1
- package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
- package/dist/cjs/fetchers/supabase.js +1 -1
- package/dist/cjs/fetchers/supabase.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +1 -1
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/turso.d.ts.map +1 -1
- package/dist/cjs/fetchers/turso.js +1 -1
- package/dist/cjs/fetchers/turso.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +32 -0
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +116 -18
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/fetchers/airtable.d.ts.map +1 -1
- package/dist/esm/fetchers/airtable.js +2 -2
- package/dist/esm/fetchers/airtable.js.map +1 -1
- package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/esm/fetchers/clickhouse.js +2 -2
- package/dist/esm/fetchers/clickhouse.js.map +1 -1
- package/dist/esm/fetchers/csv-file.d.ts.map +1 -1
- package/dist/esm/fetchers/csv-file.js +4 -4
- package/dist/esm/fetchers/csv-file.js.map +1 -1
- package/dist/esm/fetchers/firestore.d.ts.map +1 -1
- package/dist/esm/fetchers/firestore.js +2 -2
- package/dist/esm/fetchers/firestore.js.map +1 -1
- package/dist/esm/fetchers/google-sheets.d.ts.map +1 -1
- package/dist/esm/fetchers/google-sheets.js +2 -2
- package/dist/esm/fetchers/google-sheets.js.map +1 -1
- package/dist/esm/fetchers/javascript.d.ts.map +1 -1
- package/dist/esm/fetchers/javascript.js +2 -2
- package/dist/esm/fetchers/javascript.js.map +1 -1
- package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
- package/dist/esm/fetchers/mariadb.js +2 -2
- package/dist/esm/fetchers/mariadb.js.map +1 -1
- package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
- package/dist/esm/fetchers/mongodb.js +2 -2
- package/dist/esm/fetchers/mongodb.js.map +1 -1
- package/dist/esm/fetchers/mysql.d.ts.map +1 -1
- package/dist/esm/fetchers/mysql.js +2 -2
- package/dist/esm/fetchers/mysql.js.map +1 -1
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +2 -2
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/redis.d.ts.map +1 -1
- package/dist/esm/fetchers/redis.js +2 -2
- package/dist/esm/fetchers/redis.js.map +1 -1
- package/dist/esm/fetchers/redshift.d.ts.map +1 -1
- package/dist/esm/fetchers/redshift.js +3 -3
- package/dist/esm/fetchers/redshift.js.map +1 -1
- package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
- package/dist/esm/fetchers/rest-api.js +3 -3
- package/dist/esm/fetchers/rest-api.js.map +1 -1
- package/dist/esm/fetchers/supabase.d.ts.map +1 -1
- package/dist/esm/fetchers/supabase.js +2 -2
- package/dist/esm/fetchers/supabase.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +2 -2
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/turso.d.ts.map +1 -1
- package/dist/esm/fetchers/turso.js +2 -2
- package/dist/esm/fetchers/turso.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +32 -0
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +112 -17
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/fetchers/airtable.ts +35 -36
- package/src/fetchers/clickhouse.ts +26 -36
- package/src/fetchers/csv-file.ts +13 -21
- package/src/fetchers/firestore.ts +41 -35
- package/src/fetchers/google-sheets.ts +15 -23
- package/src/fetchers/javascript.ts +11 -21
- package/src/fetchers/mariadb.ts +33 -44
- package/src/fetchers/mongodb.ts +66 -81
- package/src/fetchers/mysql.ts +33 -45
- package/src/fetchers/postgresql.ts +52 -62
- package/src/fetchers/redis.ts +6 -5
- package/src/fetchers/redshift.ts +29 -41
- package/src/fetchers/rest-api.ts +11 -21
- package/src/fetchers/supabase.ts +104 -41
- package/src/fetchers/teleport.ts +53 -64
- package/src/fetchers/turso.ts +27 -39
- package/src/utils.ts +188 -31
package/src/fetchers/turso.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
replaceSecretReference,
|
|
3
3
|
generateDateFormatterCode,
|
|
4
4
|
generateSafeJSONParseCode,
|
|
5
|
+
generateFilterTreeHelpersCode,
|
|
5
6
|
generateSearchEscapeHelpersCode,
|
|
6
7
|
} from '../utils'
|
|
7
8
|
|
|
@@ -42,6 +43,8 @@ export const generateTursoFetcher = (
|
|
|
42
43
|
|
|
43
44
|
${generateSafeJSONParseCode()}
|
|
44
45
|
|
|
46
|
+
${generateFilterTreeHelpersCode()}
|
|
47
|
+
|
|
45
48
|
${generateSearchEscapeHelpersCode()}
|
|
46
49
|
|
|
47
50
|
${generateDateFormatterCode()}
|
|
@@ -92,52 +95,37 @@ export default async function handler(req, res) {
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
if (filters) {
|
|
95
|
-
const
|
|
98
|
+
const filterTree = normalizeFilterTree(safeJSONParse(filters))
|
|
96
99
|
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
const value = filter.destination
|
|
103
|
-
const operand = filter.operand || '='
|
|
100
|
+
if (filterTree) {
|
|
101
|
+
const buildCondition = (condition) => {
|
|
102
|
+
const field = sanitizeIdentifier(condition.source)
|
|
103
|
+
const value = condition.destination
|
|
104
|
+
const operand = condition.operand
|
|
104
105
|
|
|
105
106
|
if (Array.isArray(value)) {
|
|
106
|
-
if (value.length === 0) return
|
|
107
|
+
if (value.length === 0) return null
|
|
107
108
|
const placeholders = value.map(() => '?').join(', ')
|
|
108
109
|
queryParams.push(...value)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
whereClauses.push(\`\${field} IN (\${placeholders})\`)
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
if (value === null) {
|
|
116
|
-
if (operand === '=') {
|
|
117
|
-
whereClauses.push(\`\${field} IS NULL\`)
|
|
118
|
-
} else if (operand === '!=') {
|
|
119
|
-
whereClauses.push(\`\${field} IS NOT NULL\`)
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
const validOps = ['=', '!=', '>', '<', '>=', '<=']
|
|
123
|
-
const sqlOperator = validOps.includes(operand) ? operand : '='
|
|
124
|
-
whereClauses.push(\`\${field} \${sqlOperator} ?\`)
|
|
125
|
-
queryParams.push(value)
|
|
126
|
-
}
|
|
110
|
+
return operand === '!='
|
|
111
|
+
? \`\${field} NOT IN (\${placeholders})\`
|
|
112
|
+
: \`\${field} IN (\${placeholders})\`
|
|
127
113
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const placeholders = value.map(() => '?').join(', ')
|
|
134
|
-
queryParams.push(...value)
|
|
135
|
-
whereClauses.push(\`\${field} IN (\${placeholders})\`)
|
|
136
|
-
} else {
|
|
137
|
-
whereClauses.push(\`\${field} = ?\`)
|
|
138
|
-
queryParams.push(value)
|
|
114
|
+
|
|
115
|
+
if (value === null) {
|
|
116
|
+
if (operand === '=') return \`\${field} IS NULL\`
|
|
117
|
+
if (operand === '!=') return \`\${field} IS NOT NULL\`
|
|
118
|
+
return null
|
|
139
119
|
}
|
|
140
|
-
|
|
120
|
+
|
|
121
|
+
const validOps = ['=', '!=', '>', '<', '>=', '<=']
|
|
122
|
+
const sqlOperator = validOps.includes(operand) ? operand : '='
|
|
123
|
+
queryParams.push(value)
|
|
124
|
+
return \`\${field} \${sqlOperator} ?\`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const clause = buildFilterTreeClause(filterTree, buildCondition)
|
|
128
|
+
if (clause) whereClauses.push(clause)
|
|
141
129
|
}
|
|
142
130
|
}
|
|
143
131
|
|
package/src/utils.ts
CHANGED
|
@@ -596,6 +596,146 @@ const dateReplacer = (key, value) => {
|
|
|
596
596
|
}`
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
+
/**
|
|
600
|
+
* Every leaf condition of a filters array, unwrapping any `{ type: 'group' }`
|
|
601
|
+
* envelopes the inspector wrapped them in. Generator-side checks that ask
|
|
602
|
+
* "does any destination reference state / a route param?" must look through
|
|
603
|
+
* groups — asking `entry.destination` of a group silently answers "no", which
|
|
604
|
+
* is how a dynamic filter ends up baked into initialData at build time.
|
|
605
|
+
*/
|
|
606
|
+
export const collectFilterLeafConditions = (entries: unknown): unknown[] => {
|
|
607
|
+
if (!Array.isArray(entries)) {
|
|
608
|
+
return []
|
|
609
|
+
}
|
|
610
|
+
const leaves: unknown[] = []
|
|
611
|
+
const walk = (entry: unknown): void => {
|
|
612
|
+
if (!entry || typeof entry !== 'object') {
|
|
613
|
+
return
|
|
614
|
+
}
|
|
615
|
+
const node = entry as { type?: string; children?: unknown[] }
|
|
616
|
+
if (node.type === 'group') {
|
|
617
|
+
;(node.children || []).forEach(walk)
|
|
618
|
+
return
|
|
619
|
+
}
|
|
620
|
+
leaves.push(entry)
|
|
621
|
+
}
|
|
622
|
+
entries.forEach(walk)
|
|
623
|
+
return leaves
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Rebuilds a filters array keeping its group structure, dropping leaf
|
|
628
|
+
* conditions that `keepCondition` rejects and any group left empty by that.
|
|
629
|
+
* Used so the SSG emit can discard unresolvable dynamic destinations without
|
|
630
|
+
* flattening an `or` group into ANDs on the way.
|
|
631
|
+
*/
|
|
632
|
+
export const pruneFilterTree = (
|
|
633
|
+
entries: unknown[],
|
|
634
|
+
keepCondition: (condition: unknown) => boolean
|
|
635
|
+
): unknown[] => {
|
|
636
|
+
const prune = (entry: unknown): unknown | null => {
|
|
637
|
+
if (!entry || typeof entry !== 'object') {
|
|
638
|
+
return null
|
|
639
|
+
}
|
|
640
|
+
const node = entry as { type?: string; children?: unknown[] }
|
|
641
|
+
if (node.type === 'group') {
|
|
642
|
+
const children = (node.children || []).map(prune).filter(Boolean)
|
|
643
|
+
if (children.length === 0) {
|
|
644
|
+
return null
|
|
645
|
+
}
|
|
646
|
+
return { ...node, children }
|
|
647
|
+
}
|
|
648
|
+
return keepCondition(entry) ? entry : null
|
|
649
|
+
}
|
|
650
|
+
return entries.map(prune).filter(Boolean) as unknown[]
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Runtime helpers for the filter TREE the GUI authors.
|
|
655
|
+
*
|
|
656
|
+
* The inspector emits filters as a tree — a root `{ type: 'group', operator,
|
|
657
|
+
* children }` whose children are `{ type: 'condition', source, destination,
|
|
658
|
+
* operand }` leaves or further groups (an `or` group nested inside the root
|
|
659
|
+
* `and` is how "A and (B or C)" is expressed). Older projects, and params built
|
|
660
|
+
* by hand, still send a flat array of bare conditions or a plain `{ key: value }`
|
|
661
|
+
* map.
|
|
662
|
+
*
|
|
663
|
+
* Every fetcher used to hand-roll `parsedFilters.forEach(f => { if (!f.source)
|
|
664
|
+
* return ... })`, which silently DROPPED any group — a group has no `.source`,
|
|
665
|
+
* so the whole filter became a no-op and the page rendered unfiltered rows.
|
|
666
|
+
* These helpers exist so no fetcher has to know the shape: `normalizeFilterTree`
|
|
667
|
+
* turns all three input forms into one tree, and the walkers below consume it.
|
|
668
|
+
*/
|
|
669
|
+
export const generateFilterTreeHelpersCode = (): string => {
|
|
670
|
+
return `const normalizeFilterTree = (parsed) => {
|
|
671
|
+
if (parsed === null || parsed === undefined) return null
|
|
672
|
+
|
|
673
|
+
const toNode = (entry) => {
|
|
674
|
+
if (!entry || typeof entry !== 'object') return null
|
|
675
|
+
if (entry.type === 'group') {
|
|
676
|
+
const children = Array.isArray(entry.children)
|
|
677
|
+
? entry.children.map(toNode).filter(Boolean)
|
|
678
|
+
: []
|
|
679
|
+
if (children.length === 0) return null
|
|
680
|
+
return { type: 'group', operator: entry.operator === 'or' ? 'or' : 'and', children }
|
|
681
|
+
}
|
|
682
|
+
if (!entry.source || entry.destination === undefined) return null
|
|
683
|
+
return {
|
|
684
|
+
type: 'condition',
|
|
685
|
+
source: entry.source,
|
|
686
|
+
destination: entry.destination,
|
|
687
|
+
operand: entry.operand || '=',
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const children = Array.isArray(parsed)
|
|
692
|
+
? parsed.map(toNode).filter(Boolean)
|
|
693
|
+
: Object.entries(parsed).map(([source, destination]) =>
|
|
694
|
+
toNode({ source, destination, operand: '=' })
|
|
695
|
+
).filter(Boolean)
|
|
696
|
+
|
|
697
|
+
if (children.length === 0) return null
|
|
698
|
+
// A single root group is already the tree; wrapping it in another and-group
|
|
699
|
+
// would only add a redundant level.
|
|
700
|
+
if (children.length === 1 && children[0].type === 'group') return children[0]
|
|
701
|
+
return { type: 'group', operator: 'and', children }
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const evaluateFilterTree = (node, testCondition) => {
|
|
705
|
+
if (!node) return true
|
|
706
|
+
if (node.type === 'group') {
|
|
707
|
+
if (node.children.length === 0) return true
|
|
708
|
+
return node.operator === 'or'
|
|
709
|
+
? node.children.some((child) => evaluateFilterTree(child, testCondition))
|
|
710
|
+
: node.children.every((child) => evaluateFilterTree(child, testCondition))
|
|
711
|
+
}
|
|
712
|
+
return testCondition(node)
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const buildFilterTreeClause = (node, buildCondition) => {
|
|
716
|
+
if (!node) return null
|
|
717
|
+
if (node.type === 'group') {
|
|
718
|
+
const parts = []
|
|
719
|
+
for (const child of node.children) {
|
|
720
|
+
const clause = buildFilterTreeClause(child, buildCondition)
|
|
721
|
+
if (clause) parts.push(clause)
|
|
722
|
+
}
|
|
723
|
+
if (parts.length === 0) return null
|
|
724
|
+
if (parts.length === 1) return parts[0]
|
|
725
|
+
return '(' + parts.join(node.operator === 'or' ? ' OR ' : ' AND ') + ')'
|
|
726
|
+
}
|
|
727
|
+
return buildCondition(node)
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
const flattenFilterConditions = (node) => {
|
|
731
|
+
if (!node) return []
|
|
732
|
+
if (node.type === 'group') {
|
|
733
|
+
return node.children.reduce((acc, child) => acc.concat(flattenFilterConditions(child)), [])
|
|
734
|
+
}
|
|
735
|
+
return [node]
|
|
736
|
+
}`
|
|
737
|
+
}
|
|
738
|
+
|
|
599
739
|
export const generateSortFilterHelperCode = (): string => {
|
|
600
740
|
return `function getNestedValue(obj, path) {
|
|
601
741
|
if (!obj || typeof obj !== 'object') return undefined
|
|
@@ -801,13 +941,14 @@ export const hasUnresolvableDynamicParams = (
|
|
|
801
941
|
}
|
|
802
942
|
|
|
803
943
|
if (param.type === 'static' && Array.isArray(param.content)) {
|
|
804
|
-
const
|
|
944
|
+
const leafConditions = collectFilterLeafConditions(param.content)
|
|
945
|
+
const hasDynamicDestinations = leafConditions.some(
|
|
805
946
|
(item: any) =>
|
|
806
947
|
item && typeof item === 'object' && ASTUtils.isUIDLDynamicReference(item?.destination)
|
|
807
948
|
)
|
|
808
949
|
|
|
809
950
|
if (hasDynamicDestinations && dynamicRouteAttr) {
|
|
810
|
-
const allResolvable =
|
|
951
|
+
const allResolvable = leafConditions.every((item: any) => {
|
|
811
952
|
if (!item || typeof item !== 'object') {
|
|
812
953
|
return true
|
|
813
954
|
}
|
|
@@ -1165,9 +1306,9 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1165
1306
|
// tslint:disable-next-line:no-any
|
|
1166
1307
|
const resourceParamsForFilters = (node.content as any).resource?.params || {}
|
|
1167
1308
|
const nodeFilters = resourceParamsForFilters.filters?.content || []
|
|
1168
|
-
const hasDynamicFilterDestinations =
|
|
1169
|
-
|
|
1170
|
-
|
|
1309
|
+
const hasDynamicFilterDestinations = collectFilterLeafConditions(nodeFilters).some((f: any) =>
|
|
1310
|
+
ASTUtils.isUIDLDynamicReference(f?.destination)
|
|
1311
|
+
)
|
|
1171
1312
|
|
|
1172
1313
|
// Update all target JSX nodes with initialData (only those that don't already have it)
|
|
1173
1314
|
for (const jsxNode of nodesToUpdate) {
|
|
@@ -1291,9 +1432,12 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1291
1432
|
if (key === 'sorts' || key === 'filters' || key === 'queryColumns') {
|
|
1292
1433
|
let itemsToProcess = validItems
|
|
1293
1434
|
if (key === 'filters') {
|
|
1294
|
-
// Keep filter
|
|
1295
|
-
//
|
|
1296
|
-
|
|
1435
|
+
// Keep filter conditions that are either static or route-resolvable
|
|
1436
|
+
// (via dynamicRouteAttr) and drop the ones with unresolvable dynamic
|
|
1437
|
+
// destinations. Pruned through the tree so a condition nested in a
|
|
1438
|
+
// group is judged on its own destination, and an `or` group keeps
|
|
1439
|
+
// its shape on the way to the data source.
|
|
1440
|
+
itemsToProcess = pruneFilterTree(validItems, (item: any) => {
|
|
1297
1441
|
if (!ASTUtils.isUIDLDynamicReference(item?.destination)) {
|
|
1298
1442
|
return true
|
|
1299
1443
|
}
|
|
@@ -1310,36 +1454,49 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1310
1454
|
const hasRouteResolvableFilters =
|
|
1311
1455
|
key === 'filters' &&
|
|
1312
1456
|
dynamicRouteAttr &&
|
|
1313
|
-
itemsToProcess.some(
|
|
1457
|
+
collectFilterLeafConditions(itemsToProcess).some(
|
|
1314
1458
|
(item: any) =>
|
|
1315
1459
|
item &&
|
|
1316
1460
|
typeof item === 'object' &&
|
|
1317
1461
|
ASTUtils.isUIDLDynamicReference(item?.destination)
|
|
1318
1462
|
)
|
|
1319
1463
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
ASTUtils.isUIDLDynamicReference(item?.destination)
|
|
1335
|
-
) {
|
|
1336
|
-
return buildFilterObjectAST(item, dynamicRouteAttr)
|
|
1337
|
-
}
|
|
1338
|
-
return ASTUtils.objectToObjectExpression(item)
|
|
1339
|
-
}
|
|
1464
|
+
// Recurses through groups so a route-resolvable destination nested
|
|
1465
|
+
// inside one still gets its `context.params.*` AST instead of being
|
|
1466
|
+
// emitted as a raw UIDL dynamic-reference object.
|
|
1467
|
+
const buildFilterEntryAST = (item: any): types.Expression => {
|
|
1468
|
+
if (typeof item === 'string') {
|
|
1469
|
+
return types.stringLiteral(item)
|
|
1470
|
+
}
|
|
1471
|
+
if (typeof item === 'number') {
|
|
1472
|
+
return types.numericLiteral(item)
|
|
1473
|
+
}
|
|
1474
|
+
if (typeof item === 'boolean') {
|
|
1475
|
+
return types.booleanLiteral(item)
|
|
1476
|
+
}
|
|
1477
|
+
if (typeof item !== 'object' || item === null) {
|
|
1340
1478
|
return types.nullLiteral()
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1479
|
+
}
|
|
1480
|
+
if (item.type === 'group' && Array.isArray(item.children)) {
|
|
1481
|
+
return types.objectExpression([
|
|
1482
|
+
types.objectProperty(types.identifier('type'), types.stringLiteral('group')),
|
|
1483
|
+
types.objectProperty(
|
|
1484
|
+
types.identifier('operator'),
|
|
1485
|
+
types.stringLiteral(item.operator === 'or' ? 'or' : 'and')
|
|
1486
|
+
),
|
|
1487
|
+
types.objectProperty(
|
|
1488
|
+
types.identifier('children'),
|
|
1489
|
+
types.arrayExpression(item.children.map(buildFilterEntryAST))
|
|
1490
|
+
),
|
|
1491
|
+
])
|
|
1492
|
+
}
|
|
1493
|
+
if (hasRouteResolvableFilters && ASTUtils.isUIDLDynamicReference(item?.destination)) {
|
|
1494
|
+
return buildFilterObjectAST(item, dynamicRouteAttr)
|
|
1495
|
+
}
|
|
1496
|
+
return ASTUtils.objectToObjectExpression(item)
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
const arrayExpr = types.arrayExpression(itemsToProcess.map(buildFilterEntryAST))
|
|
1343
1500
|
// Wrap in JSON.stringify()
|
|
1344
1501
|
astValue = types.callExpression(
|
|
1345
1502
|
types.memberExpression(types.identifier('JSON'), types.identifier('stringify')),
|