@teleporthq/teleport-plugin-next-data-source 0.42.0 → 0.42.3

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.
Files changed (61) hide show
  1. package/COUNT_API_FIX.md +185 -0
  2. package/SEARCH_FIX_SUMMARY.md +96 -0
  3. package/dist/cjs/count-fetchers.d.ts.map +1 -1
  4. package/dist/cjs/count-fetchers.js +1 -1
  5. package/dist/cjs/count-fetchers.js.map +1 -1
  6. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  7. package/dist/cjs/fetchers/clickhouse.js +1 -1
  8. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  9. package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
  10. package/dist/cjs/fetchers/firestore.js +1 -1
  11. package/dist/cjs/fetchers/firestore.js.map +1 -1
  12. package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
  13. package/dist/cjs/fetchers/javascript.js +1 -1
  14. package/dist/cjs/fetchers/javascript.js.map +1 -1
  15. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  16. package/dist/cjs/fetchers/redshift.js +3 -1
  17. package/dist/cjs/fetchers/redshift.js.map +1 -1
  18. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  19. package/dist/cjs/fetchers/rest-api.js +2 -2
  20. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  21. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  22. package/dist/cjs/fetchers/turso.js +1 -1
  23. package/dist/cjs/fetchers/turso.js.map +1 -1
  24. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  25. package/dist/cjs/pagination-plugin.js +280 -165
  26. package/dist/cjs/pagination-plugin.js.map +1 -1
  27. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  28. package/dist/esm/count-fetchers.d.ts.map +1 -1
  29. package/dist/esm/count-fetchers.js +1 -1
  30. package/dist/esm/count-fetchers.js.map +1 -1
  31. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  32. package/dist/esm/fetchers/clickhouse.js +1 -1
  33. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  34. package/dist/esm/fetchers/firestore.d.ts.map +1 -1
  35. package/dist/esm/fetchers/firestore.js +1 -1
  36. package/dist/esm/fetchers/firestore.js.map +1 -1
  37. package/dist/esm/fetchers/javascript.d.ts.map +1 -1
  38. package/dist/esm/fetchers/javascript.js +1 -1
  39. package/dist/esm/fetchers/javascript.js.map +1 -1
  40. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  41. package/dist/esm/fetchers/redshift.js +3 -1
  42. package/dist/esm/fetchers/redshift.js.map +1 -1
  43. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  44. package/dist/esm/fetchers/rest-api.js +2 -2
  45. package/dist/esm/fetchers/rest-api.js.map +1 -1
  46. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  47. package/dist/esm/fetchers/turso.js +1 -1
  48. package/dist/esm/fetchers/turso.js.map +1 -1
  49. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  50. package/dist/esm/pagination-plugin.js +280 -165
  51. package/dist/esm/pagination-plugin.js.map +1 -1
  52. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +2 -2
  54. package/src/count-fetchers.ts +2 -1
  55. package/src/fetchers/clickhouse.ts +12 -6
  56. package/src/fetchers/firestore.ts +45 -13
  57. package/src/fetchers/javascript.ts +48 -13
  58. package/src/fetchers/redshift.ts +32 -9
  59. package/src/fetchers/rest-api.ts +68 -6
  60. package/src/fetchers/turso.ts +46 -16
  61. package/src/pagination-plugin.ts +440 -296
@@ -75,7 +75,7 @@ var array_mapper_pagination_1 = require("./array-mapper-pagination");
75
75
  var utils_1 = require("./utils");
