@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":"browser-row-policy.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/browser-row-policy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AASU,QAAA,oBAAoB,GAA+C;IAC9E,kEAAkE;IAClE,wEAAwE;IACxE,mBAAmB,EAAE;QACnB,SAAS,EAAE,sBAAsB;QACjC,aAAa,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;KAC/C;IACD,yEAAyE;IACzE,+DAA+D;IAC/D,iBAAiB,EAAE;QACjB,SAAS,EAAE,gCAAgC;QAC3C,aAAa,EAAE,EAAE;KAClB;CACF,CAAA;AAED;;;;;;;GAOG;AACI,IAAM,4BAA4B,GACvC,cAAc,OAAA,mHACO,IAAI,CAAC,SAAS,CAAC,4BAAoB,CAAC,q8JA8H1D,EA/He,CA+Hf,CAAA;AAhIY,QAAA,4BAA4B,gCAgIxC;AAED;;;GAGG;AACI,IAAM,oBAAoB,GAAG,UAClC,SAAiB,EACjB,eAAsC;IAEtC,IAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;SAClC,IAAI,EAAE;SACN,WAAW,EAAE;SACb,KAAK,CAAC,GAAG,CAAC,CAAA;IACb,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACtD,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,4BAAoB,EAAE,IAAI,CAAC;QAChE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACrC,CAAA;AACH,CAAC,CAAA;AAbY,QAAA,oBAAoB,wBAahC;AAED;;;GAGG;AACI,IAAM,4BAA4B,GAAG,UAC1C,SAAiB,EACjB,YAA2B;IAE3B,OAAO,uDAAgD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAC9E,YAAY,IAAI,MAAM,yNAMzB,CAAA;AACD,CAAC,CAAA;AAZY,QAAA,4BAA4B,gCAYxC"}
1
+ {"version":3,"file":"browser-row-policy.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/browser-row-policy.ts"],"names":[],"mappings":";;;AAAA,+DAA2D;AAwB3D;;;;GAIG;AACU,QAAA,oBAAoB,GAC/B,+BAAa,CAAC,oBAAoB,CAAA;AAEpC;;;;;;;GAOG;AACI,IAAM,4BAA4B,GACvC,cAAc,OAAA,mHACO,IAAI,CAAC,SAAS,CAAC,4BAAoB,CAAC,q8JA8H1D,EA/He,CA+Hf,CAAA;AAhIY,QAAA,4BAA4B,gCAgIxC;AAED;;;GAGG;AACI,IAAM,oBAAoB,GAAG,UAClC,SAAiB,EACjB,eAAsC;IAEtC,IAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;SAClC,IAAI,EAAE;SACN,WAAW,EAAE;SACb,KAAK,CAAC,GAAG,CAAC,CAAA;IACb,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACtD,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,4BAAoB,EAAE,IAAI,CAAC;QAChE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACrC,CAAA;AACH,CAAC,CAAA;AAbY,QAAA,oBAAoB,wBAahC;AAED;;;GAGG;AACI,IAAM,4BAA4B,GAAG,UAC1C,SAAiB,EACjB,YAA2B;IAE3B,OAAO,uDAAgD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAC9E,YAAY,IAAI,MAAM,yNAMzB,CAAA;AACD,CAAC,CAAA;AAZY,QAAA,4BAA4B,gCAYxC"}
@@ -1,14 +1,26 @@
1
1
  import * as types from '@babel/types';
2
- export declare const buildFiltersStringifyCall: (filters: Array<{
2
+ /**
3
+ * One entry of the filter TREE the inspector authors: a condition leaf, or a
4
+ * group of further entries joined with `and` / `or`. The generated fetchers
5
+ * read this same tree (`normalizeFilterTree` in utils.ts), so the group
6
+ * operator must reach them intact — flattening an `or` group into its leaves
7
+ * turns "any of" into "all of" on the published site.
8
+ */
9
+ export type FilterCondition = {
3
10
  source?: string;
4
11
  operand?: string;
5
12
  destination: unknown;
6
- }>, buildDestinationExpression: (destination: unknown) => types.Expression) => types.CallExpression;
7
- export declare const appendFiltersParam: (paramsProps: types.ObjectProperty[], filters: Array<{
8
- source?: string;
9
- operand?: string;
10
- destination: unknown;
11
- }> | undefined, buildDestinationExpression: (destination: unknown) => types.Expression) => void;
13
+ };
14
+ export type FilterGroup = {
15
+ type: 'group';
16
+ operator?: string;
17
+ children: FilterEntry[];
18
+ };
19
+ export type FilterEntry = FilterCondition | FilterGroup;
20
+ export declare const isFilterGroup: (entry: unknown) => entry is FilterGroup;
21
+ export declare const buildFiltersStringifyCall: (filters: FilterEntry[], buildDestinationExpression: (destination: unknown) => types.Expression) => types.CallExpression;
22
+ export declare const buildStaticFiltersStringifyCall: (filters: FilterEntry[]) => types.CallExpression;
23
+ export declare const appendFiltersParam: (paramsProps: types.ObjectProperty[], filters: FilterEntry[] | undefined, buildDestinationExpression: (destination: unknown) => types.Expression) => void;
12
24
  export declare const pushStateIdsAsDeps: (deps: types.Expression[], seen: Set<string>, stateIds: string[]) => void;
