@teleporthq/teleport-plugin-next-data-source 0.43.71 → 0.43.75

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 (143) hide show
  1. package/__tests__/_helpers/pagination-widget-fixture.ts +8 -1
  2. package/__tests__/blog-adjacent-arranged.test.ts +176 -0
  3. package/__tests__/blog-post-contents.test.ts +212 -0
  4. package/__tests__/blog-post-page-enrichment.test.ts +28 -5
  5. package/__tests__/blog-post-picture-stand-in.test.ts +48 -0
  6. package/__tests__/blog-post-reading-time.test.ts +55 -0
  7. package/__tests__/browser-row-policy.test.ts +5 -1
  8. package/__tests__/content-preset-wiring.test.ts +108 -0
  9. package/__tests__/fixed-list-sort.test.ts +183 -0
  10. package/__tests__/pagination-filter-groups.test.ts +186 -0
  11. package/__tests__/plain-list-sort.test.ts +215 -0
  12. package/__tests__/product-price-sort.ts +47 -19
  13. package/__tests__/rest-api-key-header.test.ts +18 -0
  14. package/__tests__/search-url-sync.test.ts +34 -15
  15. package/__tests__/shared-resource-prefetch.test.ts +65 -0
  16. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  17. package/dist/cjs/fetchers/postgresql.js +2 -1
  18. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  19. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  20. package/dist/cjs/fetchers/rest-api.js +3 -1
  21. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  22. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  23. package/dist/cjs/fetchers/teleport.js +3 -2
  24. package/dist/cjs/fetchers/teleport.js.map +1 -1
  25. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts +7 -6
  26. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -1
  27. package/dist/cjs/fetchers/utils/browser-row-policy.js +7 -33
  28. package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -1
  29. package/dist/cjs/filter-utils.d.ts +19 -7
  30. package/dist/cjs/filter-utils.d.ts.map +1 -1
  31. package/dist/cjs/filter-utils.js +49 -13
  32. package/dist/cjs/filter-utils.js.map +1 -1
  33. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  34. package/dist/cjs/pagination-plugin.js +137 -118
  35. package/dist/cjs/pagination-plugin.js.map +1 -1
  36. package/dist/cjs/product-price-sort.d.ts +0 -9
  37. package/dist/cjs/product-price-sort.d.ts.map +1 -1
  38. package/dist/cjs/product-price-sort.js +1 -13
  39. package/dist/cjs/product-price-sort.js.map +1 -1
  40. package/dist/cjs/row-order.d.ts +19 -0
  41. package/dist/cjs/row-order.d.ts.map +1 -0
  42. package/dist/cjs/row-order.js +45 -0
  43. package/dist/cjs/row-order.js.map +1 -0
  44. package/dist/cjs/sort-utils.d.ts +10 -0
  45. package/dist/cjs/sort-utils.d.ts.map +1 -1
  46. package/dist/cjs/sort-utils.js +22 -1
  47. package/dist/cjs/sort-utils.js.map +1 -1
  48. package/dist/cjs/transformations/blog-adjacent-posts.d.ts +11 -1
  49. package/dist/cjs/transformations/blog-adjacent-posts.d.ts.map +1 -1
  50. package/dist/cjs/transformations/blog-adjacent-posts.js +14 -1
  51. package/dist/cjs/transformations/blog-adjacent-posts.js.map +1 -1
  52. package/dist/cjs/transformations/blog-comments.d.ts +1 -1
  53. package/dist/cjs/transformations/blog-comments.d.ts.map +1 -1
  54. package/dist/cjs/transformations/blog-comments.js +1 -1
  55. package/dist/cjs/transformations/blog-comments.js.map +1 -1
  56. package/dist/cjs/transformations/blog-post.d.ts +14 -0
  57. package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
  58. package/dist/cjs/transformations/blog-post.js +4 -1
  59. package/dist/cjs/transformations/blog-post.js.map +1 -1
  60. package/dist/cjs/transformations/heading-anchors.d.ts +32 -8
  61. package/dist/cjs/transformations/heading-anchors.d.ts.map +1 -1
  62. package/dist/cjs/transformations/heading-anchors.js +34 -10
  63. package/dist/cjs/transformations/heading-anchors.js.map +1 -1
  64. package/dist/cjs/transformations/index.d.ts +24 -12
  65. package/dist/cjs/transformations/index.d.ts.map +1 -1
  66. package/dist/cjs/transformations/index.js +59 -11
  67. package/dist/cjs/transformations/index.js.map +1 -1
  68. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  69. package/dist/cjs/utils.d.ts.map +1 -1
  70. package/dist/cjs/utils.js +52 -3
  71. package/dist/cjs/utils.js.map +1 -1
  72. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  73. package/dist/esm/fetchers/postgresql.js +3 -2
  74. package/dist/esm/fetchers/postgresql.js.map +1 -1
  75. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  76. package/dist/esm/fetchers/rest-api.js +3 -1
  77. package/dist/esm/fetchers/rest-api.js.map +1 -1
  78. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  79. package/dist/esm/fetchers/teleport.js +4 -3
  80. package/dist/esm/fetchers/teleport.js.map +1 -1
  81. package/dist/esm/fetchers/utils/browser-row-policy.d.ts +7 -6
  82. package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -1
  83. package/dist/esm/fetchers/utils/browser-row-policy.js +5 -31
  84. package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -1
  85. package/dist/esm/filter-utils.d.ts +19 -7
  86. package/dist/esm/filter-utils.d.ts.map +1 -1
  87. package/dist/esm/filter-utils.js +46 -12
  88. package/dist/esm/filter-utils.js.map +1 -1
  89. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  90. package/dist/esm/pagination-plugin.js +140 -121
  91. package/dist/esm/pagination-plugin.js.map +1 -1
  92. package/dist/esm/product-price-sort.d.ts +0 -9
  93. package/dist/esm/product-price-sort.d.ts.map +1 -1
  94. package/dist/esm/product-price-sort.js +0 -11
  95. package/dist/esm/product-price-sort.js.map +1 -1
  96. package/dist/esm/row-order.d.ts +19 -0
  97. package/dist/esm/row-order.d.ts.map +1 -0
  98. package/dist/esm/row-order.js +40 -0
  99. package/dist/esm/row-order.js.map +1 -0
  100. package/dist/esm/sort-utils.d.ts +10 -0
  101. package/dist/esm/sort-utils.d.ts.map +1 -1
  102. package/dist/esm/sort-utils.js +20 -0
  103. package/dist/esm/sort-utils.js.map +1 -1
  104. package/dist/esm/transformations/blog-adjacent-posts.d.ts +11 -1
  105. package/dist/esm/transformations/blog-adjacent-posts.d.ts.map +1 -1
  106. package/dist/esm/transformations/blog-adjacent-posts.js +14 -1
  107. package/dist/esm/transformations/blog-adjacent-posts.js.map +1 -1
  108. package/dist/esm/transformations/blog-comments.d.ts +1 -1
  109. package/dist/esm/transformations/blog-comments.d.ts.map +1 -1
  110. package/dist/esm/transformations/blog-comments.js +1 -1
  111. package/dist/esm/transformations/blog-comments.js.map +1 -1
  112. package/dist/esm/transformations/blog-post.d.ts +14 -0
  113. package/dist/esm/transformations/blog-post.d.ts.map +1 -1
  114. package/dist/esm/transformations/blog-post.js +4 -1
  115. package/dist/esm/transformations/blog-post.js.map +1 -1
  116. package/dist/esm/transformations/heading-anchors.d.ts +32 -8
  117. package/dist/esm/transformations/heading-anchors.d.ts.map +1 -1
  118. package/dist/esm/transformations/heading-anchors.js +33 -9
  119. package/dist/esm/transformations/heading-anchors.js.map +1 -1
  120. package/dist/esm/transformations/index.d.ts +24 -12
  121. package/dist/esm/transformations/index.d.ts.map +1 -1
  122. package/dist/esm/transformations/index.js +58 -11
  123. package/dist/esm/transformations/index.js.map +1 -1
  124. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  125. package/dist/esm/utils.d.ts.map +1 -1
  126. package/dist/esm/utils.js +52 -3
  127. package/dist/esm/utils.js.map +1 -1
  128. package/package.json +5 -5
  129. package/src/fetchers/postgresql.ts +11 -15
  130. package/src/fetchers/rest-api.ts +3 -1
  131. package/src/fetchers/teleport.ts +12 -16
  132. package/src/fetchers/utils/browser-row-policy.ts +10 -20
  133. package/src/filter-utils.ts +102 -28
  134. package/src/pagination-plugin.ts +211 -175
  135. package/src/product-price-sort.ts +0 -11
  136. package/src/row-order.ts +54 -0
  137. package/src/sort-utils.ts +25 -0
  138. package/src/transformations/blog-adjacent-posts.ts +89 -3
  139. package/src/transformations/blog-comments.ts +5 -5
  140. package/src/transformations/blog-post.ts +64 -13
  141. package/src/transformations/heading-anchors.ts +79 -16
  142. package/src/transformations/index.ts +80 -13
  143. package/src/utils.ts +74 -3
