@teleporthq/teleport-plugin-common 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.
@@ -104,6 +104,81 @@ const buildNonEmptyFilterDestinationPredicate = (): types.ArrowFunctionExpressio
104
104
  )
105
105
  }
106
106
 
107
+ // Same idea one level up: a filter entry survives if it is a group that still
108
+ // has children, or a condition whose destination resolved to something real.
109
+ const buildSurvivingFilterNodePredicate = (): types.ArrowFunctionExpression => {
110
+ const f = types.identifier('__f')
111
+ const emptyDestination = buildNonEmptyFilterDestinationPredicate().body as types.Expression
112
+ return types.arrowFunctionExpression(
113
+ [f],
114
+ types.conditionalExpression(
115
+ types.binaryExpression(
116
+ '===',
117
+ types.memberExpression(f, types.identifier('type')),
118
+ types.stringLiteral('group')
119
+ ),
120
+ types.binaryExpression(
121
+ '>',
122
+ types.memberExpression(
123
+ types.memberExpression(f, types.identifier('children')),
124
+ types.identifier('length')
125
+ ),
126
+ types.numericLiteral(0)
127
+ ),
128
+ emptyDestination
129
+ )
130
+ )
131
+ }
132
+
133
+ // The inspector authors filters as a TREE — a root `and` group whose children
134
+ // are conditions or nested `or` groups. Emitting the tree (rather than mapping
135
+ // each entry as if it were a condition, which turned every group into an empty
136
+ // `{ source: '', destination: '', operand: '' }` row that the predicate then
137
+ // dropped) is what lets the data-source runtime honour the filter at all.
138
+ const buildFilterNodeExpression = (
139
+ entry: { type?: string; operator?: string; children?: unknown[] } & {
140
+ source?: string
141
+ destination?: unknown
142
+ operand?: string
143
+ },
144
+ dynamicReferencePrefixMap: Record<string, string>
145
+ ): types.Expression => {
146
+ if (entry && entry.type === 'group' && Array.isArray(entry.children)) {
147
+ const childExpressions = entry.children.map((child) =>
148
+ buildFilterNodeExpression(child as never, dynamicReferencePrefixMap)
149
+ )
150
+ return types.objectExpression([
151
+ types.objectProperty(types.identifier('type'), types.stringLiteral('group')),
152
+ types.objectProperty(
153
+ types.identifier('operator'),
154
+ types.stringLiteral(entry.operator === 'or' ? 'or' : 'and')
155
+ ),
156
+ types.objectProperty(
157
+ types.identifier('children'),
158
+ types.callExpression(
159
+ types.memberExpression(
160
+ types.arrayExpression(childExpressions),
161
+ types.identifier('filter')
162
+ ),
163
+ [buildSurvivingFilterNodePredicate()]
164
+ )
165
+ ),
166
+ ])
167
+ }
168
+
169
+ return types.objectExpression([
170
+ types.objectProperty(types.identifier('type'), types.stringLiteral('condition')),
171
+ types.objectProperty(types.identifier('source'), types.stringLiteral(entry?.source || '')),
172
+ types.objectProperty(
173
+ types.identifier('destination'),
174
+ ASTUtils.convertFilterDestinationToExpression(entry?.destination, {
175
+ dynamicReferencePrefixMap,
176
+ })
177
+ ),
178
+ types.objectProperty(types.identifier('operand'), types.stringLiteral(entry?.operand || '')),
179
+ ])
180
+ }
181
+
107
182
  // Global references in the UIDL come in two shapes:
108
183
  // Shape A: { id: "ecommerce", refPath: ["Cart", "total"] }
109
184
  // Shape B: { id: undefined, refPath: ["E-commerce", "Settings", "Delivery", "..."] }
@@ -1822,24 +1897,8 @@ const generateDataSourceNode: NodeToJSX<
1822
1897
  if (property.type === 'static') {
1823
1898
  // Special handling for filters array - convert dynamic destinations
1824
1899
  if (attrKey === 'filters' && Array.isArray(property.content)) {
1825
- const filterEntries = property.content.map(
1826
- (filter: { source?: string; destination?: unknown; operand?: string }) =>
1827
- types.objectExpression([
1828
- types.objectProperty(
1829
- types.identifier('source'),
1830
- types.stringLiteral(filter.source || '')
1831
- ),
1832
- types.objectProperty(
1833
- types.identifier('destination'),
1834
- ASTUtils.convertFilterDestinationToExpression(filter.destination, {
1835
- dynamicReferencePrefixMap: options.dynamicReferencePrefixMap,
1836
- })
1837
- ),
1838
- types.objectProperty(
1839
- types.identifier('operand'),
1840
- types.stringLiteral(filter.operand || '')
1841
- ),
1842
- ])
1900
+ const filterEntries = property.content.map((filter: never) =>
1901
+ buildFilterNodeExpression(filter, options.dynamicReferencePrefixMap)
1843
1902
  )
1844
1903
  // Drop conditions whose destination resolves to an empty value at
1845
1904
  // runtime (empty string / null / undefined, or an empty
@@ -1848,15 +1907,23 @@ const generateDataSourceNode: NodeToJSX<
1848
1907
  // path's `buildNonEmptyDestinationPredicate` (kept inline here
1849
1908
  // because teleport-plugin-common must not depend on the
1850
1909
  // next-data-source plugin).
1910
+ // JSON.stringify because these params are handed to
1911
+ // `new URLSearchParams(params)`, which would otherwise stringify the
1912
+ // array to '[object Object]' and lose every filter in transit.
1851
1913
  acc.push(
1852
1914
  types.objectProperty(
1853
1915
  types.stringLiteral(attrKey),
1854
1916
  types.callExpression(
1855
- types.memberExpression(
1856
- types.arrayExpression(filterEntries),
1857
- types.identifier('filter')
1858
- ),
1859
- [buildNonEmptyFilterDestinationPredicate()]
1917
+ types.memberExpression(types.identifier('JSON'), types.identifier('stringify')),
1918
+ [
1919
+ types.callExpression(
1920
+ types.memberExpression(
1921
+ types.arrayExpression(filterEntries),
1922
+ types.identifier('filter')
1923
+ ),
1924
+ [buildSurvivingFilterNodePredicate()]
1925
+ ),
1926
+ ]
1860
1927
  )
1861
1928
  )
1862
1929
  )