76
76
  var createNextArrayMapperPaginationPlugin = function () {
77
77
  var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
78
- var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, _a, paginatedMappers, searchOnlyMappers, paginationOnlyMappers, detectedPaginations, detectedSearchOnly, paginationInfos, getStaticPropsChunk, isPage, isComponent, opts, perPageMap, searchConfigMap, queryColumnsMap, hasSearchEnabled, firstReturnIndex, insertIndex, dataSourceToInfos_1, searchOnlyDataSources;
78
+ var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, _a, paginatedMappers, searchOnlyMappers, paginationOnlyMappers, detectedPaginations, detectedSearchOnly, paginationInfos, getStaticPropsChunk, isPage, isComponent, opts, perPageMap, searchConfigMap, queryColumnsMap, stateDeclarations, hasSearchEnabled, firstReturnIndex, insertIndex, dataSourceToInfos_1, componentUseEffects_1, componentReturnIndex, componentEffectsInsertIndex_1, searchOnlyDataSources;
79
79
  var _b, _c, _d;
80
80
  return __generator(this, function (_e) {
81
81
  uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
@@ -159,6 +159,7 @@ var createNextArrayMapperPaginationPlugin = function () {
159
159
  perPageMap = ((_b = opts.paginationConfig) === null || _b === void 0 ? void 0 : _b.perPageMap) || new Map();
160
160
  searchConfigMap = ((_c = opts.paginationConfig) === null || _c === void 0 ? void 0 : _c.searchConfigMap) || new Map();
161
161
  queryColumnsMap = ((_d = opts.paginationConfig) === null || _d === void 0 ? void 0 : _d.queryColumnsMap) || new Map();
162
+ stateDeclarations = [];
162
163
  detectedPaginations.forEach(function (detected, index) {
163
164
  var paginationNodeId = "pg_".concat(index);
164
165
  // Use arrayMapperRenderProp if available, otherwise fall back to dataSourceIdentifier
@@ -169,6 +170,37 @@ var createNextArrayMapperPaginationPlugin = function () {
169
170
  var queryColumns = queryColumnsMap.get(detected.dataSourceIdentifier);
170
171
  var info = (0, array_mapper_pagination_1.generatePaginationLogic)(paginationNodeId, detected.dataSourceIdentifier, perPage, searchConfig, queryColumns);
171
172
  paginationInfos.push(info);
173
+ // Add refs to track first render for each useEffect (add first)
174
+ if (info.searchEnabled) {
175
+ var skipCountFetchOnMountRefVar = "skipCountFetchOnMount_pg_".concat(index);
176
+ var skipCountFetchRefAST = types.variableDeclaration('const', [
177
+ types.variableDeclarator(types.identifier(skipCountFetchOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
178
+ ]);
179
+ stateDeclarations.push(skipCountFetchRefAST);
180
+ info.skipCountFetchOnMountRefVar = skipCountFetchOnMountRefVar;
181
+ var skipDebounceOnMountRefVar = "skipDebounceOnMount_pg_".concat(index);
182
+ var skipDebounceRefAST = types.variableDeclaration('const', [
183
+ types.variableDeclarator(types.identifier(skipDebounceOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
184
+ ]);
185
+ stateDeclarations.push(skipDebounceRefAST);
186
+ info.skipDebounceOnMountRefVar = skipDebounceOnMountRefVar;
187
+ }
188
+ // Add maxPages state
189
+ var maxPagesStateVar = "".concat(info.pageStateVar.replace('_page', ''), "_maxPages");
190
+ var setMaxPagesStateVar = "set".concat(maxPagesStateVar.charAt(0).toUpperCase() + maxPagesStateVar.slice(1));
191
+ // For pages: initialize from props (with pagination-specific prop name), for components: initialize to 0
192
+ var maxPagesInitValue = isPage
193
+ ? types.logicalExpression('||', types.optionalMemberExpression(types.identifier('props'), types.identifier("".concat(info.dataSourceIdentifier, "_pg_").concat(index, "_maxPages")), false, true), types.numericLiteral(0))
194
+ : types.numericLiteral(0);
195
+ var maxPagesStateAST = types.variableDeclaration('const', [
196
+ types.variableDeclarator(types.arrayPattern([
197
+ types.identifier(maxPagesStateVar),
198
+ types.identifier(setMaxPagesStateVar),
199
+ ]), types.callExpression(types.identifier('useState'), [maxPagesInitValue])),
200
+ ]);
201
+ stateDeclarations.push(maxPagesStateAST);
202
+ info.maxPagesStateVar = maxPagesStateVar;
203
+ info.setMaxPagesStateVar = setMaxPagesStateVar;
172
204
  // If both pagination and search are enabled, combine them into a single state object
173
205
  if (info.searchEnabled && info.searchQueryVar && info.setSearchQueryVar) {
174
206
  // Combined state: { page: 1, debouncedQuery: '' }
@@ -185,7 +217,7 @@ var createNextArrayMapperPaginationPlugin = function () {
185
217
  ]),
186
218
  ])),
187
219
  ]);
188
- blockStatement.body.unshift(combinedStateAST);
220
+ stateDeclarations.push(combinedStateAST);
189
221
  // Still need the immediate search query state for the input
190
222
  var searchStateAST = types.variableDeclaration('const', [
191
223
  types.variableDeclarator(types.arrayPattern([
@@ -193,7 +225,7 @@ var createNextArrayMapperPaginationPlugin = function () {
193
225
  types.identifier(info.setSearchQueryVar),
194
226
  ]), types.callExpression(types.identifier('useState'), [types.stringLiteral('')])),
195
227
  ]);
196
- blockStatement.body.unshift(searchStateAST);
228
+ stateDeclarations.push(searchStateAST);
197
229
  info.combinedStateVar = combinedStateVar;
198
230
  info.setCombinedStateVar = setCombinedStateVar;
199
231
  }
@@ -205,40 +237,13 @@ var createNextArrayMapperPaginationPlugin = function () {
205
237
  types.identifier(info.setPageStateVar),
206
238
  ]), types.callExpression(types.identifier('useState'), [types.numericLiteral(1)])),
207
239
  ]);
208
- blockStatement.body.unshift(pageStateAST);
209
- }
210
- // Add maxPages state
211
- var maxPagesStateVar = "".concat(info.pageStateVar.replace('_page', ''), "_maxPages");
212
- var setMaxPagesStateVar = "set".concat(maxPagesStateVar.charAt(0).toUpperCase() + maxPagesStateVar.slice(1));
213
- // For pages: initialize from props (with pagination-specific prop name), for components: initialize to 0
214
- var maxPagesInitValue = isPage
215
- ? types.logicalExpression('||', types.optionalMemberExpression(types.identifier('props'), types.identifier("".concat(info.dataSourceIdentifier, "_pg_").concat(index, "_maxPages")), false, true), types.numericLiteral(0))
216
- : types.numericLiteral(0);
217
- var maxPagesStateAST = types.variableDeclaration('const', [
218
- types.variableDeclarator(types.arrayPattern([
219
- types.identifier(maxPagesStateVar),
220
- types.identifier(setMaxPagesStateVar),
221
- ]), types.callExpression(types.identifier('useState'), [maxPagesInitValue])),
222
- ]);
223
- blockStatement.body.unshift(maxPagesStateAST);
224
- info.maxPagesStateVar = maxPagesStateVar;
225
- info.setMaxPagesStateVar = setMaxPagesStateVar;
226
- // Add refs to track first render for each useEffect
227
- if (info.searchEnabled) {
228
- var skipDebounceOnMountRefVar = "skipDebounceOnMount_pg_".concat(index);
229
- var skipDebounceRefAST = types.variableDeclaration('const', [
230
- types.variableDeclarator(types.identifier(skipDebounceOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
231
- ]);
232
- blockStatement.body.unshift(skipDebounceRefAST);
233
- info.skipDebounceOnMountRefVar = skipDebounceOnMountRefVar;
234
- var skipCountFetchOnMountRefVar = "skipCountFetchOnMount_pg_".concat(index);
235
- var skipCountFetchRefAST = types.variableDeclaration('const', [
236
- types.variableDeclarator(types.identifier(skipCountFetchOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
237
- ]);
238
- blockStatement.body.unshift(skipCountFetchRefAST);
239
- info.skipCountFetchOnMountRefVar = skipCountFetchOnMountRefVar;
240
+ stateDeclarations.push(pageStateAST);
240
241
  }
241
242
  });
243
+ // Add all state declarations at once to the beginning in correct order
244
+ stateDeclarations.reverse().forEach(function (stateDecl) {
245
+ blockStatement.body.unshift(stateDecl);
246
+ });
242
247
  hasSearchEnabled = paginationInfos.some(function (info) { return info.searchEnabled; });
243
248
  if (hasSearchEnabled && !dependencies.useEffect) {
244
249
  dependencies.useEffect = {
@@ -288,74 +293,75 @@ var createNextArrayMapperPaginationPlugin = function () {
288
293
  ]));
289
294
  blockStatement.body.splice(insertIndex, 0, debounceEffect);
290
295
  // Add useEffect to refetch count when search changes (for both pages and components)
291
- if (info.queryColumns && info.queryColumns.length > 0) {
292
- var detected = detectedPaginations.find(function (d) { return d.dataSourceIdentifier === info.dataSourceIdentifier; });
293
- if (!detected) {
294
- return;
295
- }
296
- var resourceDefAttr = detected.dataProviderJSX.openingElement.attributes.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'resourceDefinition'; });
297
- if (resourceDefAttr &&
298
- resourceDefAttr.value &&
299
- resourceDefAttr.value.type === 'JSXExpressionContainer') {
300
- var resourceDef = resourceDefAttr.value.expression;
301
- if (resourceDef.type === 'ObjectExpression') {
302
- var dataSourceIdProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'dataSourceId'; });
303
- var tableNameProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'tableName'; });
304
- var dataSourceTypeProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'dataSourceType'; });
305
- if (dataSourceIdProp && tableNameProp && dataSourceTypeProp) {
306
- var dataSourceId = dataSourceIdProp.value.value;
307
- var tableName = tableNameProp.value.value;
308
- var dataSourceType = dataSourceTypeProp.value.value;
309
- var fileName = "".concat(dataSourceType, "-").concat(tableName, "-").concat(dataSourceId.substring(0, 8));
310
- var setMaxPagesStateVar = info.setMaxPagesStateVar;
311
- // Create useEffect to refetch count when debounced search changes
312
- var skipCountFetchOnMountRefVar = info.skipCountFetchOnMountRefVar;
313
- var combinedStateVar = info.combinedStateVar;
314
- var refetchCountEffect = types.expressionStatement(types.callExpression(types.identifier('useEffect'), [
315
- types.arrowFunctionExpression([], types.blockStatement([
316
- types.ifStatement(types.memberExpression(types.identifier(skipCountFetchOnMountRefVar), types.identifier('current')), types.blockStatement([
317
- types.expressionStatement(types.assignmentExpression('=', types.memberExpression(types.identifier(skipCountFetchOnMountRefVar), types.identifier('current')), types.booleanLiteral(false))),
318
- types.returnStatement(),
319
- ])),
320
- types.expressionStatement(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.callExpression(types.identifier('fetch'), [
321
- types.templateLiteral([
322
- types.templateElement({
323
- raw: "/api/".concat(fileName, "-count?"),
324
- cooked: "/api/".concat(fileName, "-count?"),
325
- }),
326
- types.templateElement({ raw: '', cooked: '' }),
327
- ], [
328
- types.newExpression(types.identifier('URLSearchParams'), [
329
- types.objectExpression([
330
- types.objectProperty(types.identifier('query'), types.memberExpression(types.identifier(combinedStateVar), types.identifier('debouncedQuery'))),
331
- types.objectProperty(types.identifier('queryColumns'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
332
- types.arrayExpression(info.queryColumns.map(function (col) {
333
- return types.stringLiteral(col);
334
- })),
335
- ])),
336
- ]),
337
- ]),
296
+ var detected = detectedPaginations.find(function (d) { return d.dataSourceIdentifier === info.dataSourceIdentifier; });
297
+ if (!detected) {
298
+ return;
299
+ }
300
+ var resourceDefAttr = detected.dataProviderJSX.openingElement.attributes.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'resourceDefinition'; });
301
+ if (resourceDefAttr &&
302
+ resourceDefAttr.value &&
303
+ resourceDefAttr.value.type === 'JSXExpressionContainer') {
304
+ var resourceDef = resourceDefAttr.value.expression;
305
+ if (resourceDef.type === 'ObjectExpression') {
306
+ var dataSourceIdProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'dataSourceId'; });
307
+ var tableNameProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'tableName'; });
308
+ var dataSourceTypeProp = resourceDef.properties.find(function (p) { return p.type === 'ObjectProperty' && p.key.value === 'dataSourceType'; });
309
+ if (dataSourceIdProp && tableNameProp && dataSourceTypeProp) {
310
+ var dataSourceId = dataSourceIdProp.value.value;
311
+ var tableName = tableNameProp.value.value;
312
+ var dataSourceType = dataSourceTypeProp.value.value;
313
+ var fileName = "".concat(dataSourceType, "-").concat(tableName, "-").concat(dataSourceId.substring(0, 8));
314
+ var setMaxPagesStateVar = info.setMaxPagesStateVar;
315
+ // Create useEffect to refetch count when debounced search changes
316
+ var skipCountFetchOnMountRefVar = info.skipCountFetchOnMountRefVar;
317
+ var combinedStateVar = info.combinedStateVar;
318
+ // Build URLSearchParams properties - query is always included, queryColumns is optional
319
+ var urlSearchParamsProperties = [
320
+ types.objectProperty(types.identifier('query'), types.memberExpression(types.identifier(combinedStateVar), types.identifier('debouncedQuery'))),
321
+ ];
322
+ // Add queryColumns only if they exist
323
+ if (info.queryColumns && info.queryColumns.length > 0) {
324
+ urlSearchParamsProperties.push(types.objectProperty(types.identifier('queryColumns'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
325
+ types.arrayExpression(info.queryColumns.map(function (col) { return types.stringLiteral(col); })),
326
+ ])));
327
+ }
328
+ var refetchCountEffect = types.expressionStatement(types.callExpression(types.identifier('useEffect'), [
329
+ types.arrowFunctionExpression([], types.blockStatement([
330
+ types.ifStatement(types.memberExpression(types.identifier(skipCountFetchOnMountRefVar), types.identifier('current')), types.blockStatement([
331
+ types.expressionStatement(types.assignmentExpression('=', types.memberExpression(types.identifier(skipCountFetchOnMountRefVar), types.identifier('current')), types.booleanLiteral(false))),
332
+ types.returnStatement(),
333
+ ])),
334
+ types.expressionStatement(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.callExpression(types.identifier('fetch'), [
335
+ types.templateLiteral([
336
+ types.templateElement({
337
+ raw: "/api/".concat(fileName, "-count?"),
338
+ cooked: "/api/".concat(fileName, "-count?"),
339
+ }),
340
+ types.templateElement({ raw: '', cooked: '' }),
341
+ ], [
342
+ types.newExpression(types.identifier('URLSearchParams'), [
343
+ types.objectExpression(urlSearchParamsProperties),
338
344
  ]),
339
- ]), types.identifier('then')), [
340
- types.arrowFunctionExpression([types.identifier('res')], types.callExpression(types.memberExpression(types.identifier('res'), types.identifier('json')), [])),
341
- ]), types.identifier('then')), [
342
- types.arrowFunctionExpression([types.identifier('data')], types.blockStatement([
343
- types.ifStatement(types.logicalExpression('&&', types.identifier('data'), types.binaryExpression('in', types.stringLiteral('count'), types.identifier('data'))), types.blockStatement([
344
- types.expressionStatement(types.callExpression(types.identifier(setMaxPagesStateVar), [
345
- types.conditionalExpression(types.binaryExpression('===', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(0)), types.numericLiteral(0), types.callExpression(types.memberExpression(types.identifier('Math'), types.identifier('ceil')), [
346
- types.binaryExpression('/', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(info.perPage)),
347
- ])),
345
+ ]),
346
+ ]), types.identifier('then')), [
347
+ types.arrowFunctionExpression([types.identifier('res')], types.callExpression(types.memberExpression(types.identifier('res'), types.identifier('json')), [])),
348
+ ]), types.identifier('then')), [
349
+ types.arrowFunctionExpression([types.identifier('data')], types.blockStatement([
350
+ types.ifStatement(types.logicalExpression('&&', types.identifier('data'), types.binaryExpression('in', types.stringLiteral('count'), types.identifier('data'))), types.blockStatement([
351
+ types.expressionStatement(types.callExpression(types.identifier(setMaxPagesStateVar), [
352
+ types.conditionalExpression(types.binaryExpression('===', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(0)), types.numericLiteral(0), types.callExpression(types.memberExpression(types.identifier('Math'), types.identifier('ceil')), [
353
+ types.binaryExpression('/', types.memberExpression(types.identifier('data'), types.identifier('count')), types.numericLiteral(info.perPage)),
348
354
  ])),
349
355
  ])),
350
356
  ])),
351
357
  ])),
352
358
  ])),
353
- types.arrayExpression([
354
- types.memberExpression(types.identifier(combinedStateVar), types.identifier('debouncedQuery')),
355
- ]),
356
- ]));
357
- blockStatement.body.splice(insertIndex, 0, refetchCountEffect);
358
- }
359
+ ])),
360
+ types.arrayExpression([
361
+ types.memberExpression(types.identifier(combinedStateVar), types.identifier('debouncedQuery')),
362
+ ]),
363
+ ]));
364
+ blockStatement.body.splice(insertIndex, 0, refetchCountEffect);
359
365
  }
360
366
  }
361
367
  }
@@ -405,7 +411,7 @@ var createNextArrayMapperPaginationPlugin = function () {
405
411
  }
406
412
  dataSourceToInfos_1.get(info.dataSourceIdentifier).push({ info: info, detected: detected, fileName: fileName });
407
413
  });