@@ -1 +1 @@
1
- {"version":3,"file":"filter-utils.d.ts","sourceRoot":"","sources":["../../src/filter-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AA6ErC,eAAO,MAAM,yBAAyB,YAC3B,MAAM;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,4CACjC,OAAO,KAAK,MAAM,UAAU,KACrE,MAAM,cAkBR,CAAA;AAGD,eAAO,MAAM,kBAAkB,gBAChB,MAAM,cAAc,EAAE,WAC1B,MAAM;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,SAAS,4CAC7C,OAAO,KAAK,MAAM,UAAU,KACrE,IAUF,CAAA;AAUD,eAAO,MAAM,kBAAkB,SACvB,MAAM,UAAU,EAAE,QAClB,IAAI,MAAM,CAAC,YACP,MAAM,EAAE,KACjB,IAQF,CAAA;AAaD,eAAO,MAAM,iBAAiB,SACtB,MAAM,UAAU,EAAE,QAClB,IAAI,MAAM,CAAC,WACR,MAAM,EAAE,KAChB,IASF,CAAA"}
1
+ {"version":3,"file":"filter-utils.d.ts","sourceRoot":"","sources":["../../src/filter-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAA;AACzF,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,CAAA;AACvF,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,WAAW,CAAA;AAEvD,eAAO,MAAM,aAAa,UAAW,OAAO,yBAIe,CAAA;AA+H3D,eAAO,MAAM,yBAAyB,YAC3B,WAAW,EAAE,4CACoB,OAAO,KAAK,MAAM,UAAU,KACrE,MAAM,cAIN,CAAA;AAiBH,eAAO,MAAM,+BAA+B,YAAa,WAAW,EAAE,KAAG,MAAM,cAI5E,CAAA;AAGH,eAAO,MAAM,kBAAkB,gBAChB,MAAM,cAAc,EAAE,WAC1B,WAAW,EAAE,GAAG,SAAS,4CACQ,OAAO,KAAK,MAAM,UAAU,KACrE,IAUF,CAAA;AAUD,eAAO,MAAM,kBAAkB,SACvB,MAAM,UAAU,EAAE,QAClB,IAAI,MAAM,CAAC,YACP,MAAM,EAAE,KACjB,IAQF,CAAA;AAaD,eAAO,MAAM,iBAAiB,SACtB,MAAM,UAAU,EAAE,QAClB,IAAI,MAAM,CAAC,WACR,MAAM,EAAE,KAChB,IASF,CAAA"}
@@ -1,4 +1,10 @@
1
1
  import * as types from '@babel/types';
2
+ export var isFilterGroup = function (entry) {
3
+ return !!entry &&
4
+ typeof entry === 'object' &&
5
+ entry.type === 'group' &&
6
+ Array.isArray(entry.children);
7
+ };
2
8
  // Build a single filter entry: { source: '<src>', destination: <destExpr>, operand: '<op>' }
3
9
  var buildFilterEntry = function (source, destinationExpr, operand) {
4
10
  return types.objectExpression([
@@ -7,10 +13,19 @@ var buildFilterEntry = function (source, destinationExpr, operand) {
7
13
  types.objectProperty(types.identifier('operand'), types.stringLiteral(operand)),
8
14
  ]);
9
15
  };
16
+ // { type: 'group', operator: 'and' | 'or', children: <childrenExpr> }
17
+ var buildFilterGroup = function (operator, childrenExpr) {
18
+ return types.objectExpression([
19
+ types.objectProperty(types.identifier('type'), types.stringLiteral('group')),
20
+ types.objectProperty(types.identifier('operator'), types.stringLiteral(operator === 'or' ? 'or' : 'and')),
21
+ types.objectProperty(types.identifier('children'), childrenExpr),
22
+ ]);
23
+ };
10
24
  // Predicate:
11
- // (__f) => __f.destination !== '' && __f.destination !== null &&
12
- // __f.destination !== undefined &&
13
- // !(Array.isArray(__f.destination) && __f.destination.filter(Boolean).length === 0)
25
+ // (__f) => __f.type === 'group' ||
26
+ // (__f.destination !== '' && __f.destination !== null &&
27
+ // __f.destination !== undefined &&
28
+ // !(Array.isArray(__f.destination) && __f.destination.filter(Boolean).length === 0))
14
29
  // Used at runtime to drop filter conditions whose destination resolves to an
15
30
  // empty value. Keeps the page generic: state-bound filters (e.g.
16
31
  // `selectedCategory === ''` after picking "All Categories") and url-bound
@@ -20,19 +35,31 @@ var buildFilterEntry = function (source, destinationExpr, operand) {
20
35
  // string and returns zero rows. The array clause covers array-overlap filters
21
36
  // (e.g. category `CATEGORY_DESCENDANTS[selectedCategory] || []`) whose "All"
22
37
  // reset resolves to `[]` — an empty overlap set must mean "no filter", not
23
- // "match nothing".
38
+ // "match nothing". A group has no destination of its own and is kept; its
39
+ // children carry the same `.filter(...)`, and a group emptied that way is
40
+ // dropped by the fetcher's `normalizeFilterTree`.
24
41
  var buildNonEmptyDestinationPredicate = function () {
25
42
  var f = types.identifier('__f');
26
43
  var dest = types.memberExpression(f, types.identifier('destination'));
27
44
  var isEmptyArray = types.logicalExpression('&&', types.callExpression(types.memberExpression(types.identifier('Array'), types.identifier('isArray')), [dest]), types.binaryExpression('===', types.memberExpression(types.callExpression(types.memberExpression(dest, types.identifier('filter')), [
28
45
  types.identifier('Boolean'),
29
46
  ]), types.identifier('length')), types.numericLiteral(0)));
30
- return types.arrowFunctionExpression([f], types.logicalExpression('&&', types.logicalExpression('&&', types.logicalExpression('&&', types.binaryExpression('!==', dest, types.stringLiteral('')), types.binaryExpression('!==', dest, types.nullLiteral())), types.binaryExpression('!==', dest, types.identifier('undefined'))), types.unaryExpression('!', isEmptyArray)));
47
+ return types.arrowFunctionExpression([f], types.logicalExpression('||', types.binaryExpression('===', types.memberExpression(f, types.identifier('type')), types.stringLiteral('group')), types.logicalExpression('&&', types.logicalExpression('&&', types.logicalExpression('&&', types.binaryExpression('!==', dest, types.stringLiteral('')), types.binaryExpression('!==', dest, types.nullLiteral())), types.binaryExpression('!==', dest, types.identifier('undefined'))), types.unaryExpression('!', isEmptyArray))));
48
+ };
49
+ // `[ entry, ... ].filter(<non-empty destination>)`, recursing into groups so
50
+ // every level of the tree drops its empty conditions at runtime.
51
+ var buildFilteredEntriesArray = function (filters, buildDestinationExpression) {
52
+ var entries = filters.map(function (filter) {
53
+ return isFilterGroup(filter)
54
+ ? buildFilterGroup(filter.operator, buildFilteredEntriesArray(filter.children, buildDestinationExpression))
55
+ : buildFilterEntry(filter.source || '', buildDestinationExpression(filter.destination), filter.operand || '');
56
+ });
57
+ return types.callExpression(types.memberExpression(types.arrayExpression(entries), types.identifier('filter')), [buildNonEmptyDestinationPredicate()]);
31
58
  };
32
59
  // Build the AST for:
33
60
  // JSON.stringify(
34
- // [ {source, destination, operand}, ... ]
35
- // .filter(__f => __f.destination !== '' && __f.destination !== null && __f.destination !== undefined)
61
+ // [ {source, destination, operand}, { type: 'group', operator, children: [...].filter(...) }, ... ]
62
+ // .filter(__f => __f.type === 'group' || (__f.destination !== '' && __f.destination !== null && __f.destination !== undefined))
36
63
  // )
37
64
  //
38
65
  // The `.filter(...)` step is unconditional even when every entry is a static
@@ -41,11 +68,18 @@ var buildNonEmptyDestinationPredicate = function () {
41
68
  // type is added but its empty-value behavior is forgotten don't silently
42
69
  // re-introduce empty-string filters.
43
70
  export var buildFiltersStringifyCall = function (filters, buildDestinationExpression) {
44
- var entries = filters.map(function (filter) {
45
- return buildFilterEntry(filter.source || '', buildDestinationExpression(filter.destination), filter.operand || '');
46
- });
47
- var filteredArray = types.callExpression(types.memberExpression(types.arrayExpression(entries), types.identifier('filter')), [buildNonEmptyDestinationPredicate()]);
48
- return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [filteredArray]);
71
+ return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [buildFilteredEntriesArray(filters, buildDestinationExpression)]);
72
+ };
73
+ // The build-time counterpart for `getStaticProps`: every destination is a
74
+ // literal (the dynamic ones were pruned — see `pruneFilterTree`), so the tree
75
+ // is written out as plain string literals with no runtime `.filter(...)`.
76
+ var buildStaticFilterEntryAST = function (filter) {
77
+ return isFilterGroup(filter)
78
+ ? buildFilterGroup(filter.operator, types.arrayExpression(filter.children.map(buildStaticFilterEntryAST)))
79
+ : buildFilterEntry(filter.source || '', types.stringLiteral(typeof filter.destination === 'string' ? filter.destination : ''), filter.operand || '');
80
+ };
81
+ export var buildStaticFiltersStringifyCall = function (filters) {
82
+ return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [types.arrayExpression(filters.map(buildStaticFilterEntryAST))]);
49
83
  };
50
84
  // Convenience: push `filters: <call>` onto a paramsProps array.
51
85
  export var appendFiltersParam = function (paramsProps, filters, buildDestinationExpression) {
@@ -1 +1 @@
1
- {"version":3,"file":"filter-utils.js","sourceRoot":"","sources":["../../src/filter-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,6FAA6F;AAC7F,IAAM,gBAAgB,GAAG,UACvB,MAAc,EACd,eAAiC,EACjC,OAAe;IAEf,OAAA,KAAK,CAAC,gBAAgB,CAAC;QACrB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7E,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;QACtE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;KAChF,CAAC;AAJF,CAIE,CAAA;AAEJ,aAAa;AACb,mEAAmE;AACnE,8CAA8C;AAC9C,+FAA+F;AAC/F,6EAA6E;AAC7E,iEAAiE;AACjE,0EAA0E;AAC1E,+EAA+E;AAC/E,6EAA6E;AAC7E,yEAAyE;AACzE,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,mBAAmB;AACnB,IAAM,iCAAiC,GAAG;IACxC,IAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACjC,IAAM,IAAI,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAA;IACvE,IAAM,YAAY,GAAG,KAAK,CAAC,iBAAiB,CAC1C,IAAI,EACJ,KAAK,CAAC,cAAc,CAClB,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAC9E,CAAC,IAAI,CAAC,CACP,EACD,KAAK,CAAC,gBAAgB,CACpB,KAAK,EACL,KAAK,CAAC,gBAAgB,CACpB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE;QAC7E,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;KAC5B,CAAC,EACF,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC3B,EACD,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CACxB,CACF,CAAA;IACD,OAAO,KAAK,CAAC,uBAAuB,CAClC,CAAC,CAAC,CAAC,EACH,KAAK,CAAC,iBAAiB,CACrB,IAAI,EACJ,KAAK,CAAC,iBAAiB,CACrB,IAAI,EACJ,KAAK,CAAC,iBAAiB,CACrB,IAAI,EACJ,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,EAC5D,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CACzD,EACD,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CACnE,EACD,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,YAAY,CAAC,CACzC,CACF,CAAA;AACH,CAAC,CAAA;AAED,qBAAqB;AACrB,oBAAoB;AACpB,8CAA8C;AAC9C,4GAA4G;AAC5G,MAAM;AACN,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,yEAAyE;AACzE,qCAAqC;AACrC,MAAM,CAAC,IAAM,yBAAyB,GAAG,UACvC,OAA2E,EAC3E,0BAAsE;IAEtE,IAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAC,MAAM;QACjC,OAAA,gBAAgB,CACd,MAAM,CAAC,MAAM,IAAI,EAAE,EACnB,0BAA0B,CAAC,MAAM,CAAC,WAAW,CAAC,EAC9C,MAAM,CAAC,OAAO,IAAI,EAAE,CACrB;IAJD,CAIC,CACF,CAAA;IAED,IAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CACxC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAClF,CAAC,iCAAiC,EAAE,CAAC,CACtC,CAAA;IAED,OAAO,KAAK,CAAC,cAAc,CACzB,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAC/E,CAAC,aAAa,CAAC,CAChB,CAAA;AACH,CAAC,CAAA;AAED,gEAAgE;AAChE,MAAM,CAAC,IAAM,kBAAkB,GAAG,UAChC,WAAmC,EACnC,OAAuF,EACvF,0BAAsE;IAEtE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;QACpC,OAAM;KACP;IACD,WAAW,CAAC,IAAI,CACd,KAAK,CAAC,cAAc,CAClB,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAC3B,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAC/D,CACF,CAAA;AACH,CAAC,CAAA;AAED,6EAA6E;AAC7E,oEAAoE;AACpE,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,yBAAyB;AACzB,MAAM,CAAC,IAAM,kBAAkB,GAAG,UAChC,IAAwB,EACxB,IAAiB,EACjB,QAAkB;IAElB,KAAiB,UAAQ,EAAR,qBAAQ,EAAR,sBAAQ,EAAR,IAAQ,EAAE;QAAtB,IAAM,EAAE,iBAAA;QACX,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAChB,SAAQ;SACT;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACZ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;KAChC;AACH,CAAC,CAAA;AAED,+EAA+E;AAC/E,gFAAgF;AAChF,uEAAuE;AACvE,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,6EAA6E;AAC7E,qDAAqD;AACrD,yCAAyC;AACzC,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAC/B,IAAwB,EACxB,IAAiB,EACjB,OAAiB;IAEjB,KAAiB,UAAO,EAAP,mBAAO,EAAP,qBAAO,EAAP,IAAO,EAAE;QAArB,IAAM,EAAE,gBAAA;QACX,IAAM,GAAG,GAAG,gBAAS,EAAE,CAAE,CAAA;QACzB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACjB,SAAQ;SACT;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACb,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;KACnF;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"filter-utils.js","sourceRoot":"","sources":["../../src/filter-utils.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAwkCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAs1B5E,CAAA"}
1
+ {"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAooCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAq1B5E,CAAA"}
@@ -48,11 +48,11 @@ import * as types from '@babel/types';
48
48
  import { parseExpression } from '@babel/parser';
49
49
  import { ASTStatementOrder, GenericUtils, StringUtils } from '@teleporthq/teleport-shared';
50
50
  import { ASTUtils, URLQueryWriter, URLSearchParamSync } from '@teleporthq/teleport-plugin-common';
51
- import { generateSafeFileName } from './utils';
51
+ import { collectFilterLeafConditions, generateSafeFileName, pruneFilterTree } from './utils';
52
52
  import { generateDataSourceFetcherWithCore } from './data-source-fetchers';
53
53
  import { buildProductTransformOptions } from './transformations';
54
- import { appendSortsParam, extractDynamicSort } from './sort-utils';
55
- import { appendFiltersParam, pushStateIdsAsDeps, pushPropIdsAsDeps } from './filter-utils';
54
+ import { appendSortsParam, extractDynamicSort, readFixedSort } from './sort-utils';
55
+ import { appendFiltersParam, buildStaticFiltersStringifyCall, pushStateIdsAsDeps, pushPropIdsAsDeps, } from './filter-utils';
56
56
  import { appendItemsPathParam, extractItemsPath } from './items-path';
57
57
  import { resolveRepeaterPerPage } from './repeater-page-size';
58
58
  import { applyLoadingStateToDataProvider, buildLoadingStateDeclarations, getLoadingStateVars, } from './loading-state';
@@ -103,79 +103,37 @@ function searchDefaultValueInitAST(value) {
103
103
  // independent AST node — Babel does not support shared references.
104
104
  return types.cloneNode(value.ast, /* deep */ true);
105
105
  }
106
- // Builds the `useState(...)` initializer for the search query. When the
107
- // cms-list-repeater is bound to a URL param (`searchUrlParamKey`), the query is
108
- // seeded from `window.location.search` on the client so a deep link such as
109
- // `/products-list?searchKeyword=yoga` arrives pre-filtered on the very first
110
- // paint; the server render (where `window` is undefined) and any missing param
111
- // fall back to the `searchDefaultValue` seed (empty string by default). This
112
- // mirrors the `selectedCategory` / `sortBy` initializer emitted by
113
- // `createStateHookAST` for state-level `urlSearchParamBinding`, keeping the
114
- // three products-list controls consistent.
106
+ // Builds the `useState(...)` initializer for the search query: the
107
+ // `searchDefaultValue` seed (empty string by default), never the address. A
108
+ // statically generated page is rendered on the server without the visitor's
109
+ // `?searchKeyword=`, and the browser's first render must match it — a query
110
+ // seeded from `window.location.search` rendered a filled input and skipped the
111
+ // prefetched rows there, and React warned of a hydration mismatch. A URL-bound
112
+ // search adopts the address after mount instead (`pushSearchUrlSyncEffects`),
113
+ // as the page number does (`page-url-sync.ts`).
115
114
  //
116
115
  // Returns a fresh AST on every call (no shared node references) so the same
117
116
  // initializer can seed both the immediate `ds_N_searchQuery` state and the
118
117
  // debounced `ds_N_state.debouncedQuery` value.
119
118
  function buildSearchQueryInitAST(usage) {
120
- var fallback = searchDefaultValueInitAST(usage.searchDefaultValue);
121
- if (!usage.searchUrlParamKey) {
122
- return fallback;
123
- }
124
- // (typeof window !== 'undefined'
125
- // ? new URLSearchParams(window.location.search).get('<key>')
126
- // : null) ?? <fallback>
127
- return types.logicalExpression('??', types.conditionalExpression(types.binaryExpression('!==', types.unaryExpression('typeof', types.identifier('window')), types.stringLiteral('undefined')), types.callExpression(types.memberExpression(types.newExpression(types.identifier('URLSearchParams'), [
128
- types.memberExpression(types.memberExpression(types.identifier('window'), types.identifier('location')), types.identifier('search')),
129
- ]), types.identifier('get')), [types.stringLiteral(usage.searchUrlParamKey)]), types.nullLiteral()), fallback);
119
+ return searchDefaultValueInitAST(usage.searchDefaultValue);
130
120
  }
131
- // The UIDL's `filters.content` array can wrap one or more conditions inside
132
- // a `{ type: 'group', operator: 'and' | 'or', children: [...] }` entry — the
133
- // GUI builds this shape when the inspector adds a logical group. The data
134
- // source API endpoint (`processFilters` in the generated data-source module)
135
- // only knows how to consume a FLAT array of `{ source, destination, operand }`
136
- // conditions, so we walk groups recursively here and collect their leaf
137
- // conditions in order. Anything that isn't a group AND isn't a condition is
138
- // dropped — defensive against partially-built filter entries that would
139
- // otherwise emit `{ source: '', destination: '', operand: '' }` rows the
140
- // API ignores anyway.
141
- //
142
- // `or`-grouped conditions are flattened just like `and`-grouped ones — the
143
- // downstream SQL builder always joins flat filters with `AND`, so emitting
144
- // the conditions side-by-side approximates AND semantics. A future API
145
- // upgrade that respects group operators would key off the original tree
146
- // directly; until then, AND-flattening is the closest correct behaviour and
147
- // matches what the inspector preview shows for the common single-group case
148
- // the GUI emits today.
149
- function flattenFilterGroups(filters) {
121
+ // The UIDL's `filters.content` array is the tree the inspector authored:
122
+ // `{ type: 'group', operator: 'and' | 'or', children: [...] }` entries around
123
+ // `{ source, destination, operand }` conditions, nested as deep as the user
124
+ // grouped them. The tree is kept as it is — the generated fetchers read it with
125
+ // `normalizeFilterTree`, so an `or` group stays an `or`. Only junk is dropped:
126
+ // an entry that is neither a group nor a condition (a half-built inspector
127
+ // row) would otherwise reach the API as `{ source: '', destination: '' }`.
128
+ // Entries without an explicit `type` are the legacy flat form and are
129
+ // conditions.
130
+ function readFilterTree(filters) {
150
131
  if (!Array.isArray(filters)) {
151
132
  return [];
152
133
  }
153
- var out = [];
154
- var walk = function (entry) {
155
- if (!entry || typeof entry !== 'object') {
156
- return;
157
- }
158
- if (entry.type === 'group' && Array.isArray(entry.children)) {
159
- for (var _i = 0, _a = entry.children; _i < _a.length; _i++) {
160
- var child = _a[_i];
161
- walk(child);
162
- }
163
- return;
164
- }
165
- // Backwards-compatible: entries without an explicit `type` (legacy flat
166
- // form) and entries explicitly tagged `condition` are both treated as
167
- // condition leaves.
168
- if (entry.type === undefined || entry.type === 'condition') {
169
- out.push(entry);
170
- }
171
- };
172
- for (var _i = 0, filters_1 = filters; _i < filters_1.length; _i++) {
173
- var entry = filters_1[_i];
174
- walk(entry);
175
- }
176
- return out;
134
+ return pruneFilterTree(filters, function (entry) { return entry.type === undefined || entry.type === 'condition'; });
177
135
  }
178
- // Walks a flat filter list to extract every `urlSearchParams` reference key
136
+ // Walks the filter tree to extract every `urlSearchParams` reference key
179
137
  // (e.g. `'categoryFilter'`). Used to (a) inject `const router = useRouter()`
180
138
  // once at the top of the component, (b) wire `router.query.<key>` into the
181
139
  // `useMemo` dependency array so the client-side fetch reruns whenever the
@@ -184,8 +142,8 @@ function flattenFilterGroups(filters) {
184
142
  function collectFilterUrlSearchParamKeys(filters) {
185
143
  var seen = new Set();
186
144
  var out = [];
187
- for (var _i = 0, filters_2 = filters; _i < filters_2.length; _i++) {
188
- var f = filters_2[_i];
145
+ for (var _i = 0, _a = collectFilterLeafConditions(filters); _i < _a.length; _i++) {
146
+ var f = _a[_i];
189
147
  var dest = f === null || f === void 0 ? void 0 : f.destination;
190
148
  if (!ASTUtils.isUIDLDynamicReference(dest)) {
191
149
  continue;
@@ -202,6 +160,12 @@ function collectFilterUrlSearchParamKeys(filters) {
202
160
  }
203
161
  return out;
204
162
  }
163
+ // The filter tree with every dynamic destination pruned — what `getStaticProps`
164
+ // can resolve at build time. Groups keep their operator; a group left empty by
165
+ // the pruning disappears with it (`pruneFilterTree`).
166
+ function staticFiltersOf(usage) {
167
+ return pruneFilterTree(usage.filters || [], function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
168
+ }
205
169
  // Returns true when any filter destination is a `urlSearchParams` dynamic
206
170
  // reference — used by the plugin to know it needs to import `useRouter` and
207
171
  // emit `const router = useRouter()` at the top of the component. Cheaper to
@@ -359,22 +323,28 @@ function buildStateRegistry(uidlNode) {
359
323
  if ((_k = (_j = parentDataSource.resourceParams) === null || _j === void 0 ? void 0 : _j.sorts) === null || _k === void 0 ? void 0 : _k.content) {
360
324
  sorts = parentDataSource.resourceParams.sorts.content;
361
325
  }
362
- // If legacy sorts aren't set, fall back to the new dynamic single-column
363
- // sort fields on the cms-list-repeater (used by admin-panel listing pages).
326
+ // If legacy sorts aren't set, fall back to the single-column sort fields
327
+ // on the cms-list-repeater. A FIXED one (a column chosen in the editor,
328
+ // e.g. a blog listing's newest first) is a static sort: read as dynamic,
329
+ // it made the list drop the server-side first page (`initialData` below
330
+ // is skipped for a dynamic sort) — the pre-rendered HTML carried no
331
+ // posts, and the browser fetched page 1 a second time. Only a sort
332
+ // bound to state (the admin panel's sortable columns) is dynamic.
364
333
  var dynamicSort = void 0;
365
334
  if ((!sorts || sorts.length === 0) && content.sort) {
366
- dynamicSort = extractDynamicSort(content.sort, content.sortDirection);
335
+ var fixedSort = readFixedSort(content.sort, content.sortDirection);
336
+ if (fixedSort) {
337
+ sorts = [fixedSort];
338
+ }
339
+ else {
340
+ dynamicSort = extractDynamicSort(content.sort, content.sortDirection);
341
+ }
367
342
  }
368
- // Extract filters from parent's resource params. The inspector wraps
369
- // every condition in a `{ type: 'group' }` envelope (single-group or
370
- // nested), so flatten to leaf conditions before the downstream emit
371
- // sites consume `.source` / `.destination` / `.operand` directly —
372
- // they expect a flat condition array. See `flattenFilterGroups`'s
373
- // header comment for why AND-flattening is the correct fallback for
374
- // the API endpoint's flat-condition contract.
343
+ // Extract filters from parent's resource params, keeping the group tree
344
+ // the inspector authored (see `readFilterTree`).
375
345
  var filters = [];
376
346
  if ((_m = (_l = parentDataSource.resourceParams) === null || _l === void 0 ? void 0 : _l.filters) === null || _m === void 0 ? void 0 : _m.content) {
377
- filters = flattenFilterGroups(parentDataSource.resourceParams.filters.content);
347
+ filters = readFilterTree(parentDataSource.resourceParams.filters.content);
378
348
  }
379
349
  // Split dynamic destination keys by reference type. `state`/`prop`
380
350
  // refs resolve to bare identifiers (so they're useMemo deps as-is);
@@ -382,8 +352,8 @@ function buildStateRegistry(uidlNode) {
382
352
  // `useRouter()` declaration injected separately.
383
353
  var filterStateIds = [];
384
354
  var filterPropIds = [];
385
- for (var _i = 0, filters_3 = filters; _i < filters_3.length; _i++) {
386
- var f = filters_3[_i];
355
+ for (var _i = 0, _u = collectFilterLeafConditions(filters); _i < _u.length; _i++) {
356
+ var f = _u[_i];
387
357
  if (!ASTUtils.isUIDLDynamicReference(f.destination)) {
388
358
  continue;
389
359
  }
@@ -489,8 +459,8 @@ function buildStateRegistry(uidlNode) {
489
459
  }
490
460
  // Recurse into children
491
461
  if (((_r = node.content) === null || _r === void 0 ? void 0 : _r.children) && Array.isArray(node.content.children)) {
492
- for (var _u = 0, _v = node.content.children; _u < _v.length; _u++) {
493
- var child = _v[_u];
462
+ for (var _v = 0, _w = node.content.children; _v < _w.length; _v++) {
463
+ var child = _w[_v];
494
464
  traverse(child, parentDataSource);
495
465
  }
496
466
  }
@@ -515,8 +485,8 @@ function buildStateRegistry(uidlNode) {
515
485
  }
516
486
  }
517
487
  if (Array.isArray(node.children)) {
518
- for (var _w = 0, _x = node.children; _w < _x.length; _w++) {
519
- var child = _x[_w];
488
+ for (var _x = 0, _y = node.children; _x < _y.length; _x++) {
489
+ var child = _y[_x];
520
490
  traverse(child, parentDataSource);
521
491
  }
522
492
  }
@@ -596,11 +566,55 @@ function pushSearchUrlSyncEffects(effectStatements, usage, vars) {
596
566
  ? types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery'))
597
567
  : types.identifier(vars.debouncedSearchQueryVar);
598
568
  };
569
+ // The query starts at its default (see `buildSearchQueryInitAST`), so the
570
+ // pair must agree on who goes first: the read-back adopts the address, THEN
571
+ // the write-back may write — before that, its first run would delete the very
572
+ // `?<key>=` the read-back is about to adopt.
573
+ var adoptedRefVar = "ds_".concat(usage.index, "_searchUrlAdopted");
574
+ var adopterVar = "ds_".concat(usage.index, "_adoptUrlSearch");
575
+ effectStatements.push(types.variableDeclaration('const', [
576
+ types.variableDeclarator(types.identifier(adoptedRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(false)])),
577
+ ]), buildUrlSearchAdopter(adopterVar, usage, vars));
599
578
  // write-back: debounced query → `?<searchUrlParamKey>=`
600
- effectStatements.push(URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr()));
601
- // read-back: `?<searchUrlParamKey>=` → input (`setDs_N_searchQuery`). The
602
- // debounce effect propagates the change into the debounced value + fetch.
603
- effectStatements.push(URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, vars.setSearchQueryVar));
579
+ effectStatements.push(URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr(), undefined, adoptedRefVar));
580
+ // read-back: `?<searchUrlParamKey>=` → the input AND the applied query at once
581
+ // (`ds_N_adoptUrlSearch`), so an address is not a typed change: it skips the
582
+ // debounce and keeps the page — `?searchKeyword=x&page=3` lands on page 3.
583
+ effectStatements.push(URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, adopterVar, undefined, adoptedRefVar));
584
+ }
585
+ // `const ds_N_adoptUrlSearch = (update) => { … }`: the setter the search's URL
586
+ // read-back calls with its `(prev) => next` updater. It moves the input and the
587
+ // applied (debounced) query together; the combined paginated state keeps its
588
+ // page, which a typed change resets to 1 in the debounce effect.
589
+ function buildUrlSearchAdopter(adopterVar, usage, vars) {
590
+ var update = types.identifier('update');
591
+ var applyToDebounced = usage.category === 'paginated+search'
592
+ ? // setDs_N_state((state) => {
593
+ // const next = update(state.debouncedQuery)
594
+ // return next === state.debouncedQuery ? state : { ...state, debouncedQuery: next }
595
+ // })
596
+ types.callExpression(types.identifier(vars.setCombinedStateVar), [
597
+ types.arrowFunctionExpression([types.identifier('state')], types.blockStatement([
598
+ types.variableDeclaration('const', [
599
+ types.variableDeclarator(types.identifier('next'), types.callExpression(types.identifier('update'), [
600
+ types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery')),
601
+ ])),
602
+ ]),
603
+ types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression([
604
+ types.spreadElement(types.identifier('state')),
605
+ types.objectProperty(types.identifier('debouncedQuery'), types.identifier('next')),
606
+ ]))),
607
+ ])),
608
+ ])
609
+ : types.callExpression(types.identifier(vars.setDebouncedSearchQueryVar), [update]);
610
+ return types.variableDeclaration('const', [
611
+ types.variableDeclarator(types.identifier(adopterVar), types.arrowFunctionExpression([types.identifier('update')], types.blockStatement([
612
+ types.expressionStatement(types.callExpression(types.identifier(vars.setSearchQueryVar), [
613
+ types.identifier('update'),
614
+ ])),
615
+ types.expressionStatement(applyToDebounced),
616
+ ]))),
617
+ ]);
604
618
  }
605
619
  // How one usage reads and writes its current page.
606
620
  //
@@ -862,13 +876,12 @@ export var createNextArrayMapperPaginationPlugin = function () {
862
876
  ]),
863
877
  ])),
864
878
  ]));
865
- // Immediate search query state — seeded with `searchDefaultValue` (or
866
- // the `searchUrlParamKey` URL value when bound) so the input is
867
- // pre-filled on mount. The debounced value above is seeded identically
868
- // so a deep-linked `?searchKeyword=` fetches filtered results on the
869
- // first paint: the paginated+search `initialData` is gated on
870
- // `!ds_N_state.debouncedQuery`, so a non-empty seed forces the
871
- // DataProvider to fetch instead of reusing the unfiltered SSG prefetch.
879
+ // Immediate search query state — seeded with `searchDefaultValue`, like
880
+ // the debounced value above. A deep-linked `?searchKeyword=` is adopted
881
+ // after mount by the URL read-back, which sets both at once; the
882
+ // paginated+search `initialData` is gated on `!ds_N_state.debouncedQuery`,
883
+ // so the adopted query makes the DataProvider fetch filtered rows
884
+ // instead of reusing the unfiltered SSG prefetch the first render shows.
872
885
  stateDeclarations.push(types.variableDeclaration('const', [
873
886
  types.variableDeclarator(types.arrayPattern([
874
887
  types.identifier(vars.searchQueryVar),
@@ -1734,7 +1747,13 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
1734
1747
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1735
1748
  }
1736
1749
  function updateDataProviderForPlain(dp, fileName, usage, localized) {
1737
- var _a, _b, _c, _d;
1750
+ var _a, _b, _c, _d, _e, _f;
1751
+ // A sort bound to state is the visitor's, which the server cannot know: rows
1752
+ // pre-rendered in the table's order would stand in for it, since a seeded
1753
+ // provider skips its first fetch — the paginated lists drop them the same way.
1754
+ if (usage.dynamicSort) {
1755
+ dp.openingElement.attributes = dp.openingElement.attributes.filter(function (attr) { var _a; return !(attr.type === 'JSXAttribute' && ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'initialData'); });
1756
+ }
1738
1757
  var attrs = dp.openingElement.attributes;
1739
1758
  var clientCache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined;
1740
1759
  // Check if fetchData already exists
@@ -1757,10 +1776,12 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1757
1776
  }
1758
1777
  // Find the params attribute. A plain list may have none at all — but the
1759
1778
  // fetch it was just given sends `params` regardless, and in a localized
1760
- // project those have to carry the locale, so the attribute is created.
1779
+ // project those have to carry the locale, and a sorted list its sort, so the
1780
+ // attribute is created.
1761
1781
  var paramsAttrIndex = attrs.findIndex(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'params'; });
1782
+ var isSorted = usage.sorts.length > 0 || !!usage.dynamicSort;
1762
1783
  if (paramsAttrIndex === -1) {
1763
- if (!localized) {
1784
+ if (!localized && !isSorted) {
1764
1785
  return;
1765
1786
  }
1766
1787
  attrs.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression([]))));
@@ -1781,10 +1802,17 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1781
1802
  if (!paramsExpression) {
1782
1803
  return;
1783
1804
  }
1784
- // Build useMemo dependencies including filter state IDs
1805
+ // The repeater's sort, which the paginated and searchable lists add to the
1806
+ // params they rebuild: kept as they come, a plain list's params never
1807
+ // carried it, and the rows arrived in the table's own order.
1808
+ if (paramsExpression.type === 'ObjectExpression' && !hasObjectKey(paramsExpression, 'sorts')) {
1809
+ appendSortsParam(paramsExpression.properties, usage.sorts, usage.dynamicSort);
1810
+ }
1811
+ // Build useMemo dependencies including filter state IDs and a dynamic sort's state
1785
1812
  var memoDeps = [];
1786
1813
  var memoSeen = new Set();
1787
1814
  pushStateIdsAsDeps(memoDeps, memoSeen, usage.filterStateIds);
1815
+ pushStateIdsAsDeps(memoDeps, memoSeen, (_f = (_e = usage.dynamicSort) === null || _e === void 0 ? void 0 : _e.depStateIds) !== null && _f !== void 0 ? _f : []);
1788
1816
  pushPropIdsAsDeps(memoDeps, memoSeen, usage.filterPropIds);
1789
1817
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1790
1818
  if (localized && paramsExpression.type === 'ObjectExpression') {
@@ -1798,6 +1826,13 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1798
1826
  // Replace the params attribute
1799
1827
  attrs[paramsAttrIndex] = types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(memoizedParams));
1800
1828
  }
1829
+ var hasObjectKey = function (object, key) {
1830
+ return object.properties.some(function (property) {
1831
+ return property.type === 'ObjectProperty' &&
1832
+ ((property.key.type === 'Identifier' && property.key.name === key) ||
1833
+ (property.key.type === 'StringLiteral' && property.key.value === key));
1834
+ });
1835
+ };
1801
1836
  function stabilizeDataProviderWithoutRepeater(dp) {
1802
1837
  var _a, _b, _c;
1803
1838
  var attrs = dp.openingElement.attributes;
@@ -2227,17 +2262,9 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2227
2262
  }
2228
2263
  // Add filters if present
2229
2264
  // Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
2230
- var staticFilters = (usage.filters || []).filter(function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
2265
+ var staticFilters = staticFiltersOf(usage);
2231
2266
  if (staticFilters.length > 0) {
2232
- fetchParams.push(types.objectProperty(types.identifier('filters'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
2233
- types.arrayExpression(staticFilters.map(function (filter) {
2234
- return types.objectExpression([
2235
- types.objectProperty(types.identifier('source'), types.stringLiteral(filter.source || '')),
2236
- types.objectProperty(types.identifier('destination'), types.stringLiteral(typeof filter.destination === 'string' ? filter.destination : '')),
2237
- types.objectProperty(types.identifier('operand'), types.stringLiteral(filter.operand || '')),
2238
- ]);
2239
- })),
2240
- ])));
2267
+ fetchParams.push(types.objectProperty(types.identifier('filters'), buildStaticFiltersStringifyCall(staticFilters)));
2241
2268
  }
2242
2269
  appendItemsPathParam(fetchParams, usage.itemsPath, 'itemsPath');
2243
2270
  // The prefetch is per locale — getStaticProps runs once per language.
@@ -2277,7 +2304,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2277
2304
  var maxPagesPropName_1 = "".concat(vars.propsPrefix, "_maxPages");
2278
2305
  // Use filter-specific count variable if usage has static filters
2279
2306
  // (dynamic filters can't be resolved at build time)
2280
- var staticFiltersForCount = (usage.filters || []).filter(function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
2307
+ var staticFiltersForCount = staticFiltersOf(usage);
2281
2308
  // A count scoped to an inner array is a different number from the
2282
2309
  // whole-payload one, so it gets its own variable just like a filtered one.
2283
2310
  var hasScopedCount = staticFiltersForCount.length > 0 || !!usage.itemsPath;
@@ -2328,7 +2355,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2328
2355
  usagesByFilters.forEach(function (usages, filtersKey) {
2329
2356
  var firstUsage = usages[0];
2330
2357
  // Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
2331
- var staticFiltersForCount = (firstUsage.filters || []).filter(function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
2358
+ var staticFiltersForCount = staticFiltersOf(firstUsage);
2332
2359
  var hasStaticFilters = staticFiltersForCount.length > 0;
2333
2360
  // Create unique count variable name based on filters (and inner-array
2334
2361
  // scope — must match the naming at the maxPages site above)
@@ -2348,15 +2375,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2348
2375
  // Build count params if static filters exist
2349
2376
  var countParams = [];
2350
2377
  if (hasStaticFilters) {
2351
- countParams.push(types.objectProperty(types.identifier('filters'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
2352
- types.arrayExpression(staticFiltersForCount.map(function (f) {
2353
- return types.objectExpression([
2354
- types.objectProperty(types.identifier('source'), types.stringLiteral(f.source || '')),
2355
- types.objectProperty(types.identifier('destination'), types.stringLiteral(typeof f.destination === 'string' ? f.destination : '')),
2356
- types.objectProperty(types.identifier('operand'), types.stringLiteral(f.operand || '')),
2357
- ]);
2358
- })),
2359
- ])));
2378
+ countParams.push(types.objectProperty(types.identifier('filters'), buildStaticFiltersStringifyCall(staticFiltersForCount)));
2360
2379
  }
2361
2380
  appendItemsPathParam(countParams, firstUsage.itemsPath, 'collectionPath');
2362
2381
  fetchesArray.elements.push(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchCount')), countParams.length > 0 ? [types.objectExpression(countParams)] : []), types.identifier('catch')), [