@teleporthq/teleport-plugin-next-data-source 0.43.66 → 0.43.68

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 (334) hide show
  1. package/__tests__/array-mapper-cache-wiring.test.ts +11 -0
  2. package/__tests__/array-overlap-sql.test.ts +53 -0
  3. package/__tests__/blog-post-page-enrichment.test.ts +214 -0
  4. package/__tests__/browser-row-policy.test.ts +503 -0
  5. package/__tests__/data-source-cache-wrapping.test.ts +18 -2
  6. package/__tests__/data-source-request-locale.test.ts +313 -0
  7. package/__tests__/ecommerce-product-options.test.ts +206 -0
  8. package/__tests__/ecommerce-product-pages.test.ts +82 -0
  9. package/__tests__/ecommerce-product-pre-options.golden.json +505 -0
  10. package/__tests__/ecommerce-product-storefront-contract.test.ts +293 -0
  11. package/__tests__/ecommerce-product-subscriptions.test.ts +121 -0
  12. package/__tests__/fetchers.test.ts +2 -2
  13. package/__tests__/gated-data-provider.test.ts +88 -0
  14. package/__tests__/items-path.test.ts +150 -0
  15. package/__tests__/localized-columns.test.ts +217 -0
  16. package/__tests__/numbered-pagination.test.ts +15 -0
  17. package/__tests__/product-filter-fields.ts +230 -0
  18. package/__tests__/product-filter-sql.fixture.json +7 -0
  19. package/__tests__/product-options-storefront.fixture.json +2510 -0
  20. package/__tests__/product-page-url-fixtures.json +25 -0
  21. package/__tests__/product-price-sort.ts +4 -2
  22. package/__tests__/raw-rows-mode.test.ts +111 -0
  23. package/__tests__/refetch-loading-state.test.ts +23 -0
  24. package/__tests__/rest-api-response-cache.test.ts +434 -0
  25. package/__tests__/search-clear-button.test.ts +122 -0
  26. package/__tests__/table-read-route-protected-tables.test.ts +493 -0
  27. package/dist/cjs/array-overlap-sql.d.ts +21 -0
  28. package/dist/cjs/array-overlap-sql.d.ts.map +1 -0
  29. package/dist/cjs/array-overlap-sql.js +25 -0
  30. package/dist/cjs/array-overlap-sql.js.map +1 -0
  31. package/dist/cjs/content-localization.d.ts +37 -0
  32. package/dist/cjs/content-localization.d.ts.map +1 -0
  33. package/dist/cjs/content-localization.js +29 -0
  34. package/dist/cjs/content-localization.js.map +1 -0
  35. package/dist/cjs/count-effect.d.ts +11 -1
  36. package/dist/cjs/count-effect.d.ts.map +1 -1
  37. package/dist/cjs/count-effect.js +30 -2
  38. package/dist/cjs/count-effect.js.map +1 -1
  39. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  40. package/dist/cjs/data-source-fetchers.js +10 -4
  41. package/dist/cjs/data-source-fetchers.js.map +1 -1
  42. package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
  43. package/dist/cjs/fetchers/airtable.js +1 -1
  44. package/dist/cjs/fetchers/airtable.js.map +1 -1
  45. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  46. package/dist/cjs/fetchers/clickhouse.js +1 -1
  47. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  48. package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
  49. package/dist/cjs/fetchers/firestore.js +1 -1
  50. package/dist/cjs/fetchers/firestore.js.map +1 -1
  51. package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
  52. package/dist/cjs/fetchers/javascript.js +1 -1
  53. package/dist/cjs/fetchers/javascript.js.map +1 -1
  54. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
  55. package/dist/cjs/fetchers/mariadb.js +1 -1
  56. package/dist/cjs/fetchers/mariadb.js.map +1 -1
  57. package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
  58. package/dist/cjs/fetchers/mongodb.js +1 -1
  59. package/dist/cjs/fetchers/mongodb.js.map +1 -1
  60. package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
  61. package/dist/cjs/fetchers/mysql.js +1 -1
  62. package/dist/cjs/fetchers/mysql.js.map +1 -1
  63. package/dist/cjs/fetchers/postgresql.d.ts +1 -1
  64. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  65. package/dist/cjs/fetchers/postgresql.js +9 -4
  66. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  67. package/dist/cjs/fetchers/raw-query.d.ts +8 -1
  68. package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
  69. package/dist/cjs/fetchers/raw-query.js +42 -4
  70. package/dist/cjs/fetchers/raw-query.js.map +1 -1
  71. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  72. package/dist/cjs/fetchers/redshift.js +1 -1
  73. package/dist/cjs/fetchers/redshift.js.map +1 -1
  74. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  75. package/dist/cjs/fetchers/rest-api.js +7 -2
  76. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  77. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  78. package/dist/cjs/fetchers/teleport.js +16 -6
  79. package/dist/cjs/fetchers/teleport.js.map +1 -1
  80. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  81. package/dist/cjs/fetchers/turso.js +1 -1
  82. package/dist/cjs/fetchers/turso.js.map +1 -1
  83. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts +43 -0
  84. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -0
  85. package/dist/cjs/fetchers/utils/browser-row-policy.js +66 -0
  86. package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -0
  87. package/dist/cjs/fetchers/utils/request-sql-guards.d.ts +8 -0
  88. package/dist/cjs/fetchers/utils/request-sql-guards.d.ts.map +1 -0
  89. package/dist/cjs/fetchers/utils/request-sql-guards.js +12 -0
  90. package/dist/cjs/fetchers/utils/request-sql-guards.js.map +1 -0
  91. package/dist/cjs/fetchers/utils/rest-api-response-cache.d.ts +40 -0
  92. package/dist/cjs/fetchers/utils/rest-api-response-cache.d.ts.map +1 -0
  93. package/dist/cjs/fetchers/utils/rest-api-response-cache.js +64 -0
  94. package/dist/cjs/fetchers/utils/rest-api-response-cache.js.map +1 -0
  95. package/dist/cjs/fetchers/utils/table-access-guard.d.ts +23 -0
  96. package/dist/cjs/fetchers/utils/table-access-guard.d.ts.map +1 -0
  97. package/dist/cjs/fetchers/utils/table-access-guard.js +34 -0
  98. package/dist/cjs/fetchers/utils/table-access-guard.js.map +1 -0
  99. package/dist/cjs/index.d.ts +5 -0
  100. package/dist/cjs/index.d.ts.map +1 -1
  101. package/dist/cjs/index.js +60 -8
  102. package/dist/cjs/index.js.map +1 -1
  103. package/dist/cjs/items-path.d.ts +10 -0
  104. package/dist/cjs/items-path.d.ts.map +1 -0
  105. package/dist/cjs/items-path.js +86 -0
  106. package/dist/cjs/items-path.js.map +1 -0
  107. package/dist/cjs/loading-state.d.ts +16 -1
  108. package/dist/cjs/loading-state.d.ts.map +1 -1
  109. package/dist/cjs/loading-state.js +69 -3
  110. package/dist/cjs/loading-state.js.map +1 -1
  111. package/dist/cjs/localized-columns.d.ts +56 -0
  112. package/dist/cjs/localized-columns.d.ts.map +1 -0
  113. package/dist/cjs/localized-columns.js +137 -0
  114. package/dist/cjs/localized-columns.js.map +1 -0
  115. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  116. package/dist/cjs/pagination-plugin.js +140 -50
  117. package/dist/cjs/pagination-plugin.js.map +1 -1
  118. package/dist/cjs/product-filter-fields.d.ts +87 -0
  119. package/dist/cjs/product-filter-fields.d.ts.map +1 -0
  120. package/dist/cjs/product-filter-fields.js +161 -0
  121. package/dist/cjs/product-filter-fields.js.map +1 -0
  122. package/dist/cjs/request-locale.d.ts +49 -0
  123. package/dist/cjs/request-locale.d.ts.map +1 -0
  124. package/dist/cjs/request-locale.js +130 -0
  125. package/dist/cjs/request-locale.js.map +1 -0
  126. package/dist/cjs/search-clear.d.ts +31 -0
  127. package/dist/cjs/search-clear.d.ts.map +1 -0
  128. package/dist/cjs/search-clear.js +103 -0
  129. package/dist/cjs/search-clear.js.map +1 -0
  130. package/dist/cjs/transformations/blog-adjacent-posts.d.ts +16 -0
  131. package/dist/cjs/transformations/blog-adjacent-posts.d.ts.map +1 -0
  132. package/dist/cjs/transformations/blog-adjacent-posts.js +25 -0
  133. package/dist/cjs/transformations/blog-adjacent-posts.js.map +1 -0
  134. package/dist/cjs/transformations/blog-comments.d.ts +30 -0
  135. package/dist/cjs/transformations/blog-comments.d.ts.map +1 -0
  136. package/dist/cjs/transformations/blog-comments.js +34 -0
  137. package/dist/cjs/transformations/blog-comments.js.map +1 -0
  138. package/dist/cjs/transformations/blog-post.d.ts +2 -0
  139. package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
  140. package/dist/cjs/transformations/blog-post.js +4 -1
  141. package/dist/cjs/transformations/blog-post.js.map +1 -1
  142. package/dist/cjs/transformations/ecommerce-product.d.ts +9 -1
  143. package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
  144. package/dist/cjs/transformations/ecommerce-product.js +28 -1
  145. package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
  146. package/dist/cjs/transformations/heading-anchors.d.ts +25 -0
  147. package/dist/cjs/transformations/heading-anchors.d.ts.map +1 -0
  148. package/dist/cjs/transformations/heading-anchors.js +29 -0
  149. package/dist/cjs/transformations/heading-anchors.js.map +1 -0
  150. package/dist/cjs/transformations/index.d.ts +61 -4
  151. package/dist/cjs/transformations/index.d.ts.map +1 -1
  152. package/dist/cjs/transformations/index.js +69 -19
  153. package/dist/cjs/transformations/index.js.map +1 -1
  154. package/dist/cjs/transformations/shared-utils.d.ts.map +1 -1
  155. package/dist/cjs/transformations/shared-utils.js +1 -1
  156. package/dist/cjs/transformations/shared-utils.js.map +1 -1
  157. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  158. package/dist/cjs/utils.d.ts +11 -1
  159. package/dist/cjs/utils.d.ts.map +1 -1
  160. package/dist/cjs/utils.js +60 -16
  161. package/dist/cjs/utils.js.map +1 -1
  162. package/dist/esm/array-overlap-sql.d.ts +21 -0
  163. package/dist/esm/array-overlap-sql.d.ts.map +1 -0
  164. package/dist/esm/array-overlap-sql.js +21 -0
  165. package/dist/esm/array-overlap-sql.js.map +1 -0
  166. package/dist/esm/content-localization.d.ts +37 -0
  167. package/dist/esm/content-localization.d.ts.map +1 -0
  168. package/dist/esm/content-localization.js +24 -0
  169. package/dist/esm/content-localization.js.map +1 -0
  170. package/dist/esm/count-effect.d.ts +11 -1
  171. package/dist/esm/count-effect.d.ts.map +1 -1
  172. package/dist/esm/count-effect.js +28 -1
  173. package/dist/esm/count-effect.js.map +1 -1
  174. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  175. package/dist/esm/data-source-fetchers.js +11 -5
  176. package/dist/esm/data-source-fetchers.js.map +1 -1
  177. package/dist/esm/fetchers/airtable.d.ts.map +1 -1
  178. package/dist/esm/fetchers/airtable.js +1 -1
  179. package/dist/esm/fetchers/airtable.js.map +1 -1
  180. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  181. package/dist/esm/fetchers/clickhouse.js +1 -1
  182. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  183. package/dist/esm/fetchers/firestore.d.ts.map +1 -1
  184. package/dist/esm/fetchers/firestore.js +1 -1
  185. package/dist/esm/fetchers/firestore.js.map +1 -1
  186. package/dist/esm/fetchers/javascript.d.ts.map +1 -1
  187. package/dist/esm/fetchers/javascript.js +1 -1
  188. package/dist/esm/fetchers/javascript.js.map +1 -1
  189. package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
  190. package/dist/esm/fetchers/mariadb.js +1 -1
  191. package/dist/esm/fetchers/mariadb.js.map +1 -1
  192. package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
  193. package/dist/esm/fetchers/mongodb.js +1 -1
  194. package/dist/esm/fetchers/mongodb.js.map +1 -1
  195. package/dist/esm/fetchers/mysql.d.ts.map +1 -1
  196. package/dist/esm/fetchers/mysql.js +1 -1
  197. package/dist/esm/fetchers/mysql.js.map +1 -1
  198. package/dist/esm/fetchers/postgresql.d.ts +1 -1
  199. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  200. package/dist/esm/fetchers/postgresql.js +9 -4
  201. package/dist/esm/fetchers/postgresql.js.map +1 -1
  202. package/dist/esm/fetchers/raw-query.d.ts +8 -1
  203. package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
  204. package/dist/esm/fetchers/raw-query.js +42 -4
  205. package/dist/esm/fetchers/raw-query.js.map +1 -1
  206. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  207. package/dist/esm/fetchers/redshift.js +1 -1
  208. package/dist/esm/fetchers/redshift.js.map +1 -1
  209. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  210. package/dist/esm/fetchers/rest-api.js +7 -2
  211. package/dist/esm/fetchers/rest-api.js.map +1 -1
  212. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  213. package/dist/esm/fetchers/teleport.js +16 -6
  214. package/dist/esm/fetchers/teleport.js.map +1 -1
  215. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  216. package/dist/esm/fetchers/turso.js +1 -1
  217. package/dist/esm/fetchers/turso.js.map +1 -1
  218. package/dist/esm/fetchers/utils/browser-row-policy.d.ts +43 -0
  219. package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -0
  220. package/dist/esm/fetchers/utils/browser-row-policy.js +60 -0
  221. package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -0
  222. package/dist/esm/fetchers/utils/request-sql-guards.d.ts +8 -0
  223. package/dist/esm/fetchers/utils/request-sql-guards.d.ts.map +1 -0
  224. package/dist/esm/fetchers/utils/request-sql-guards.js +8 -0
  225. package/dist/esm/fetchers/utils/request-sql-guards.js.map +1 -0
  226. package/dist/esm/fetchers/utils/rest-api-response-cache.d.ts +40 -0
  227. package/dist/esm/fetchers/utils/rest-api-response-cache.d.ts.map +1 -0
  228. package/dist/esm/fetchers/utils/rest-api-response-cache.js +59 -0
  229. package/dist/esm/fetchers/utils/rest-api-response-cache.js.map +1 -0
  230. package/dist/esm/fetchers/utils/table-access-guard.d.ts +23 -0
  231. package/dist/esm/fetchers/utils/table-access-guard.d.ts.map +1 -0
  232. package/dist/esm/fetchers/utils/table-access-guard.js +29 -0
  233. package/dist/esm/fetchers/utils/table-access-guard.js.map +1 -0
  234. package/dist/esm/index.d.ts +5 -0
  235. package/dist/esm/index.d.ts.map +1 -1
  236. package/dist/esm/index.js +55 -7
  237. package/dist/esm/index.js.map +1 -1
  238. package/dist/esm/items-path.d.ts +10 -0
  239. package/dist/esm/items-path.d.ts.map +1 -0
  240. package/dist/esm/items-path.js +58 -0
  241. package/dist/esm/items-path.js.map +1 -0
  242. package/dist/esm/loading-state.d.ts +16 -1
  243. package/dist/esm/loading-state.d.ts.map +1 -1
  244. package/dist/esm/loading-state.js +69 -3
  245. package/dist/esm/loading-state.js.map +1 -1
  246. package/dist/esm/localized-columns.d.ts +56 -0
  247. package/dist/esm/localized-columns.d.ts.map +1 -0
  248. package/dist/esm/localized-columns.js +132 -0
  249. package/dist/esm/localized-columns.js.map +1 -0
  250. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  251. package/dist/esm/pagination-plugin.js +141 -51
  252. package/dist/esm/pagination-plugin.js.map +1 -1
  253. package/dist/esm/product-filter-fields.d.ts +87 -0
  254. package/dist/esm/product-filter-fields.d.ts.map +1 -0
  255. package/dist/esm/product-filter-fields.js +154 -0
  256. package/dist/esm/product-filter-fields.js.map +1 -0
  257. package/dist/esm/request-locale.d.ts +49 -0
  258. package/dist/esm/request-locale.d.ts.map +1 -0
  259. package/dist/esm/request-locale.js +98 -0
  260. package/dist/esm/request-locale.js.map +1 -0
  261. package/dist/esm/search-clear.d.ts +31 -0
  262. package/dist/esm/search-clear.d.ts.map +1 -0
  263. package/dist/esm/search-clear.js +74 -0
  264. package/dist/esm/search-clear.js.map +1 -0
  265. package/dist/esm/transformations/blog-adjacent-posts.d.ts +16 -0
  266. package/dist/esm/transformations/blog-adjacent-posts.d.ts.map +1 -0
  267. package/dist/esm/transformations/blog-adjacent-posts.js +21 -0
  268. package/dist/esm/transformations/blog-adjacent-posts.js.map +1 -0
  269. package/dist/esm/transformations/blog-comments.d.ts +30 -0
  270. package/dist/esm/transformations/blog-comments.d.ts.map +1 -0
  271. package/dist/esm/transformations/blog-comments.js +30 -0
  272. package/dist/esm/transformations/blog-comments.js.map +1 -0
  273. package/dist/esm/transformations/blog-post.d.ts +2 -0
  274. package/dist/esm/transformations/blog-post.d.ts.map +1 -1
  275. package/dist/esm/transformations/blog-post.js +4 -1
  276. package/dist/esm/transformations/blog-post.js.map +1 -1
  277. package/dist/esm/transformations/ecommerce-product.d.ts +9 -1
  278. package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
  279. package/dist/esm/transformations/ecommerce-product.js +29 -2
  280. package/dist/esm/transformations/ecommerce-product.js.map +1 -1
  281. package/dist/esm/transformations/heading-anchors.d.ts +25 -0
  282. package/dist/esm/transformations/heading-anchors.d.ts.map +1 -0
  283. package/dist/esm/transformations/heading-anchors.js +25 -0
  284. package/dist/esm/transformations/heading-anchors.js.map +1 -0
  285. package/dist/esm/transformations/index.d.ts +61 -4
  286. package/dist/esm/transformations/index.d.ts.map +1 -1
  287. package/dist/esm/transformations/index.js +69 -19
  288. package/dist/esm/transformations/index.js.map +1 -1
  289. package/dist/esm/transformations/shared-utils.d.ts.map +1 -1
  290. package/dist/esm/transformations/shared-utils.js +1 -1
  291. package/dist/esm/transformations/shared-utils.js.map +1 -1
  292. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  293. package/dist/esm/utils.d.ts +11 -1
  294. package/dist/esm/utils.d.ts.map +1 -1
  295. package/dist/esm/utils.js +60 -16
  296. package/dist/esm/utils.js.map +1 -1
  297. package/package.json +5 -5
  298. package/src/array-overlap-sql.ts +41 -0
  299. package/src/content-localization.ts +53 -0
  300. package/src/count-effect.ts +53 -2
  301. package/src/data-source-fetchers.ts +41 -5
  302. package/src/fetchers/airtable.ts +4 -2
  303. package/src/fetchers/clickhouse.ts +4 -2
  304. package/src/fetchers/firestore.ts +4 -2
  305. package/src/fetchers/javascript.ts +9 -1
  306. package/src/fetchers/mariadb.ts +4 -2
  307. package/src/fetchers/mongodb.ts +4 -2
  308. package/src/fetchers/mysql.ts +4 -2
  309. package/src/fetchers/postgresql.ts +53 -12
  310. package/src/fetchers/raw-query.ts +60 -5
  311. package/src/fetchers/redshift.ts +4 -2
  312. package/src/fetchers/rest-api.ts +27 -5
  313. package/src/fetchers/teleport.ts +85 -22
  314. package/src/fetchers/turso.ts +4 -2
  315. package/src/fetchers/utils/browser-row-policy.ts +212 -0
  316. package/src/fetchers/utils/request-sql-guards.ts +25 -0
  317. package/src/fetchers/utils/rest-api-response-cache.ts +188 -0
  318. package/src/fetchers/utils/table-access-guard.ts +39 -0
  319. package/src/index.ts +79 -11
  320. package/src/items-path.ts +74 -0
  321. package/src/loading-state.ts +134 -3
  322. package/src/localized-columns.ts +146 -0
  323. package/src/pagination-plugin.ts +206 -60
  324. package/src/product-filter-fields.ts +173 -0
  325. package/src/request-locale.ts +113 -0
  326. package/src/search-clear.ts +102 -0
  327. package/src/transformations/blog-adjacent-posts.ts +74 -0
  328. package/src/transformations/blog-comments.ts +132 -0
  329. package/src/transformations/blog-post.ts +38 -5
  330. package/src/transformations/ecommerce-product.ts +568 -5
  331. package/src/transformations/heading-anchors.ts +85 -0
  332. package/src/transformations/index.ts +191 -23
  333. package/src/transformations/shared-utils.ts +6 -0
  334. package/src/utils.ts +109 -19