408
- // Create ONE useEffect per unique data source
414
+ componentUseEffects_1 = [];
409
415
  dataSourceToInfos_1.forEach(function (infos) {
410
416
  var fileName = infos[0].fileName;
411
417
  // Create array of setState calls - one for each pagination using this data source
@@ -433,7 +439,13 @@ var createNextArrayMapperPaginationPlugin = function () {
433
439
  ])),
434
440
  types.arrayExpression([]),
435
441
  ]));
436
- blockStatement.body.unshift(useEffectAST);
442
+ componentUseEffects_1.push(useEffectAST);
443
+ });
444
+ componentReturnIndex = blockStatement.body.findIndex(function (stmt) { return stmt.type === 'ReturnStatement'; });
445
+ componentEffectsInsertIndex_1 = componentReturnIndex !== -1 ? componentReturnIndex : blockStatement.body.length;
446
+ // Insert in reverse order to maintain correct order
447
+ componentUseEffects_1.reverse().forEach(function (effect) {
448
+ blockStatement.body.splice(componentEffectsInsertIndex_1, 0, effect);
437
449
  });
438
450
  }
439
451
  createAPIRoutesForPaginatedDataSources(uidl.node, options.dataSources, componentChunk, options.extractedResources, paginationInfos, isComponent);
@@ -447,7 +459,7 @@ var createNextArrayMapperPaginationPlugin = function () {
447
459
  }