13
25
  export declare const pushPropIdsAsDeps: (deps: types.Expression[], seen: Set<string>, propIds: string[]) => void;
14
26
  //# sourceMappingURL=filter-utils.d.ts.map
@@ -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"}
@@ -23,8 +23,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.pushPropIdsAsDeps = exports.pushStateIdsAsDeps = exports.appendFiltersParam = exports.buildFiltersStringifyCall = void 0;
26
+ exports.pushPropIdsAsDeps = exports.pushStateIdsAsDeps = exports.appendFiltersParam = exports.buildStaticFiltersStringifyCall = exports.buildFiltersStringifyCall = exports.isFilterGroup = void 0;
27
27
  var types = __importStar(require("@babel/types"));
28
+ var isFilterGroup = function (entry) {
29
+ return !!entry &&
30
+ typeof entry === 'object' &&
31
+ entry.type === 'group' &&
32
+ Array.isArray(entry.children);
33
+ };
34
+ exports.isFilterGroup = isFilterGroup;
28
35
  // Build a single filter entry: { source: '<src>', destination: <destExpr>, operand: '<op>' }
29
36
  var buildFilterEntry = function (source, destinationExpr, operand) {
30
37
  return types.objectExpression([
@@ -33,10 +40,19 @@ var buildFilterEntry = function (source, destinationExpr, operand) {
33
40
  types.objectProperty(types.identifier('operand'), types.stringLiteral(operand)),
34
41
  ]);
35
42
  };
43
+ // { type: 'group', operator: 'and' | 'or', children: <childrenExpr> }
44
+ var buildFilterGroup = function (operator, childrenExpr) {
45
+ return types.objectExpression([
46
+ types.objectProperty(types.identifier('type'), types.stringLiteral('group')),
47
+ types.objectProperty(types.identifier('operator'), types.stringLiteral(operator === 'or' ? 'or' : 'and')),
48
+ types.objectProperty(types.identifier('children'), childrenExpr),
49
+ ]);
50
+ };
36
51
  // Predicate:
37
- // (__f) => __f.destination !== '' && __f.destination !== null &&
38
- // __f.destination !== undefined &&
39
- // !(Array.isArray(__f.destination) && __f.destination.filter(Boolean).length === 0)
52
+ // (__f) => __f.type === 'group' ||
53
+ // (__f.destination !== '' && __f.destination !== null &&
54
+ // __f.destination !== undefined &&
55
+ // !(Array.isArray(__f.destination) && __f.destination.filter(Boolean).length === 0))
40
56
  // Used at runtime to drop filter conditions whose destination resolves to an
41
57
  // empty value. Keeps the page generic: state-bound filters (e.g.
42
58
  // `selectedCategory === ''` after picking "All Categories") and url-bound
@@ -46,19 +62,31 @@ var buildFilterEntry = function (source, destinationExpr, operand) {
46
62
  // string and returns zero rows. The array clause covers array-overlap filters
47
63
  // (e.g. category `CATEGORY_DESCENDANTS[selectedCategory] || []`) whose "All"
48
64
  // reset resolves to `[]` — an empty overlap set must mean "no filter", not
49
- // "match nothing".
65
+ // "match nothing". A group has no destination of its own and is kept; its
66
+ // children carry the same `.filter(...)`, and a group emptied that way is
67
+ // dropped by the fetcher's `normalizeFilterTree`.
50
68
  var buildNonEmptyDestinationPredicate = function () {
51
69
  var f = types.identifier('__f');
52
70
  var dest = types.memberExpression(f, types.identifier('destination'));
53
71
  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')), [
54
72
  types.identifier('Boolean'),
55
73
  ]), types.identifier('length')), types.numericLiteral(0)));