@@ -53,15 +53,19 @@ import { generateDataSourceFetcherWithCore } from './data-source-fetchers';
53
53
  import { buildProductTransformOptions } from './transformations';
54
54
  import { appendSortsParam, extractDynamicSort } from './sort-utils';
55
55
  import { appendFiltersParam, pushStateIdsAsDeps, pushPropIdsAsDeps } from './filter-utils';
56
+ import { appendItemsPathParam, extractItemsPath } from './items-path';
56
57
  import { applyLoadingStateToDataProvider, buildLoadingStateDeclarations, getLoadingStateVars, } from './loading-state';
57
58
  import { mergeServerCacheOptions, resolveCacheFromRepeaterContent } from './cache/config';
58
59
  import { buildCacheHydrationEffect, buildCacheStoreThen, buildCachedFetchBody, buildCachedParamsDeclarations, registerCacheClientImports, } from './cache/ast';
59
60
  import { convertControlToButton, dropInactivePaginationControls, findPaginationControl, setJSXExpressionAttribute, } from './pagination-controls';
60
- import { buildCountFetchEffect } from './count-effect';
61
+ import { buildCountFetchEffect, buildCountSeqDeclaration } from './count-effect';
62
+ import { findAllSearchClearButtonsInJSX, findSiblingSearchInput, wireSearchClearButton, } from './search-clear';
61
63
  import { buildPageTokensDeclaration, wireNumberedPagination, } from './numbered-pagination';