448
460
  searchOnlyDataSources = detectedSearchOnly;
449
461
  if (searchOnlyDataSources.length > 0) {
450
- handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, searchConfigMap, queryColumnsMap, insertIndex, dependencies);
462
+ handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, searchConfigMap, queryColumnsMap, dependencies);
451
463
  // Create API routes for search-only data sources
452
464
  createAPIRoutesForSearchOnlyDataSources(uidl.node, options.dataSources, componentChunk, options.extractedResources, searchOnlyDataSources);
453
465
  }
@@ -457,8 +469,66 @@ var createNextArrayMapperPaginationPlugin = function () {
457
469
  return paginationPlugin;
458
470
  };
459
471
  exports.createNextArrayMapperPaginationPlugin = createNextArrayMapperPaginationPlugin;
472
+ function findParentNode(root, target, currentParent) {
473
+ if (currentParent === void 0) { currentParent = null; }
474
+ if (!root || !target) {
475
+ return null;
476
+ }
477
+ if (root === target) {
478
+ return currentParent;
479
+ }
480
+ if (root.type === 'JSXElement' || root.type === 'JSXFragment') {
481
+ if (root.children && Array.isArray(root.children)) {
482
+ for (var _i = 0, _a = root.children; _i < _a.length; _i++) {
483
+ var child = _a[_i];
484
+ var found = findParentNode(child, target, root);
485
+ if (found !== null) {
486
+ return found;
487
+ }
488
+ }
489
+ }
490
+ }
491
+ else if (root.type === 'JSXExpressionContainer') {
492
+ if (root.expression) {
493
+ var found = findParentNode(root.expression, target, root);
494
+ if (found !== null) {
495
+ return found;
496
+ }
497
+ }
498
+ }
499
+ else if (root.type === 'BlockStatement') {
500
+ if (root.body && Array.isArray(root.body)) {
501
+ for (var _b = 0, _c = root.body; _b < _c.length; _b++) {
502
+ var stmt = _c[_b];
503
+ var found = findParentNode(stmt, target, root);
504
+ if (found !== null) {
505
+ return found;
506
+ }
507
+ }
508
+ }
509
+ }
510
+ else if (root.type === 'ReturnStatement') {
511
+ if (root.argument) {
512
+ var found = findParentNode(root.argument, target, root);
513
+ if (found !== null) {
514
+ return found;
515
+ }
516
+ }
517
+ }
518
+ else if (root.type === 'ConditionalExpression') {
519
+ var foundConsequent = findParentNode(root.consequent, target, root);
520
+ if (foundConsequent !== null) {
521
+ return foundConsequent;
522
+ }
523
+ var foundAlternate = findParentNode(root.alternate, target, root);
524
+ if (foundAlternate !== null) {
525
+ return foundAlternate;
526
+ }
527
+ }
528
+ return null;
529
+ }
460
530
  function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