56
- 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)));
74
+ 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))));
75
+ };
76
+ // `[ entry, ... ].filter(<non-empty destination>)`, recursing into groups so
77
+ // every level of the tree drops its empty conditions at runtime.
78
+ var buildFilteredEntriesArray = function (filters, buildDestinationExpression) {
79
+ var entries = filters.map(function (filter) {
80
+ return (0, exports.isFilterGroup)(filter)
81
+ ? buildFilterGroup(filter.operator, buildFilteredEntriesArray(filter.children, buildDestinationExpression))
82
+ : buildFilterEntry(filter.source || '', buildDestinationExpression(filter.destination), filter.operand || '');
83
+ });
84
+ return types.callExpression(types.memberExpression(types.arrayExpression(entries), types.identifier('filter')), [buildNonEmptyDestinationPredicate()]);
57
85
  };
58
86
  // Build the AST for:
59
87
  // JSON.stringify(
60
- // [ {source, destination, operand}, ... ]
61
- // .filter(__f => __f.destination !== '' && __f.destination !== null && __f.destination !== undefined)
88
+ // [ {source, destination, operand}, { type: 'group', operator, children: [...].filter(...) }, ... ]
89
+ // .filter(__f => __f.type === 'group' || (__f.destination !== '' && __f.destination !== null && __f.destination !== undefined))
62
90
  // )
63
91
  //
64
92
  // The `.filter(...)` step is unconditional even when every entry is a static
@@ -67,13 +95,21 @@ var buildNonEmptyDestinationPredicate = function () {
67
95
  // type is added but its empty-value behavior is forgotten don't silently
68
96
  // re-introduce empty-string filters.
69
97
  var buildFiltersStringifyCall = function (filters, buildDestinationExpression) {
70
- var entries = filters.map(function (filter) {
71
- return buildFilterEntry(filter.source || '', buildDestinationExpression(filter.destination), filter.operand || '');
72
- });
73
- var filteredArray = types.callExpression(types.memberExpression(types.arrayExpression(entries), types.identifier('filter')), [buildNonEmptyDestinationPredicate()]);
74
- return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [filteredArray]);
98
+ return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [buildFilteredEntriesArray(filters, buildDestinationExpression)]);
75
99
  };
76
100
  exports.buildFiltersStringifyCall = buildFiltersStringifyCall;
101
+ // The build-time counterpart for `getStaticProps`: every destination is a
102
+ // literal (the dynamic ones were pruned — see `pruneFilterTree`), so the tree
103
+ // is written out as plain string literals with no runtime `.filter(...)`.
104
+ var buildStaticFilterEntryAST = function (filter) {
105
+ return (0, exports.isFilterGroup)(filter)
106
+ ? buildFilterGroup(filter.operator, types.arrayExpression(filter.children.map(buildStaticFilterEntryAST)))
107
+ : buildFilterEntry(filter.source || '', types.stringLiteral(typeof filter.destination === 'string' ? filter.destination : ''), filter.operand || '');
108
+ };
109
+ var buildStaticFiltersStringifyCall = function (filters) {
110
+ return types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [types.arrayExpression(filters.map(buildStaticFilterEntryAST))]);
111
+ };
112
+ exports.buildStaticFiltersStringifyCall = buildStaticFiltersStringifyCall;
77
113
  // Convenience: push `filters: <call>` onto a paramsProps array.
78
114
  var appendFiltersParam = function (paramsProps, filters, buildDestinationExpression) {
79
115
  if (!filters || filters.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"filter-utils.js","sourceRoot":"","sources":["../../src/filter-utils.ts"],"names":[],"mappings":"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"}
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"}
@@ -129,79 +129,37 @@ function searchDefaultValueInitAST(value) {
129
129
  // independent AST node — Babel does not support shared references.
130
130
  return types.cloneNode(value.ast, /* deep */ true);
131
131
  }
132
- // Builds the `useState(...)` initializer for the search query. When the
133
- // cms-list-repeater is bound to a URL param (`searchUrlParamKey`), the query is
134
- // seeded from `window.location.search` on the client so a deep link such as
135
- // `/products-list?searchKeyword=yoga` arrives pre-filtered on the very first
136
- // paint; the server render (where `window` is undefined) and any missing param
137
- // fall back to the `searchDefaultValue` seed (empty string by default). This
138
- // mirrors the `selectedCategory` / `sortBy` initializer emitted by
139
- // `createStateHookAST` for state-level `urlSearchParamBinding`, keeping the
140
- // three products-list controls consistent.
132
+ // Builds the `useState(...)` initializer for the search query: the
133
+ // `searchDefaultValue` seed (empty string by default), never the address. A
134
+ // statically generated page is rendered on the server without the visitor's
135
+ // `?searchKeyword=`, and the browser's first render must match it — a query
136
+ // seeded from `window.location.search` rendered a filled input and skipped the
137
+ // prefetched rows there, and React warned of a hydration mismatch. A URL-bound
138
+ // search adopts the address after mount instead (`pushSearchUrlSyncEffects`),
139
+ // as the page number does (`page-url-sync.ts`).
141
140
  //
142
141
  // Returns a fresh AST on every call (no shared node references) so the same
143
142
  // initializer can seed both the immediate `ds_N_searchQuery` state and the
144
143
  // debounced `ds_N_state.debouncedQuery` value.
145
144
  function buildSearchQueryInitAST(usage) {
146
- var fallback = searchDefaultValueInitAST(usage.searchDefaultValue);
147
- if (!usage.searchUrlParamKey) {
148
- return fallback;
149
- }
150
- // (typeof window !== 'undefined'
151
- // ? new URLSearchParams(window.location.search).get('<key>')
152
- // : null) ?? <fallback>
153
- 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'), [
154
- types.memberExpression(types.memberExpression(types.identifier('window'), types.identifier('location')), types.identifier('search')),
155
- ]), types.identifier('get')), [types.stringLiteral(usage.searchUrlParamKey)]), types.nullLiteral()), fallback);
145
+ return searchDefaultValueInitAST(usage.searchDefaultValue);
156
146
  }