62
64
  import { buildAccumulatingResponseHandler, buildInfiniteScrollDeclarations, buildSentinelElement, buildSentinelObserverEffect, getInfiniteScrollVars, } from './infinite-scroll';
63
65
  import { buildFilterSortPageResetEffect, buildPageResetRefDeclaration, hasNoPageResetDeps, } from './page-reset';
64
66
  import { buildPageUrlRefDeclaration, buildPageUrlSyncEffect } from './page-url-sync';
67
+ import { isLocalizedProject } from './content-localization';
68
+ import { appendClientLocaleParam, buildClientLocaleExpression, buildServerLocaleParam, ensureRouterDeclaration, hasLocaleParam, } from './request-locale';
65
69
  // tslint:disable-next-line:no-any
66
70
  function parseSearchDefaultValue(raw) {
67
71
  if (!raw || typeof raw !== 'object') {
@@ -453,6 +457,7 @@ function buildStateRegistry(uidlNode) {
453
457
  infiniteScroll: infiniteScroll,
454
458
  infiniteScrollLoadMore: infiniteScroll && !!content.infiniteScrollLoadMore,
455
459
  pageUrlParamKey: pageUrlParamKey,
460
+ itemsPath: extractItemsPath(content.source, parentDataSource.identifier, parentDataSource.resourceDef.dataSourceType || ''),
456
461
  category: 'plain',
457
462
  };
458
463
  // Determine category
@@ -531,6 +536,7 @@ function getStateVarsForUsage(usage) {
531
536
  combinedStateVar: "ds_".concat(idx, "_state"),
532
537
  setCombinedStateVar: "setDs_".concat(idx, "_state"),
533
538
  skipDebounceRefVar: "ds_".concat(idx, "_skipDebounce"),
539
+ countSeqRefVar: "ds_".concat(idx, "_countSeq"),
534
540
  propsPrefix: "".concat(usage.dataSourceIdentifier, "_ds_").concat(idx),
535
541
  };
536
542
  }
@@ -743,7 +749,7 @@ function pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usag
743
749
  // ==================== MAIN PLUGIN ====================
744
750
  export var createNextArrayMapperPaginationPlugin = function () {
745
751
  var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
746
- var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, stateDeclarations, effectStatements, needsUseRouter, hasRouterDecl, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages;
752
+ var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages, usageBySearchInput;
747
753
  var _a, _b;
748
754
  return __generator(this, function (_c) {
749
755
  uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
@@ -773,6 +779,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
773
779
  }
774
780
  getStaticPropsChunk = chunks.find(function (chunk) { return chunk.name === 'getStaticProps'; });
775
781
  isPage = !!getStaticPropsChunk;
782
+ localized = isLocalizedProject(options);
776
783
  // Add React dependencies
777
784
  if (!dependencies.useState) {
778
785
  dependencies.useState = {
@@ -920,6 +927,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
920
927
  }
921
928
  // Add filters to count fetch params if present
922
929
  appendFiltersParam(urlParams, usage.filters, buildFilterDestinationExpression);
930
+ appendItemsPathParam(urlParams, usage.itemsPath, 'collectionPath');
923
931
  var countEffectDeps = [
924
932
  types.memberExpression(types.identifier(vars.combinedStateVar), types.identifier('debouncedQuery')),
925
933
  ];
@@ -934,12 +942,14 @@ export var createNextArrayMapperPaginationPlugin = function () {
934
942
  pushPropIdsAsDeps(countEffectDeps, countEffectSeen, usage.filterPropIds);
935
943
  // Same goes for URL-driven filters (already documented above).
936
944
  pushUrlSearchParamMemoDeps(countEffectDeps, usage);
945
+ stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
937
946
  effectStatements.push(buildCountFetchEffect({
938
947
  fileName: fileName,
939
948
  perPage: usage.perPage,
940
949
  setMaxPagesVar: vars.setMaxPagesStateVar,
941
950
  urlParams: urlParams,
942
951
  deps: countEffectDeps,
952
+ countSeqRefVar: vars.countSeqRefVar,
943
953
  }));
944
954
  // Two-way URL sync for the search input when bound to a URL param.
945
955
  pushSearchUrlSyncEffects(effectStatements, usage, vars);
@@ -990,6 +1000,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
990
1000
  countUrlParams.push(types.objectProperty(types.identifier('queryColumns'), types.callExpression(types.memberExpression(types.identifier('JSON'), types.identifier('stringify')), [types.arrayExpression(usage.queryColumns.map(function (c) { return types.stringLiteral(c); }))])));
991
1001
  }
992
1002
  appendFiltersParam(countUrlParams, usage.filters, buildFilterDestinationExpression);
1003
+ appendItemsPathParam(countUrlParams, usage.itemsPath, 'collectionPath');
993
1004
  // Default to mount-only; refresh when ANY filter destination
994
1005
  // changes — state-bound (e.g. `selectedCategory`) and URL-driven —
995
1006
  // so the pagination control reflects the current filtered count
@@ -999,12 +1010,14 @@ export var createNextArrayMapperPaginationPlugin = function () {
999
1010
  pushStateIdsAsDeps(countDeps, countDepsSeen, usage.filterStateIds);
1000
1011
  pushPropIdsAsDeps(countDeps, countDepsSeen, usage.filterPropIds);
1001
1012
  pushUrlSearchParamMemoDeps(countDeps, usage);
1013
+ stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
1002
1014
  effectStatements.push(buildCountFetchEffect({
1003
1015
  fileName: fileName,
1004
1016
  perPage: usage.perPage,
1005
1017
  setMaxPagesVar: vars.setMaxPagesStateVar,
1006
1018
  urlParams: countUrlParams,
1007
1019
  deps: countDeps,
1020
+ countSeqRefVar: vars.countSeqRefVar,
1008
1021
  }));
1009
1022
  }
1010
1023
  // Visible page numbers, when this mapper draws a numbered strip.
@@ -1061,35 +1074,10 @@ export var createNextArrayMapperPaginationPlugin = function () {
1061
1074
  });
1062
1075
  // Insert state declarations at the beginning
1063
1076
  stateDeclarations.reverse().forEach(function (s) { return blockStatement.body.unshift(s); });
1064
- needsUseRouter = registry.usages.some(function (u) { return hasUrlSearchParamFilters(u) || usageHasSearchUrlSync(u) || usageHasPageUrlSync(u); });
1077
+ needsUseRouter = localized ||
1078
+ registry.usages.some(function (u) { return hasUrlSearchParamFilters(u) || usageHasSearchUrlSync(u) || usageHasPageUrlSync(u); });
1065
1079
  if (needsUseRouter) {
1066
- if (!dependencies.useRouter) {
1067
- // Match the shape the sibling Next.js plugins use (i18n locale mapper,
1068
- // search-params plugin) so the deduped import line is identical and
1069
- // the dependency-resolver merges instead of emitting a second one.
1070
- dependencies.useRouter = {
1071
- type: 'library',
1072
- path: 'next/router',
1073
- version: '^12.1.10',
1074
- meta: { namedImport: true },
1075
- };
1076
- }
1077
- hasRouterDecl = blockStatement.body.some(function (statement) {
1078
- return statement.type === 'VariableDeclaration' &&
1079
- statement.declarations.some(function (decl) {
1080
- var _a;
1081
- return decl.id.type === 'Identifier' &&
1082
- decl.id.name === 'router' &&
1083
- ((_a = decl.init) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression' &&
1084
- decl.init.callee.type === 'Identifier' &&
1085
- decl.init.callee.name === 'useRouter';
1086
- });
1087
- });
1088
- if (!hasRouterDecl) {
1089
- blockStatement.body.unshift(types.variableDeclaration('const', [
1090
- types.variableDeclarator(types.identifier('router'), types.callExpression(types.identifier('useRouter'), [])),
1091
- ]));
1092
- }
1080
+ ensureRouterDeclaration(blockStatement.body, dependencies);
1093
1081
  }
1094
1082
  // Both the search write-back and the page ⇄ URL effect write the URL through
1095
1083
  // the shared `URLQueryWriter`, so the ref + helper they close over must be in
@@ -1131,16 +1119,16 @@ export var createNextArrayMapperPaginationPlugin = function () {
1131
1119
  var fileName = generateSafeFileName(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
1132
1120
  // Update DataProvider based on category
1133
1121
  if (usage.category === 'paginated+search') {
1134
- updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations);
1122
+ updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized);
1135
1123
  }
1136
1124
  else if (usage.category === 'paginated-only') {
1137
- updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations);
1125
+ updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
1138
1126
  }
1139
1127
  else if (usage.category === 'search-only') {
1140
- updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations);
1128
+ updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
1141
1129
  }
1142
1130
  else if (usage.category === 'plain') {
1143
- updateDataProviderForPlain(dp, fileName, usage);
1131
+ updateDataProviderForPlain(dp, fileName, usage, localized);
1144
1132
  }
1145
1133
  // Show the array mapper's loading state while a category/sort/search
1146
1134
  // change refetches, instead of leaving the previous rows on screen with
@@ -1200,7 +1188,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
1200
1188
  });