461
- var dataProviderMap = new Map();
531
+ var dataProviderList = [];
462
532
  var arrayMapperInfoMap = new Map();
463
533
  if (uidlNode) {
464
534
  var collectArrayMapperInfo_1 = function (node) {
@@ -624,32 +694,35 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
624
694
  var dataProviderIdentifier = nameAttr.value.expression.value;
625
695
  var paginationNodeInfo = null;
626
696
  var searchInputInfo = null;
627
- // Look through parent's children for siblings
628
- if (parent && parent.children && Array.isArray(parent.children)) {
629
- parent.children.forEach(function (sibling) {
697
+ var findSearchAndPaginationInScope = function (scopeNode, skipNode) {
698
+ if (skipNode === void 0) { skipNode = null; }
699
+ if (!scopeNode || !scopeNode.children || !Array.isArray(scopeNode.children)) {
700
+ return;
701
+ }
702
+ scopeNode.children.forEach(function (child) {
630
703
  var _a, _b, _c;
631
- if (sibling === dataProvider) {
704
+ if (child === skipNode) {
632
705
  return;
633
706
  }
634
- if (sibling.type === 'JSXElement') {
635
- var siblingClassName = getClassName(((_a = sibling.openingElement) === null || _a === void 0 ? void 0 : _a.attributes) || []);
636
- var siblingElementName = (_c = (_b = sibling.openingElement) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.name;
707
+ if (child.type === 'JSXElement') {
708
+ var childClassName = getClassName(((_a = child.openingElement) === null || _a === void 0 ? void 0 : _a.attributes) || []);
709
+ var childElementName = (_c = (_b = child.openingElement) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.name;
637
710
  // Found pagination node
638
- if (siblingClassName && siblingClassName.includes('cms-pagination-node')) {
639
- var prevClass = findChildWithClass(sibling, 'previous');
640
- var nextClass = findChildWithClass(sibling, 'next');
711
+ if (childClassName && childClassName.includes('cms-pagination-node')) {
712
+ var prevClass = findChildWithClass(child, 'previous');
713
+ var nextClass = findChildWithClass(child, 'next');
641
714
  if (prevClass || nextClass) {
642
715
  paginationNodeInfo = {
643
- class: siblingClassName,
716
+ class: childClassName,
644
717
  prevClass: prevClass,
645
718
  nextClass: nextClass,
646
719
  };
647
720
  }
648
721
  }
649
722
  // Found search container - search for input inside it
650
- if (siblingClassName && siblingClassName.includes('data-source-search-node')) {
651
- if (sibling.children && Array.isArray(sibling.children)) {
652
- sibling.children.forEach(function (searchChild) {
723
+ if (childClassName && childClassName.includes('data-source-search-node')) {
724
+ if (child.children && Array.isArray(child.children)) {
725
+ child.children.forEach(function (searchChild) {
653
726
  var _a, _b, _c;
654
727
  if (searchChild.type === 'JSXElement') {
655
728
  var searchChildElementName = (_b = (_a = searchChild.openingElement) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.name;
@@ -666,21 +739,32 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
666
739
  });
667
740
  }
668
741
  }
669
- // Also check if search input is a direct sibling
670
- if (siblingClassName &&
671
- siblingClassName.includes('search-input') &&
672
- siblingElementName === 'input') {
742
+ // Also check if search input is a direct child
743
+ if (childClassName &&
744
+ childClassName.includes('search-input') &&
745
+ childElementName === 'input') {
673
746
  searchInputInfo = {
674
- class: siblingClassName,
675
- jsx: sibling,
747
+ class: childClassName,
748
+ jsx: child,
676
749
  };
677
750
  }
751
+ if (!searchInputInfo || !paginationNodeInfo) {
752
+ findSearchAndPaginationInScope(child, skipNode);
753
+ }
678
754
  }
679
755
  });
756
+ };
757
+ var currentScope = parent;
758
+ var depth = 0;
759
+ var maxDepth = 5;
760
+ while (currentScope && (!searchInputInfo || !paginationNodeInfo) && depth < maxDepth) {
761
+ findSearchAndPaginationInScope(currentScope, depth === 0 ? dataProvider : null);
762
+ currentScope = findParentNode(blockStatement, currentScope);
763
+ depth++;
680
764
  }
681
765
  // Record the DataProvider with its pagination/search info
682
- var uniqueKey = "".concat(dataProviderIdentifier, "__").concat(arrayMapperRenderProp);
683
- dataProviderMap.set(uniqueKey, {
766
+ // Use array instead of Map to handle multiple DataProviders with same name
767
+ dataProviderList.push({
684
768
  identifier: dataProviderIdentifier,
685
769
  dataProvider: dataProvider,
686
770
  arrayMapperRenderProp: arrayMapperRenderProp,
@@ -695,9 +779,16 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
695
779
  var searchOnlyMappers = [];
696
780
  var paginationOnlyMappers = [];
697
781
  var plainMappers = [];
698
- dataProviderMap.forEach(function (info) {
782
+ dataProviderList.forEach(function (info) {
699
783
  var _a, _b, _c, _d;
700
- if (info.hasPagination && info.hasSearch) {
784
+ // Check UIDL flags for this array mapper
785
+ var uidlInfo = info.arrayMapperRenderProp
786
+ ? arrayMapperInfoMap.get(info.arrayMapperRenderProp)
787
+ : null;
788
+ // Only process pagination/search if UIDL explicitly enables it
789
+ var shouldHavePagination = (uidlInfo === null || uidlInfo === void 0 ? void 0 : uidlInfo.paginated) && info.hasPagination;
790
+ var shouldHaveSearch = (uidlInfo === null || uidlInfo === void 0 ? void 0 : uidlInfo.searchEnabled) && info.hasSearch;
791
+ if (shouldHavePagination && shouldHaveSearch) {
701
792
  // Pagination + Search
702
793
  paginatedMappers.push({
703
794
  paginationNodeClass: info.paginationNode.class,
@@ -710,7 +801,7 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
710
801
  searchInputJSX: (_b = info.searchInput) === null || _b === void 0 ? void 0 : _b.jsx,
711
802
  });
712
803
  }
713
- else if (info.hasPagination && !info.hasSearch) {
804
+ else if (shouldHavePagination && !shouldHaveSearch) {
714
805
  // Pagination only
715
806
  paginationOnlyMappers.push({
716
807
  paginationNodeClass: info.paginationNode.class,
@@ -723,7 +814,7 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
723
814
  searchInputJSX: undefined,
724
815
  });
725
816
  }
726
- else if (!info.hasPagination && info.hasSearch) {
817
+ else if (!shouldHavePagination && shouldHaveSearch) {
727
818
  // Search only
728
819
  searchOnlyMappers.push({
729
820
  paginationNodeClass: '',
@@ -737,7 +828,7 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
737
828
  });
738
829
  }
739
830
  else {
740
- // Plain (no pagination, no search)
831
+ // Plain (no pagination, no search) - UIDL doesn't enable it or no controls found
741
832
  plainMappers.push({
742
833
  paginationNodeClass: '',
743
834
  prevButtonClass: null,
@@ -752,7 +843,9 @@ function detectPaginationsAndSearchFromJSX(blockStatement, uidlNode) {
752
843
  });
753
844
  return { paginatedMappers: paginatedMappers, searchOnlyMappers: searchOnlyMappers, paginationOnlyMappers: paginationOnlyMappers, plainMappers: plainMappers };
754
845
  }
755
- function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, searchConfigMap, queryColumnsMap, insertIndex, dependencies) {
846
+ function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, searchConfigMap, queryColumnsMap, dependencies) {
847
+ var searchOnlyStates = [];
848
+ var searchOnlyEffects = [];
756
849
  searchOnlyDataSources.forEach(function (detected, index) {
757
850
  var searchId = "search_".concat(index);
758
851
  var searchQueryVar = "".concat(searchId, "_query");
@@ -763,11 +856,11 @@ function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, sea
763
856
  var searchConfig = searchConfigMap.get(detected.dataSourceIdentifier);
764
857
  var searchDebounce = (searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchDebounce) || 300;
765
858
  var queryColumns = queryColumnsMap.get(detected.dataSourceIdentifier);
766
- // Add search query state
767
- var searchStateAST = types.variableDeclaration('const', [
768
- types.variableDeclarator(types.arrayPattern([types.identifier(searchQueryVar), types.identifier(setSearchQueryVar)]), types.callExpression(types.identifier('useState'), [types.stringLiteral('')])),
859
+ // Add skip ref
860
+ var skipRefAST = types.variableDeclaration('const', [
861
+ types.variableDeclarator(types.identifier(skipDebounceOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
769
862
  ]);
770
- blockStatement.body.unshift(searchStateAST);
863
+ searchOnlyStates.push(skipRefAST);
771
864
  // Add debounced search state
772
865
  var debouncedSearchStateAST = types.variableDeclaration('const', [
773
866
  types.variableDeclarator(types.arrayPattern([
@@ -775,12 +868,12 @@ function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, sea
775
868
  types.identifier(setDebouncedSearchQueryVar),
776
869
  ]), types.callExpression(types.identifier('useState'), [types.stringLiteral('')])),
777
870
  ]);
778
- blockStatement.body.unshift(debouncedSearchStateAST);
779
- // Add skip ref
780
- var skipRefAST = types.variableDeclaration('const', [
781
- types.variableDeclarator(types.identifier(skipDebounceOnMountRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(true)])),
871
+ searchOnlyStates.push(debouncedSearchStateAST);
872
+ // Add search query state
873
+ var searchStateAST = types.variableDeclaration('const', [
874
+ types.variableDeclarator(types.arrayPattern([types.identifier(searchQueryVar), types.identifier(setSearchQueryVar)]), types.callExpression(types.identifier('useState'), [types.stringLiteral('')])),
782
875
  ]);
783
- blockStatement.body.unshift(skipRefAST);
876
+ searchOnlyStates.push(searchStateAST);
784
877
  // Add useEffect for debouncing
785
878
  if (!dependencies.useEffect) {
786
879
  dependencies.useEffect = {
@@ -812,7 +905,7 @@ function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, sea
812
905
  ])),
813
906
  types.arrayExpression([types.identifier(searchQueryVar)]),
814
907
  ]));
815
- blockStatement.body.splice(insertIndex, 0, debounceEffect);
908
+ searchOnlyEffects.push(debounceEffect);
816
909
  // Modify DataProvider to include search params (even without queryColumns)
817
910
  if (detected.dataProviderJSX) {
818
911
  addSearchParamsToDataProvider(detected.dataProviderJSX, {
@@ -829,6 +922,17 @@ function handleSearchOnlyArrayMappers(blockStatement, searchOnlyDataSources, sea
829
922
  });
830
923
  }
831
924
  });
925
+ // Add all state declarations at the beginning in correct order
926
+ searchOnlyStates.reverse().forEach(function (stateDecl) {
927
+ blockStatement.body.unshift(stateDecl);
928
+ });
929
+ // Recalculate insertIndex after adding states (since unshift shifted everything)
930
+ var newInsertIndex = blockStatement.body.findIndex(function (stmt) { return stmt.type === 'ReturnStatement'; });
931
+ var finalInsertIndex = newInsertIndex !== -1 ? newInsertIndex : blockStatement.body.length;
932
+ // Add all useEffect hooks before the return statement
933
+ searchOnlyEffects.reverse().forEach(function (effect) {
934
+ blockStatement.body.splice(finalInsertIndex, 0, effect);
935
+ });
832
936
  }
833
937
  function addSearchParamsToDataProvider(dataProviderJSX, config) {
834
938
  var _a, _b;
@@ -1063,6 +1167,7 @@ function findChildWithClass(node, classSubstring) {
1063
1167
  return null;
1064
1168
  }
1065
1169
  function modifyPaginationButtons(blockStatement, detectedPaginations, paginationInfos) {
1170
+ var modifiedButtons = new Set();
1066
1171
  var modifyNode = function (node) {
1067
1172
  if (!node) {
1068
1173
  return;
@@ -1070,20 +1175,25 @@ function modifyPaginationButtons(blockStatement, detectedPaginations, pagination
1070
1175
  if (node.type === 'JSXElement') {
1071
1176
  var openingElement = node.openingElement;
1072
1177
  if (openingElement && openingElement.name && openingElement.name.type === 'JSXIdentifier') {
1073
- var className_1 = getClassName(openingElement.attributes);
1074
- if (className_1) {
1075
- detectedPaginations.forEach(function (detected, index) {
1178
+ var className = getClassName(openingElement.attributes);
1179
+ if (className && !modifiedButtons.has(node)) {
1180
+ for (var index = 0; index < detectedPaginations.length; index++) {
1181
+ var detected = detectedPaginations[index];
1076
1182
  var info = paginationInfos[index];
1077
1183
  if (!info) {
1078
- return;
1184
+ continue;
1079
1185
  }
1080
- if (className_1 === detected.prevButtonClass) {
1186
+ if (className === detected.prevButtonClass) {
1081
1187
  convertToButton(node, info, 'prev');
1188
+ modifiedButtons.add(node);
1189
+ break;
1082
1190
  }
1083
- else if (className_1 === detected.nextButtonClass) {
1191
+ else if (className === detected.nextButtonClass) {
1084
1192
  convertToButton(node, info, 'next');
1193
+ modifiedButtons.add(node);
1194
+ break;
1085
1195
  }
1086
- });
1196
+ }
1087
1197
  }
1088
1198
  }
1089
1199
  }
@@ -1101,6 +1211,7 @@ function modifyPaginationButtons(blockStatement, detectedPaginations, pagination
1101
1211
  modifyNode(blockStatement);
1102
1212
  }
1103
1213
  function modifySearchInputs(blockStatement, detectedPaginations, paginationInfos) {
1214
+ var modifiedInputs = new Set();
1104
1215
  var modifyNode = function (node) {
1105
1216
  if (!node) {
1106
1217
  return;
@@ -1108,21 +1219,20 @@ function modifySearchInputs(blockStatement, detectedPaginations, paginationInfos
1108
1219
  if (node.type === 'JSXElement') {
1109
1220
  var openingElement = node.openingElement;
1110
1221
  if (openingElement && openingElement.name && openingElement.name.type === 'JSXIdentifier') {
1111
- var className_2 = getClassName(openingElement.attributes);
1112
- if (className_2) {
1113
- detectedPaginations.forEach(function (detected, index) {
1222
+ var className = getClassName(openingElement.attributes);
1223
+ if (className && !modifiedInputs.has(node)) {
1224
+ for (var index = 0; index < detectedPaginations.length; index++) {
1225
+ var detected = detectedPaginations[index];
1114
1226
  var info = paginationInfos[index];
1115
1227
  if (!info || !info.searchEnabled) {
1116
- return;
1228
+ continue;
1117
1229
  }
1118
- if (className_2 === detected.searchInputClass) {
1230
+ if (className === detected.searchInputClass) {
1119
1231
  addSearchInputHandlers(node, info);
1232
+ modifiedInputs.add(node);
1233
+ break;
1120
1234
  }
1121
- else if (className_2 && className_2.includes('search-input')) {
1122
- // Fallback: match any input with 'search-input' in class
1123
- addSearchInputHandlers(node, info);
1124
- }
1125
- });
1235
+ }
1126
1236
  }
1127
1237
  }
1128
1238
  }
@@ -1426,6 +1536,8 @@ function modifyGetStaticPropsForPagination(chunks, paginationInfos) {
1426
1536
  }
1427
1537
  function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, componentChunk, extractedResources, paginationInfos, isComponent) {
1428
1538
  var paginatedDataSourceIds = new Set(paginationInfos.map(function (info) { return info.dataSourceIdentifier; }));
1539
+ var searchEnabledDataSources = new Set(paginationInfos.filter(function (info) { return info.searchEnabled; }).map(function (info) { return info.dataSourceIdentifier; }));
1540
+ var createdCountRoutes = new Set();
1429
1541
  var traverseForDataSources = function (node) {
1430
1542
  var _a;
1431
1543
  if (!node) {
@@ -1435,8 +1547,9 @@ function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, component
1435
1547
  var renderProp = node.content.renderPropIdentifier;
1436
1548
  if (renderProp && paginatedDataSourceIds.has(renderProp)) {
1437
1549
  (0, utils_1.extractDataSourceIntoNextAPIFolder)(node, dataSources, componentChunk, extractedResources);
1438
- // For components, also create count API route
1439
- if (isComponent) {
1550
+ var hasSearch = searchEnabledDataSources.has(renderProp);
1551
+ var needsCountRoute = isComponent || hasSearch;
1552
+ if (needsCountRoute) {
1440
1553
  var resourceDef = node.content.resourceDefinition;
1441
1554
  if (resourceDef) {
1442
1555
  var dataSourceId = resourceDef.dataSourceId;
@@ -1444,13 +1557,15 @@ function createAPIRoutesForPaginatedDataSources(uidlNode, dataSources, component
1444
1557
  var dataSourceType = resourceDef.dataSourceType;
1445
1558
  var fileName = "".concat(dataSourceType, "-").concat(tableName, "-").concat(dataSourceId.substring(0, 8));
1446
1559
  var countFileName = "".concat(fileName, "-count");
1447
- // Create count API route that exports getCount handler
1448
- extractedResources["api/".concat(countFileName)] = {
1449
- fileName: countFileName,
1450
- fileType: teleport_types_1.FileType.JS,
1451
- path: ['pages', 'api'],
1452
- content: "import dataSource from '../../utils/data-sources/".concat(fileName, "'\n\nexport default dataSource.getCount\n"),
1453
- };
1560
+ if (!createdCountRoutes.has(countFileName)) {
1561
+ extractedResources["api/".concat(countFileName)] = {
1562
+ fileName: countFileName,
1563
+ fileType: teleport_types_1.FileType.JS,
1564
+ path: ['pages', 'api'],
1565
+ content: "import dataSource from '../../utils/data-sources/".concat(fileName, "'\n\nexport default dataSource.getCount\n"),
1566
+ };
1567
+ createdCountRoutes.add(countFileName);
1568
+ }
1454
1569
  }
1455
1570
  }
1456
1571
  }