157
- // The UIDL's `filters.content` array can wrap one or more conditions inside
158
- // a `{ type: 'group', operator: 'and' | 'or', children: [...] }` entry — the
159
- // GUI builds this shape when the inspector adds a logical group. The data
160
- // source API endpoint (`processFilters` in the generated data-source module)
161
- // only knows how to consume a FLAT array of `{ source, destination, operand }`
162
- // conditions, so we walk groups recursively here and collect their leaf
163
- // conditions in order. Anything that isn't a group AND isn't a condition is
164
- // dropped — defensive against partially-built filter entries that would
165
- // otherwise emit `{ source: '', destination: '', operand: '' }` rows the
166
- // API ignores anyway.
167
- //
168
- // `or`-grouped conditions are flattened just like `and`-grouped ones — the
169
- // downstream SQL builder always joins flat filters with `AND`, so emitting
170
- // the conditions side-by-side approximates AND semantics. A future API
171
- // upgrade that respects group operators would key off the original tree
172
- // directly; until then, AND-flattening is the closest correct behaviour and
173
- // matches what the inspector preview shows for the common single-group case
174
- // the GUI emits today.
175
- function flattenFilterGroups(filters) {
147
+ // The UIDL's `filters.content` array is the tree the inspector authored:
148
+ // `{ type: 'group', operator: 'and' | 'or', children: [...] }` entries around
149
+ // `{ source, destination, operand }` conditions, nested as deep as the user
150
+ // grouped them. The tree is kept as it is — the generated fetchers read it with
151
+ // `normalizeFilterTree`, so an `or` group stays an `or`. Only junk is dropped:
152
+ // an entry that is neither a group nor a condition (a half-built inspector
153
+ // row) would otherwise reach the API as `{ source: '', destination: '' }`.
154
+ // Entries without an explicit `type` are the legacy flat form and are
155
+ // conditions.
156
+ function readFilterTree(filters) {
176
157
  if (!Array.isArray(filters)) {
177
158
  return [];
178
159
  }
179
- var out = [];
180
- var walk = function (entry) {
181
- if (!entry || typeof entry !== 'object') {
182
- return;
183
- }
184
- if (entry.type === 'group' && Array.isArray(entry.children)) {
185
- for (var _i = 0, _a = entry.children; _i < _a.length; _i++) {
186
- var child = _a[_i];
187
- walk(child);
188
- }
189
- return;
190
- }
191
- // Backwards-compatible: entries without an explicit `type` (legacy flat
192
- // form) and entries explicitly tagged `condition` are both treated as
193
- // condition leaves.
194
- if (entry.type === undefined || entry.type === 'condition') {
195
- out.push(entry);
196
- }
197
- };
198
- for (var _i = 0, filters_1 = filters; _i < filters_1.length; _i++) {
199
- var entry = filters_1[_i];
200
- walk(entry);
201
- }
202
- return out;
160
+ return (0, utils_1.pruneFilterTree)(filters, function (entry) { return entry.type === undefined || entry.type === 'condition'; });
203
161
  }
204
- // Walks a flat filter list to extract every `urlSearchParams` reference key
162
+ // Walks the filter tree to extract every `urlSearchParams` reference key
205
163
  // (e.g. `'categoryFilter'`). Used to (a) inject `const router = useRouter()`
206
164
  // once at the top of the component, (b) wire `router.query.<key>` into the
207
165
  // `useMemo` dependency array so the client-side fetch reruns whenever the
@@ -210,8 +168,8 @@ function flattenFilterGroups(filters) {
210
168
  function collectFilterUrlSearchParamKeys(filters) {
211
169
  var seen = new Set();
212
170
  var out = [];
213
- for (var _i = 0, filters_2 = filters; _i < filters_2.length; _i++) {
214
- var f = filters_2[_i];
171
+ for (var _i = 0, _a = (0, utils_1.collectFilterLeafConditions)(filters); _i < _a.length; _i++) {
172
+ var f = _a[_i];
215
173
  var dest = f === null || f === void 0 ? void 0 : f.destination;
216
174
  if (!teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(dest)) {
217
175
  continue;
@@ -228,6 +186,12 @@ function collectFilterUrlSearchParamKeys(filters) {
228
186
  }
229
187
  return out;
230
188
  }
189
+ // The filter tree with every dynamic destination pruned — what `getStaticProps`
190
+ // can resolve at build time. Groups keep their operator; a group left empty by
191
+ // the pruning disappears with it (`pruneFilterTree`).
192
+ function staticFiltersOf(usage) {
193
+ return (0, utils_1.pruneFilterTree)(usage.filters || [], function (f) { return !teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(f.destination); });
194
+ }
231
195
  // Returns true when any filter destination is a `urlSearchParams` dynamic
232
196
  // reference — used by the plugin to know it needs to import `useRouter` and
233
197
  // emit `const router = useRouter()` at the top of the component. Cheaper to
@@ -385,22 +349,28 @@ function buildStateRegistry(uidlNode) {
385
349
  if ((_k = (_j = parentDataSource.resourceParams) === null || _j === void 0 ? void 0 : _j.sorts) === null || _k === void 0 ? void 0 : _k.content) {
386
350
  sorts = parentDataSource.resourceParams.sorts.content;
387
351
  }
388
- // If legacy sorts aren't set, fall back to the new dynamic single-column
389
- // sort fields on the cms-list-repeater (used by admin-panel listing pages).
352
+ // If legacy sorts aren't set, fall back to the single-column sort fields
353
+ // on the cms-list-repeater. A FIXED one (a column chosen in the editor,
354
+ // e.g. a blog listing's newest first) is a static sort: read as dynamic,
355
+ // it made the list drop the server-side first page (`initialData` below
356
+ // is skipped for a dynamic sort) — the pre-rendered HTML carried no
357
+ // posts, and the browser fetched page 1 a second time. Only a sort
358
+ // bound to state (the admin panel's sortable columns) is dynamic.
390
359
  var dynamicSort = void 0;
391
360
  if ((!sorts || sorts.length === 0) && content.sort) {
392
- dynamicSort = (0, sort_utils_1.extractDynamicSort)(content.sort, content.sortDirection);
361
+ var fixedSort = (0, sort_utils_1.readFixedSort)(content.sort, content.sortDirection);
362
+ if (fixedSort) {
363
+ sorts = [fixedSort];
364
+ }
365
+ else {
366
+ dynamicSort = (0, sort_utils_1.extractDynamicSort)(content.sort, content.sortDirection);
367
+ }
393
368
  }
394
- // Extract filters from parent's resource params. The inspector wraps
395
- // every condition in a `{ type: 'group' }` envelope (single-group or
396
- // nested), so flatten to leaf conditions before the downstream emit
397
- // sites consume `.source` / `.destination` / `.operand` directly —
398
- // they expect a flat condition array. See `flattenFilterGroups`'s
399
- // header comment for why AND-flattening is the correct fallback for
400
- // the API endpoint's flat-condition contract.
369
+ // Extract filters from parent's resource params, keeping the group tree
370
+ // the inspector authored (see `readFilterTree`).
401
371
  var filters = [];
402
372
  if ((_m = (_l = parentDataSource.resourceParams) === null || _l === void 0 ? void 0 : _l.filters) === null || _m === void 0 ? void 0 : _m.content) {
403
- filters = flattenFilterGroups(parentDataSource.resourceParams.filters.content);
373
+ filters = readFilterTree(parentDataSource.resourceParams.filters.content);
404
374
  }
405
375
  // Split dynamic destination keys by reference type. `state`/`prop`
406
376
  // refs resolve to bare identifiers (so they're useMemo deps as-is);
@@ -408,8 +378,8 @@ function buildStateRegistry(uidlNode) {
408
378
  // `useRouter()` declaration injected separately.
409
379
  var filterStateIds = [];
410
380
  var filterPropIds = [];
411
- for (var _i = 0, filters_3 = filters; _i < filters_3.length; _i++) {
412
- var f = filters_3[_i];
381
+ for (var _i = 0, _u = (0, utils_1.collectFilterLeafConditions)(filters); _i < _u.length; _i++) {
382
+ var f = _u[_i];
413
383
  if (!teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(f.destination)) {
414
384
  continue;
415
385
  }
@@ -515,8 +485,8 @@ function buildStateRegistry(uidlNode) {
515
485
  }
516
486
  // Recurse into children
517
487
  if (((_r = node.content) === null || _r === void 0 ? void 0 : _r.children) && Array.isArray(node.content.children)) {
518
- for (var _u = 0, _v = node.content.children; _u < _v.length; _u++) {
519
- var child = _v[_u];
488
+ for (var _v = 0, _w = node.content.children; _v < _w.length; _v++) {
489
+ var child = _w[_v];
520
490
  traverse(child, parentDataSource);
521
491
  }
522
492
  }
@@ -541,8 +511,8 @@ function buildStateRegistry(uidlNode) {
541
511
  }
542
512
  }
543
513
  if (Array.isArray(node.children)) {
544
- for (var _w = 0, _x = node.children; _w < _x.length; _w++) {
545
- var child = _x[_w];
514
+ for (var _x = 0, _y = node.children; _x < _y.length; _x++) {
515
+ var child = _y[_x];
546
516
  traverse(child, parentDataSource);
547
517
  }
548
518
  }
@@ -622,11 +592,55 @@ function pushSearchUrlSyncEffects(effectStatements, usage, vars) {
622
592
  ? types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery'))
623
593
  : types.identifier(vars.debouncedSearchQueryVar);
624
594
  };
595
+ // The query starts at its default (see `buildSearchQueryInitAST`), so the
596
+ // pair must agree on who goes first: the read-back adopts the address, THEN
597
+ // the write-back may write — before that, its first run would delete the very
598
+ // `?<key>=` the read-back is about to adopt.
599
+ var adoptedRefVar = "ds_".concat(usage.index, "_searchUrlAdopted");
600
+ var adopterVar = "ds_".concat(usage.index, "_adoptUrlSearch");
601
+ effectStatements.push(types.variableDeclaration('const', [
602
+ types.variableDeclarator(types.identifier(adoptedRefVar), types.callExpression(types.identifier('useRef'), [types.booleanLiteral(false)])),
603
+ ]), buildUrlSearchAdopter(adopterVar, usage, vars));
625
604
  // write-back: debounced query → `?<searchUrlParamKey>=`
626
- effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr()));
627
- // read-back: `?<searchUrlParamKey>=` → input (`setDs_N_searchQuery`). The
628
- // debounce effect propagates the change into the debounced value + fetch.
629
- effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, vars.setSearchQueryVar));
605
+ effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr(), undefined, adoptedRefVar));
606
+ // read-back: `?<searchUrlParamKey>=` → the input AND the applied query at once
607
+ // (`ds_N_adoptUrlSearch`), so an address is not a typed change: it skips the
608
+ // debounce and keeps the page — `?searchKeyword=x&page=3` lands on page 3.
609
+ effectStatements.push(teleport_plugin_common_1.URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, adopterVar, undefined, adoptedRefVar));
610
+ }
611
+ // `const ds_N_adoptUrlSearch = (update) => { … }`: the setter the search's URL
612
+ // read-back calls with its `(prev) => next` updater. It moves the input and the
613
+ // applied (debounced) query together; the combined paginated state keeps its
614
+ // page, which a typed change resets to 1 in the debounce effect.
615
+ function buildUrlSearchAdopter(adopterVar, usage, vars) {
616
+ var update = types.identifier('update');
617
+ var applyToDebounced = usage.category === 'paginated+search'
618
+ ? // setDs_N_state((state) => {
619
+ // const next = update(state.debouncedQuery)
620
+ // return next === state.debouncedQuery ? state : { ...state, debouncedQuery: next }
621
+ // })
622
+ types.callExpression(types.identifier(vars.setCombinedStateVar), [
623
+ types.arrowFunctionExpression([types.identifier('state')], types.blockStatement([
624
+ types.variableDeclaration('const', [
625
+ types.variableDeclarator(types.identifier('next'), types.callExpression(types.identifier('update'), [
626
+ types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery')),
627
+ ])),
628
+ ]),
629
+ types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression([
630
+ types.spreadElement(types.identifier('state')),
631
+ types.objectProperty(types.identifier('debouncedQuery'), types.identifier('next')),
632
+ ]))),
633
+ ])),
634
+ ])
635
+ : types.callExpression(types.identifier(vars.setDebouncedSearchQueryVar), [update]);
636
+ return types.variableDeclaration('const', [
637
+ types.variableDeclarator(types.identifier(adopterVar), types.arrowFunctionExpression([types.identifier('update')], types.blockStatement([
638
+ types.expressionStatement(types.callExpression(types.identifier(vars.setSearchQueryVar), [
639
+ types.identifier('update'),
640
+ ])),
641
+ types.expressionStatement(applyToDebounced),
642
+ ]))),
643
+ ]);
630
644
  }