1201
1189
  searchInputs = findAllSearchInputsInJSX(blockStatement);
1202
1190
  searchEnabledUsages = registry.usages.filter(function (u) { return u.searchEnabled; });
1203
- // Match by order - search input 0 -> searchEnabledUsages[0], etc.
1191
+ usageBySearchInput = new Map();
1204
1192
  searchInputs.forEach(function (input, idx) {
1205
1193
  if (idx >= searchEnabledUsages.length) {
1206
1194
  return;
@@ -1208,6 +1196,15 @@ export var createNextArrayMapperPaginationPlugin = function () {
1208
1196
  var usage = searchEnabledUsages[idx];
1209
1197
  var vars = getStateVarsForUsage(usage);
1210
1198
  wireSearchInput(input.node, vars);
1199
+ usageBySearchInput.set(input.node, usage);
1200
+ });
1201
+ // STEP 4.5: Wire the clear buttons, each to the input it shares a parent with.
1202
+ findAllSearchClearButtonsInJSX(blockStatement).forEach(function (button) {
1203
+ var input = findSiblingSearchInput(button, searchInputs.map(function (entry) { return entry.node; }));
1204
+ var usage = input ? usageBySearchInput.get(input) : undefined;
1205
+ if (usage) {
1206
+ wireSearchClearButton(button, getStateVarsForUsage(usage));
1207
+ }
1211
1208
  });
1212
1209
  // STEP 5: Wire pagination widgets
1213
1210
  //
@@ -1229,7 +1226,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
1229
1226
  });
1230
1227
  // STEP 6: Update getStaticProps if this is a page
1231
1228
  if (isPage) {
1232
- updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath);
1229
+ updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath, localized);
1233
1230
  }
1234
1231
  return [2 /*return*/, structure];
1235
1232
  });
@@ -1278,6 +1275,20 @@ function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
1278
1275
  if (node.alternate) {
1279
1276
  traverse(node.alternate);
1280
1277
  }
1278
+ // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1279
+ // panel, a gated section: the provider sits on the RIGHT of a logical
1280
+ // expression (or in a ternary's `test`), which is not a child, a body or
1281
+ // an argument. Left unvisited, the products list under the first tab of
1282
+ // a shop was never paginated or seeded, and rendered nothing.
1283
+ if (node.left) {
1284
+ traverse(node.left);
1285
+ }
1286
+ if (node.right) {
1287
+ traverse(node.right);
1288
+ }
1289
+ if (node.test) {
1290
+ traverse(node.test);
1291
+ }
1281
1292
  if (node.expression) {
1282
1293
  traverse(node.expression);
1283
1294
  }
@@ -1315,6 +1326,20 @@ function findAllDataProvidersInJSX(blockStatement) {
1315
1326
  if (node.alternate) {
1316
1327
  traverse(node.alternate);
1317
1328
  }
1329
+ // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1330
+ // panel, a gated section: the provider sits on the RIGHT of a logical
1331
+ // expression (or in a ternary's `test`), which is not a child, a body or
1332
+ // an argument. Left unvisited, the products list under the first tab of
1333
+ // a shop was never paginated or seeded, and rendered nothing.
1334
+ if (node.left) {
1335
+ traverse(node.left);
1336
+ }
1337
+ if (node.right) {
1338
+ traverse(node.right);
1339
+ }
1340
+ if (node.test) {
1341
+ traverse(node.test);
1342
+ }
1318
1343
  if (node.expression) {
1319
1344
  traverse(node.expression);
1320
1345
  }
@@ -1397,6 +1422,20 @@ function findAllSearchInputsInJSX(blockStatement) {
1397
1422
  if (node.alternate) {
1398
1423
  traverse(node.alternate);
1399
1424
  }
1425
+ // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1426
+ // panel, a gated section: the provider sits on the RIGHT of a logical
1427
+ // expression (or in a ternary's `test`), which is not a child, a body or
1428
+ // an argument. Left unvisited, the products list under the first tab of
1429
+ // a shop was never paginated or seeded, and rendered nothing.
1430
+ if (node.left) {
1431
+ traverse(node.left);
1432
+ }
1433
+ if (node.right) {
1434
+ traverse(node.right);
1435
+ }
1436
+ if (node.test) {
1437
+ traverse(node.test);
1438
+ }
1400
1439
  if (node.expression) {
1401
1440
  traverse(node.expression);
1402
1441
  }
@@ -1452,6 +1491,20 @@ function findPaginationNodesWithOwners(blockStatement, usageByProviderNode) {
1452
1491
  if (node.alternate) {
1453
1492
  traverse(node.alternate);
1454
1493
  }
1494
+ // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1495
+ // panel, a gated section: the provider sits on the RIGHT of a logical
1496
+ // expression (or in a ternary's `test`), which is not a child, a body or
1497
+ // an argument. Left unvisited, the products list under the first tab of
1498
+ // a shop was never paginated or seeded, and rendered nothing.
1499
+ if (node.left) {
1500
+ traverse(node.left);
1501
+ }
1502
+ if (node.right) {
1503
+ traverse(node.right);
1504
+ }
1505
+ if (node.test) {
1506
+ traverse(node.test);
1507
+ }
1455
1508
  if (node.expression) {
1456
1509
  traverse(node.expression);
1457
1510
  }
@@ -1494,7 +1547,7 @@ dp, usage, paramsProps, memoDeps, cacheDeclarations) {
1494
1547
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.identifier(hoisted.paramsIdentifier))));
1495
1548
  return hoisted.cachedIdentifier;