631
645
  // How one usage reads and writes its current page.
632
646
  //
@@ -888,13 +902,12 @@ var createNextArrayMapperPaginationPlugin = function () {
888
902
  ]),
889
903
  ])),
890
904
  ]));
891
- // Immediate search query state — seeded with `searchDefaultValue` (or
892
- // the `searchUrlParamKey` URL value when bound) so the input is
893
- // pre-filled on mount. The debounced value above is seeded identically
894
- // so a deep-linked `?searchKeyword=` fetches filtered results on the
895
- // first paint: the paginated+search `initialData` is gated on
896
- // `!ds_N_state.debouncedQuery`, so a non-empty seed forces the
897
- // DataProvider to fetch instead of reusing the unfiltered SSG prefetch.
905
+ // Immediate search query state — seeded with `searchDefaultValue`, like
906
+ // the debounced value above. A deep-linked `?searchKeyword=` is adopted
907
+ // after mount by the URL read-back, which sets both at once; the
908
+ // paginated+search `initialData` is gated on `!ds_N_state.debouncedQuery`,
909
+ // so the adopted query makes the DataProvider fetch filtered rows
910
+ // instead of reusing the unfiltered SSG prefetch the first render shows.
898
911
  stateDeclarations.push(types.variableDeclaration('const', [
899
912
  types.variableDeclarator(types.arrayPattern([
900
913
  types.identifier(vars.searchQueryVar),
@@ -1761,7 +1774,13 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
1761
1774
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1762
1775
  }
1763
1776
  function updateDataProviderForPlain(dp, fileName, usage, localized) {
1764
- var _a, _b, _c, _d;
1777
+ var _a, _b, _c, _d, _e, _f;
1778
+ // A sort bound to state is the visitor's, which the server cannot know: rows
1779
+ // pre-rendered in the table's order would stand in for it, since a seeded
1780
+ // provider skips its first fetch — the paginated lists drop them the same way.
1781
+ if (usage.dynamicSort) {
1782
+ 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'); });
1783
+ }
1765
1784
  var attrs = dp.openingElement.attributes;
1766
1785
  var clientCache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined;
1767
1786
  // Check if fetchData already exists
@@ -1784,10 +1803,12 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1784
1803
  }
1785
1804
  // Find the params attribute. A plain list may have none at all — but the
1786
1805
  // fetch it was just given sends `params` regardless, and in a localized
1787
- // project those have to carry the locale, so the attribute is created.
1806
+ // project those have to carry the locale, and a sorted list its sort, so the
1807
+ // attribute is created.
1788
1808
  var paramsAttrIndex = attrs.findIndex(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'params'; });
1809
+ var isSorted = usage.sorts.length > 0 || !!usage.dynamicSort;
1789
1810
  if (paramsAttrIndex === -1) {
1790
- if (!localized) {
1811
+ if (!localized && !isSorted) {
1791
1812
  return;
1792
1813
  }
1793
1814
  attrs.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression([]))));
@@ -1808,10 +1829,17 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1808
1829
  if (!paramsExpression) {
1809
1830
  return;
1810
1831
  }
1811
- // Build useMemo dependencies including filter state IDs
1832
+ // The repeater's sort, which the paginated and searchable lists add to the
1833
+ // params they rebuild: kept as they come, a plain list's params never
1834
+ // carried it, and the rows arrived in the table's own order.
1835
+ if (paramsExpression.type === 'ObjectExpression' && !hasObjectKey(paramsExpression, 'sorts')) {
1836
+ (0, sort_utils_1.appendSortsParam)(paramsExpression.properties, usage.sorts, usage.dynamicSort);
1837
+ }
1838
+ // Build useMemo dependencies including filter state IDs and a dynamic sort's state
1812
1839
  var memoDeps = [];
1813
1840
  var memoSeen = new Set();
1814
1841
  (0, filter_utils_1.pushStateIdsAsDeps)(memoDeps, memoSeen, usage.filterStateIds);
1842
+ (0, filter_utils_1.pushStateIdsAsDeps)(memoDeps, memoSeen, (_f = (_e = usage.dynamicSort) === null || _e === void 0 ? void 0 : _e.depStateIds) !== null && _f !== void 0 ? _f : []);
1815
1843
  (0, filter_utils_1.pushPropIdsAsDeps)(memoDeps, memoSeen, usage.filterPropIds);
1816
1844
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1817
1845
  if (localized && paramsExpression.type === 'ObjectExpression') {
@@ -1825,6 +1853,13 @@ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1825
1853
  // Replace the params attribute
1826
1854
  attrs[paramsAttrIndex] = types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(memoizedParams));
1827
1855
  }
1856
+ var hasObjectKey = function (object, key) {
1857
+ return object.properties.some(function (property) {
1858
+ return property.type === 'ObjectProperty' &&
1859
+ ((property.key.type === 'Identifier' && property.key.name === key) ||
1860
+ (property.key.type === 'StringLiteral' && property.key.value === key));
1861
+ });
1862
+ };
1828
1863
  function stabilizeDataProviderWithoutRepeater(dp) {
1829
1864
  var _a, _b, _c;
1830
1865
  var attrs = dp.openingElement.attributes;
@@ -2254,17 +2289,9 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2254
2289
  }
2255
2290
  // Add filters if present
2256
2291
  // Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
2257
- var staticFilters = (usage.filters || []).filter(function (f) { return !teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(f.destination); });
2292
+ var staticFilters = staticFiltersOf(usage);
2258
2293
  if (staticFilters.length > 0) {
2259
- fetchParams.push(types.objectProperty(types.identifier('filters'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
2260
- types.arrayExpression(staticFilters.map(function (filter) {
2261
- return types.objectExpression([
2262
- types.objectProperty(types.identifier('source'), types.stringLiteral(filter.source || '')),
2263
- types.objectProperty(types.identifier('destination'), types.stringLiteral(typeof filter.destination === 'string' ? filter.destination : '')),
2264
- types.objectProperty(types.identifier('operand'), types.stringLiteral(filter.operand || '')),
2265
- ]);
2266
- })),
2267
- ])));
2294
+ fetchParams.push(types.objectProperty(types.identifier('filters'), (0, filter_utils_1.buildStaticFiltersStringifyCall)(staticFilters)));
2268
2295
  }
2269
2296
  (0, items_path_1.appendItemsPathParam)(fetchParams, usage.itemsPath, 'itemsPath');
2270
2297
  // The prefetch is per locale — getStaticProps runs once per language.
@@ -2304,7 +2331,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2304
2331
  var maxPagesPropName_1 = "".concat(vars.propsPrefix, "_maxPages");
2305
2332
  // Use filter-specific count variable if usage has static filters
2306
2333
  // (dynamic filters can't be resolved at build time)
2307
- var staticFiltersForCount = (usage.filters || []).filter(function (f) { return !teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(f.destination); });
2334
+ var staticFiltersForCount = staticFiltersOf(usage);
2308
2335
  // A count scoped to an inner array is a different number from the
2309
2336
  // whole-payload one, so it gets its own variable just like a filtered one.
2310
2337
  var hasScopedCount = staticFiltersForCount.length > 0 || !!usage.itemsPath;
@@ -2355,7 +2382,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2355
2382
  usagesByFilters.forEach(function (usages, filtersKey) {
2356
2383
  var firstUsage = usages[0];
2357
2384
  // Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
2358
- var staticFiltersForCount = (firstUsage.filters || []).filter(function (f) { return !teleport_plugin_common_1.ASTUtils.isUIDLDynamicReference(f.destination); });
2385
+ var staticFiltersForCount = staticFiltersOf(firstUsage);
2359
2386
  var hasStaticFilters = staticFiltersForCount.length > 0;
2360
2387
  // Create unique count variable name based on filters (and inner-array
2361
2388
  // scope — must match the naming at the maxPages site above)
@@ -2375,15 +2402,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath, locali
2375
2402
  // Build count params if static filters exist
2376
2403
  var countParams = [];
2377
2404
  if (hasStaticFilters) {
2378
- countParams.push(types.objectProperty(types.identifier('filters'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [
2379
- types.arrayExpression(staticFiltersForCount.map(function (f) {
2380
- return types.objectExpression([
2381
- types.objectProperty(types.identifier('source'), types.stringLiteral(f.source || '')),
2382
- types.objectProperty(types.identifier('destination'), types.stringLiteral(typeof f.destination === 'string' ? f.destination : '')),
2383
- types.objectProperty(types.identifier('operand'), types.stringLiteral(f.operand || '')),
2384
- ]);
2385
- })),
2386
- ])));
2405
+ countParams.push(types.objectProperty(types.identifier('filters'), (0, filter_utils_1.buildStaticFiltersStringifyCall)(staticFiltersForCount)));
2387
2406
  }
2388
2407
  (0, items_path_1.appendItemsPathParam)(countParams, firstUsage.itemsPath, 'collectionPath');
2389
2408
  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')), [