1496
1549
  }
1497
- function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations) {
1550
+ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized) {
1498
1551
  var attrs = dp.openingElement.attributes;
1499
1552
  // Remove existing params, key, initialData, fetchData, persistDataDuringLoading
1500
1553
  dp.openingElement.attributes = attrs.filter(function (attr) {
@@ -1514,6 +1567,7 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
1514
1567
  appendSortsParam(paramsProps, usage.sorts, usage.dynamicSort);
1515
1568
  // Add filters if present
1516
1569
  appendFiltersParam(paramsProps, usage.filters, buildFilterDestinationExpression);
1570
+ appendItemsPathParam(paramsProps, usage.itemsPath, 'itemsPath');
1517
1571
  // Build useMemo dependencies including filter state IDs and dynamic sort state IDs
1518
1572
  var memoDeps = [types.identifier(vars.combinedStateVar)];
1519
1573
  var seenDeps = new Set([vars.combinedStateVar]);
@@ -1523,6 +1577,9 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
1523
1577
  pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
1524
1578
  }
1525
1579
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1580
+ if (localized) {
1581
+ appendClientLocaleParam(paramsProps, memoDeps);
1582
+ }
1526
1583
  var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
1527
1584
  // Add initialData. Skip the server-prefetched data entirely when a dynamic
1528
1585
  // state-bound sort is active — the prefetch ran without sort parameters, so
@@ -1574,7 +1631,7 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
1574
1631
  // Add persistDataDuringLoading
1575
1632
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1576
1633
  }
1577
- function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations) {
1634
+ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized) {
1578
1635
  var attrs = dp.openingElement.attributes;
1579
1636
  dp.openingElement.attributes = attrs.filter(function (attr) {
1580
1637
  var _a;
@@ -1589,6 +1646,7 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
1589
1646
  appendSortsParam(paramsProps, usage.sorts, usage.dynamicSort);
1590
1647
  // Add filters if present
1591
1648
  appendFiltersParam(paramsProps, usage.filters, buildFilterDestinationExpression);
1649
+ appendItemsPathParam(paramsProps, usage.itemsPath, 'itemsPath');
1592
1650
  // Build useMemo dependencies including filter state IDs and dynamic sort state IDs
1593
1651
  var memoDeps = [types.identifier(vars.pageStateVar)];
1594
1652
  var seenDeps = new Set([vars.pageStateVar]);
@@ -1598,6 +1656,9 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
1598
1656
  pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
1599
1657
  }
1600
1658
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1659
+ if (localized) {
1660
+ appendClientLocaleParam(paramsProps, memoDeps);
1661
+ }
1601
1662
  // Add params
1602
1663
  var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
1603
1664
  // Add initialData. See paginated+search updater for why we skip prefetch
@@ -1623,7 +1684,7 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
1623
1684
  dp.openingElement.attributes.push(buildFetchDataForUsage(fileName, usage));
1624
1685
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1625
1686
  }
1626
- function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations) {
1687
+ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations, localized) {
1627
1688
  var _a;
1628
1689
  var attrs = dp.openingElement.attributes;
1629
1690
  dp.openingElement.attributes = attrs.filter(function (attr) {
@@ -1641,6 +1702,7 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
1641
1702
  appendSortsParam(paramsProps, usage.sorts, usage.dynamicSort);
1642
1703
  // Add filters if present
1643
1704
  appendFiltersParam(paramsProps, usage.filters, buildFilterDestinationExpression);
1705
+ appendItemsPathParam(paramsProps, usage.itemsPath, 'itemsPath');
1644
1706
  // Build useMemo dependencies including filter state IDs and dynamic sort state IDs
1645
1707
  var memoDeps = [types.identifier(vars.debouncedSearchQueryVar)];
1646
1708
  var seenDeps = new Set([vars.debouncedSearchQueryVar]);
@@ -1650,6 +1712,9 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
1650
1712
  pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
1651
1713
  }
1652
1714
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1715
+ if (localized) {
1716
+ appendClientLocaleParam(paramsProps, memoDeps);
1717
+ }
1653
1718
  var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
1654
1719
  // Add initialData. See paginated+search updater for why we skip prefetch
1655
1720
  // reuse when a dynamic state-bound sort is active.
@@ -1665,7 +1730,7 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
1665
1730
  dp.openingElement.attributes.push(createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined));
1666
1731
  dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1667
1732
  }
1668
- function updateDataProviderForPlain(dp, fileName, usage) {
1733
+ function updateDataProviderForPlain(dp, fileName, usage, localized) {
1669
1734
  var _a, _b, _c, _d;
1670
1735
  var attrs = dp.openingElement.attributes;
1671
1736
  var clientCache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined;
@@ -1687,10 +1752,16 @@ function updateDataProviderForPlain(dp, fileName, usage) {
1687
1752
  if (!hasPersistData) {
1688
1753
  attrs.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
1689
1754
  }
1690
- // Find the params attribute
1755
+ // Find the params attribute. A plain list may have none at all — but the
1756
+ // fetch it was just given sends `params` regardless, and in a localized
1757
+ // project those have to carry the locale, so the attribute is created.
1691
1758
  var paramsAttrIndex = attrs.findIndex(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'params'; });
1692
1759
  if (paramsAttrIndex === -1) {
1693
- return;
1760
+ if (!localized) {
1761
+ return;
1762
+ }
1763
+ attrs.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression([]))));
1764
+ paramsAttrIndex = attrs.length - 1;
1694
1765
  }
1695
1766
  var paramsAttr = attrs[paramsAttrIndex];
1696
1767
  // Check if params is already wrapped in useMemo
@@ -1713,6 +1784,9 @@ function updateDataProviderForPlain(dp, fileName, usage) {
1713
1784
  pushStateIdsAsDeps(memoDeps, memoSeen, usage.filterStateIds);
1714
1785
  pushPropIdsAsDeps(memoDeps, memoSeen, usage.filterPropIds);
1715
1786
  pushUrlSearchParamMemoDeps(memoDeps, usage);
1787
+ if (localized && paramsExpression.type === 'ObjectExpression') {
1788
+ appendClientLocaleParam(paramsExpression.properties, memoDeps);
1789
+ }
1716
1790
  // Wrap params in useMemo with filter state dependencies
1717
1791
  var memoizedParams = types.callExpression(types.identifier('useMemo'), [
1718
1792
  types.arrowFunctionExpression([], paramsExpression),
@@ -1744,11 +1818,18 @@ function stabilizeDataProviderWithoutRepeater(dp) {
1744
1818
  if (!paramsExpression) {
1745
1819
  return;
1746
1820
  }
1747
- // Wrap params in useMemo with empty dependencies array
1748
- // This ensures the object reference stays stable across re-renders
1821
+ // Wrap params in useMemo with an empty dependencies array so the object
1822
+ // reference stays stable across re-renders. The one thing that may vary is
1823
+ // the locale a client-fetched item carries (put there by the data-source
1824
+ // plugin): a locale switch must rebuild the params, or the item would keep
1825
+ // its previous language.
1826
+ var memoDeps = [];
1827
+ if (paramsExpression.type === 'ObjectExpression' && hasLocaleParam(paramsExpression.properties)) {
1828
+ memoDeps.push(buildClientLocaleExpression());
1829
+ }
1749
1830
  var memoizedParams = types.callExpression(types.identifier('useMemo'), [
1750
1831
  types.arrowFunctionExpression([], paramsExpression),
1751
- types.arrayExpression([]),
1832
+ types.arrayExpression(memoDeps),
1752
1833
  ]);
1753
1834
  // Replace the params attribute
1754
1835
  attrs[paramsAttrIndex] = types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(memoizedParams));
@@ -2060,7 +2141,7 @@ function ensureAPIRouteExists(extractedResources, usage, dataSources, transformO
2060
2141
  };
2061
2142
  }
2062
2143
  }
2063
- function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2144
+ function updateGetStaticProps(chunks, registry, dependencies, folderPath, localized) {
2064
2145
  var _a;
2065
2146
  var getStaticPropsChunk = chunks.find(function (c) { return c.name === 'getStaticProps'; });
2066
2147
  if (!getStaticPropsChunk || getStaticPropsChunk.type !== ChunkType.AST) {
@@ -2155,6 +2236,11 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2155
2236
  })),
2156
2237
  ])));
2157
2238
  }
2239
+ appendItemsPathParam(fetchParams, usage.itemsPath, 'itemsPath');
2240
+ // The prefetch is per locale — getStaticProps runs once per language.
2241
+ if (localized) {
2242
+ fetchParams.push(buildServerLocaleParam());
2243
+ }
2158
2244
  // Check if this fetch already exists
2159
2245
  var existingFetchIndex = arrayPattern.elements.findIndex(function (el) { return (el === null || el === void 0 ? void 0 : el.type) === 'Identifier' && el.name === vars.propsPrefix; });
2160
2246
  if (existingFetchIndex === -1) {
@@ -2189,8 +2275,10 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2189
2275
  // Use filter-specific count variable if usage has static filters
2190
2276
  // (dynamic filters can't be resolved at build time)
2191
2277
  var staticFiltersForCount = (usage.filters || []).filter(function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
2192
- var hasStaticFilters = staticFiltersForCount.length > 0;
2193
- var countVarName = hasStaticFilters
2278
+ // A count scoped to an inner array is a different number from the
2279
+ // whole-payload one, so it gets its own variable just like a filtered one.
2280
+ var hasScopedCount = staticFiltersForCount.length > 0 || !!usage.itemsPath;
2281
+ var countVarName = hasScopedCount
2194
2282
  ? "".concat(usage.dataSourceIdentifier, "_ds_").concat(usage.index, "_count")
2195
2283
  : "".concat(usage.dataSourceIdentifier, "_count");
2196
2284
  // Check if maxPages calculation already exists
@@ -2228,7 +2316,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2228
2316
  var usagesByFilters = new Map();
2229
2317
  for (var _i = 0, usagesForDataSource_1 = usagesForDataSource; _i < usagesForDataSource_1.length; _i++) {
2230
2318
  var usage = usagesForDataSource_1[_i];
2231
- var filtersKey = JSON.stringify(usage.filters || []);
2319
+ var filtersKey = JSON.stringify([usage.filters || [], usage.itemsPath || []]);
2232
2320
  var existing = usagesByFilters.get(filtersKey) || [];
2233
2321
  existing.push(usage);
2234
2322
  usagesByFilters.set(filtersKey, existing);
@@ -2239,8 +2327,9 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2239
2327
  // Filter out dynamic destinations for getStaticProps (they can't be resolved at build time)
2240
2328
  var staticFiltersForCount = (firstUsage.filters || []).filter(function (f) { return !ASTUtils.isUIDLDynamicReference(f.destination); });
2241
2329
  var hasStaticFilters = staticFiltersForCount.length > 0;
2242
- // Create unique count variable name based on filters
2243
- var countVarName = hasStaticFilters
2330
+ // Create unique count variable name based on filters (and inner-array
2331
+ // scope — must match the naming at the maxPages site above)
2332
+ var countVarName = hasStaticFilters || firstUsage.itemsPath
2244
2333
  ? "".concat(firstUsage.dataSourceIdentifier, "_ds_").concat(firstUsage.index, "_count")
2245
2334
  : "".concat(firstUsage.dataSourceIdentifier, "_count");
2246
2335
  // Check if this count was already processed
@@ -2266,6 +2355,7 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
2266
2355
  })),
2267
2356
  ])));
2268
2357
  }
2358
+ appendItemsPathParam(countParams, firstUsage.itemsPath, 'collectionPath');
2269
2359
  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')), [
2270
2360
  types.arrowFunctionExpression([types.identifier('error')], types.blockStatement([
2271
2361
  types.expressionStatement(types.callExpression(types.memberExpression(types.identifier('console'), types.identifier('error')), [