@teleporthq/teleport-plugin-next-data-source 0.40.15

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 (240) hide show
  1. package/ARRAY_MAPPER_PAGINATION.md +1128 -0
  2. package/LICENSE +21 -0
  3. package/README.md +40 -0
  4. package/SEARCH_IMPLEMENTATION_SUMMARY.md +983 -0
  5. package/__tests__/fetchers.test.ts +545 -0
  6. package/__tests__/integration.test.ts +561 -0
  7. package/__tests__/mocks.ts +241 -0
  8. package/__tests__/pagination.test.ts +31 -0
  9. package/__tests__/plugin.test.ts +577 -0
  10. package/__tests__/utils.test.ts +430 -0
  11. package/__tests__/validation.test.ts +348 -0
  12. package/dist/cjs/array-mapper-pagination.d.ts +32 -0
  13. package/dist/cjs/array-mapper-pagination.d.ts.map +1 -0
  14. package/dist/cjs/array-mapper-pagination.js +77 -0
  15. package/dist/cjs/array-mapper-pagination.js.map +1 -0
  16. package/dist/cjs/count-fetchers.d.ts +12 -0
  17. package/dist/cjs/count-fetchers.d.ts.map +1 -0
  18. package/dist/cjs/count-fetchers.js +46 -0
  19. package/dist/cjs/count-fetchers.js.map +1 -0
  20. package/dist/cjs/data-source-fetchers.d.ts +14 -0
  21. package/dist/cjs/data-source-fetchers.d.ts.map +1 -0
  22. package/dist/cjs/data-source-fetchers.js +185 -0
  23. package/dist/cjs/data-source-fetchers.js.map +1 -0
  24. package/dist/cjs/fetchers/airtable.d.ts +6 -0
  25. package/dist/cjs/fetchers/airtable.d.ts.map +1 -0
  26. package/dist/cjs/fetchers/airtable.js +27 -0
  27. package/dist/cjs/fetchers/airtable.js.map +1 -0
  28. package/dist/cjs/fetchers/clickhouse.d.ts +6 -0
  29. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -0
  30. package/dist/cjs/fetchers/clickhouse.js +29 -0
  31. package/dist/cjs/fetchers/clickhouse.js.map +1 -0
  32. package/dist/cjs/fetchers/csv-file.d.ts +7 -0
  33. package/dist/cjs/fetchers/csv-file.d.ts.map +1 -0
  34. package/dist/cjs/fetchers/csv-file.js +36 -0
  35. package/dist/cjs/fetchers/csv-file.js.map +1 -0
  36. package/dist/cjs/fetchers/firestore.d.ts +6 -0
  37. package/dist/cjs/fetchers/firestore.d.ts.map +1 -0
  38. package/dist/cjs/fetchers/firestore.js +35 -0
  39. package/dist/cjs/fetchers/firestore.js.map +1 -0
  40. package/dist/cjs/fetchers/google-sheets.d.ts +6 -0
  41. package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -0
  42. package/dist/cjs/fetchers/google-sheets.js +30 -0
  43. package/dist/cjs/fetchers/google-sheets.js.map +1 -0
  44. package/dist/cjs/fetchers/index.d.ts +17 -0
  45. package/dist/cjs/fetchers/index.d.ts.map +1 -0
  46. package/dist/cjs/fetchers/index.js +56 -0
  47. package/dist/cjs/fetchers/index.js.map +1 -0
  48. package/dist/cjs/fetchers/javascript.d.ts +7 -0
  49. package/dist/cjs/fetchers/javascript.d.ts.map +1 -0
  50. package/dist/cjs/fetchers/javascript.js +40 -0
  51. package/dist/cjs/fetchers/javascript.js.map +1 -0
  52. package/dist/cjs/fetchers/mariadb.d.ts +3 -0
  53. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -0
  54. package/dist/cjs/fetchers/mariadb.js +23 -0
  55. package/dist/cjs/fetchers/mariadb.js.map +1 -0
  56. package/dist/cjs/fetchers/mongodb.d.ts +7 -0
  57. package/dist/cjs/fetchers/mongodb.d.ts.map +1 -0
  58. package/dist/cjs/fetchers/mongodb.js +52 -0
  59. package/dist/cjs/fetchers/mongodb.js.map +1 -0
  60. package/dist/cjs/fetchers/mysql.d.ts +3 -0
  61. package/dist/cjs/fetchers/mysql.d.ts.map +1 -0
  62. package/dist/cjs/fetchers/mysql.js +30 -0
  63. package/dist/cjs/fetchers/mysql.js.map +1 -0
  64. package/dist/cjs/fetchers/postgresql.d.ts +3 -0
  65. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -0
  66. package/dist/cjs/fetchers/postgresql.js +25 -0
  67. package/dist/cjs/fetchers/postgresql.js.map +1 -0
  68. package/dist/cjs/fetchers/redis.d.ts +6 -0
  69. package/dist/cjs/fetchers/redis.d.ts.map +1 -0
  70. package/dist/cjs/fetchers/redis.js +46 -0
  71. package/dist/cjs/fetchers/redis.js.map +1 -0
  72. package/dist/cjs/fetchers/redshift.d.ts +2 -0
  73. package/dist/cjs/fetchers/redshift.d.ts.map +1 -0
  74. package/dist/cjs/fetchers/redshift.js +24 -0
  75. package/dist/cjs/fetchers/redshift.js.map +1 -0
  76. package/dist/cjs/fetchers/rest-api.d.ts +6 -0
  77. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -0
  78. package/dist/cjs/fetchers/rest-api.js +58 -0
  79. package/dist/cjs/fetchers/rest-api.js.map +1 -0
  80. package/dist/cjs/fetchers/static-collection.d.ts +7 -0
  81. package/dist/cjs/fetchers/static-collection.d.ts.map +1 -0
  82. package/dist/cjs/fetchers/static-collection.js +24 -0
  83. package/dist/cjs/fetchers/static-collection.js.map +1 -0
  84. package/dist/cjs/fetchers/supabase.d.ts +7 -0
  85. package/dist/cjs/fetchers/supabase.d.ts.map +1 -0
  86. package/dist/cjs/fetchers/supabase.js +42 -0
  87. package/dist/cjs/fetchers/supabase.js.map +1 -0
  88. package/dist/cjs/fetchers/turso.d.ts +6 -0
  89. package/dist/cjs/fetchers/turso.d.ts.map +1 -0
  90. package/dist/cjs/fetchers/turso.js +25 -0
  91. package/dist/cjs/fetchers/turso.js.map +1 -0
  92. package/dist/cjs/index.d.ts +9 -0
  93. package/dist/cjs/index.d.ts.map +1 -0
  94. package/dist/cjs/index.js +325 -0
  95. package/dist/cjs/index.js.map +1 -0
  96. package/dist/cjs/pagination-plugin.d.ts +5 -0
  97. package/dist/cjs/pagination-plugin.d.ts.map +1 -0
  98. package/dist/cjs/pagination-plugin.js +1484 -0
  99. package/dist/cjs/pagination-plugin.js.map +1 -0
  100. package/dist/cjs/pagination-with-count.d.ts +6 -0
  101. package/dist/cjs/pagination-with-count.d.ts.map +1 -0
  102. package/dist/cjs/pagination-with-count.js +63 -0
  103. package/dist/cjs/pagination-with-count.js.map +1 -0
  104. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  105. package/dist/cjs/utils.d.ts +31 -0
  106. package/dist/cjs/utils.d.ts.map +1 -0
  107. package/dist/cjs/utils.js +763 -0
  108. package/dist/cjs/utils.js.map +1 -0
  109. package/dist/cjs/validation.d.ts +5 -0
  110. package/dist/cjs/validation.d.ts.map +1 -0
  111. package/dist/cjs/validation.js +29 -0
  112. package/dist/cjs/validation.js.map +1 -0
  113. package/dist/esm/array-mapper-pagination.d.ts +32 -0
  114. package/dist/esm/array-mapper-pagination.d.ts.map +1 -0
  115. package/dist/esm/array-mapper-pagination.js +72 -0
  116. package/dist/esm/array-mapper-pagination.js.map +1 -0
  117. package/dist/esm/count-fetchers.d.ts +12 -0
  118. package/dist/esm/count-fetchers.d.ts.map +1 -0
  119. package/dist/esm/count-fetchers.js +35 -0
  120. package/dist/esm/count-fetchers.js.map +1 -0
  121. package/dist/esm/data-source-fetchers.d.ts +14 -0
  122. package/dist/esm/data-source-fetchers.d.ts.map +1 -0
  123. package/dist/esm/data-source-fetchers.js +179 -0
  124. package/dist/esm/data-source-fetchers.js.map +1 -0
  125. package/dist/esm/fetchers/airtable.d.ts +6 -0
  126. package/dist/esm/fetchers/airtable.d.ts.map +1 -0
  127. package/dist/esm/fetchers/airtable.js +22 -0
  128. package/dist/esm/fetchers/airtable.js.map +1 -0
  129. package/dist/esm/fetchers/clickhouse.d.ts +6 -0
  130. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -0
  131. package/dist/esm/fetchers/clickhouse.js +24 -0
  132. package/dist/esm/fetchers/clickhouse.js.map +1 -0
  133. package/dist/esm/fetchers/csv-file.d.ts +7 -0
  134. package/dist/esm/fetchers/csv-file.d.ts.map +1 -0
  135. package/dist/esm/fetchers/csv-file.js +30 -0
  136. package/dist/esm/fetchers/csv-file.js.map +1 -0
  137. package/dist/esm/fetchers/firestore.d.ts +6 -0
  138. package/dist/esm/fetchers/firestore.d.ts.map +1 -0
  139. package/dist/esm/fetchers/firestore.js +30 -0
  140. package/dist/esm/fetchers/firestore.js.map +1 -0
  141. package/dist/esm/fetchers/google-sheets.d.ts +6 -0
  142. package/dist/esm/fetchers/google-sheets.d.ts.map +1 -0
  143. package/dist/esm/fetchers/google-sheets.js +25 -0
  144. package/dist/esm/fetchers/google-sheets.js.map +1 -0
  145. package/dist/esm/fetchers/index.d.ts +17 -0
  146. package/dist/esm/fetchers/index.d.ts.map +1 -0
  147. package/dist/esm/fetchers/index.js +17 -0
  148. package/dist/esm/fetchers/index.js.map +1 -0
  149. package/dist/esm/fetchers/javascript.d.ts +7 -0
  150. package/dist/esm/fetchers/javascript.d.ts.map +1 -0
  151. package/dist/esm/fetchers/javascript.js +34 -0
  152. package/dist/esm/fetchers/javascript.js.map +1 -0
  153. package/dist/esm/fetchers/mariadb.d.ts +3 -0
  154. package/dist/esm/fetchers/mariadb.d.ts.map +1 -0
  155. package/dist/esm/fetchers/mariadb.js +18 -0
  156. package/dist/esm/fetchers/mariadb.js.map +1 -0
  157. package/dist/esm/fetchers/mongodb.d.ts +7 -0
  158. package/dist/esm/fetchers/mongodb.d.ts.map +1 -0
  159. package/dist/esm/fetchers/mongodb.js +46 -0
  160. package/dist/esm/fetchers/mongodb.js.map +1 -0
  161. package/dist/esm/fetchers/mysql.d.ts +3 -0
  162. package/dist/esm/fetchers/mysql.d.ts.map +1 -0
  163. package/dist/esm/fetchers/mysql.js +25 -0
  164. package/dist/esm/fetchers/mysql.js.map +1 -0
  165. package/dist/esm/fetchers/postgresql.d.ts +3 -0
  166. package/dist/esm/fetchers/postgresql.d.ts.map +1 -0
  167. package/dist/esm/fetchers/postgresql.js +20 -0
  168. package/dist/esm/fetchers/postgresql.js.map +1 -0
  169. package/dist/esm/fetchers/redis.d.ts +6 -0
  170. package/dist/esm/fetchers/redis.d.ts.map +1 -0
  171. package/dist/esm/fetchers/redis.js +41 -0
  172. package/dist/esm/fetchers/redis.js.map +1 -0
  173. package/dist/esm/fetchers/redshift.d.ts +2 -0
  174. package/dist/esm/fetchers/redshift.d.ts.map +1 -0
  175. package/dist/esm/fetchers/redshift.js +20 -0
  176. package/dist/esm/fetchers/redshift.js.map +1 -0
  177. package/dist/esm/fetchers/rest-api.d.ts +6 -0
  178. package/dist/esm/fetchers/rest-api.d.ts.map +1 -0
  179. package/dist/esm/fetchers/rest-api.js +53 -0
  180. package/dist/esm/fetchers/rest-api.js.map +1 -0
  181. package/dist/esm/fetchers/static-collection.d.ts +7 -0
  182. package/dist/esm/fetchers/static-collection.d.ts.map +1 -0
  183. package/dist/esm/fetchers/static-collection.js +18 -0
  184. package/dist/esm/fetchers/static-collection.js.map +1 -0
  185. package/dist/esm/fetchers/supabase.d.ts +7 -0
  186. package/dist/esm/fetchers/supabase.d.ts.map +1 -0
  187. package/dist/esm/fetchers/supabase.js +36 -0
  188. package/dist/esm/fetchers/supabase.js.map +1 -0
  189. package/dist/esm/fetchers/turso.d.ts +6 -0
  190. package/dist/esm/fetchers/turso.d.ts.map +1 -0
  191. package/dist/esm/fetchers/turso.js +20 -0
  192. package/dist/esm/fetchers/turso.js.map +1 -0
  193. package/dist/esm/index.d.ts +9 -0
  194. package/dist/esm/index.d.ts.map +1 -0
  195. package/dist/esm/index.js +306 -0
  196. package/dist/esm/index.js.map +1 -0
  197. package/dist/esm/pagination-plugin.d.ts +5 -0
  198. package/dist/esm/pagination-plugin.d.ts.map +1 -0
  199. package/dist/esm/pagination-plugin.js +1457 -0
  200. package/dist/esm/pagination-plugin.js.map +1 -0
  201. package/dist/esm/pagination-with-count.d.ts +6 -0
  202. package/dist/esm/pagination-with-count.d.ts.map +1 -0
  203. package/dist/esm/pagination-with-count.js +34 -0
  204. package/dist/esm/pagination-with-count.js.map +1 -0
  205. package/dist/esm/tsconfig.tsbuildinfo +1 -0
  206. package/dist/esm/utils.d.ts +31 -0
  207. package/dist/esm/utils.d.ts.map +1 -0
  208. package/dist/esm/utils.js +722 -0
  209. package/dist/esm/utils.js.map +1 -0
  210. package/dist/esm/validation.d.ts +5 -0
  211. package/dist/esm/validation.d.ts.map +1 -0
  212. package/dist/esm/validation.js +25 -0
  213. package/dist/esm/validation.js.map +1 -0
  214. package/package.json +33 -0
  215. package/src/array-mapper-pagination.ts +113 -0
  216. package/src/count-fetchers.ts +99 -0
  217. package/src/data-source-fetchers.ts +313 -0
  218. package/src/fetchers/airtable.ts +153 -0
  219. package/src/fetchers/clickhouse.ts +127 -0
  220. package/src/fetchers/csv-file.ts +163 -0
  221. package/src/fetchers/firestore.ts +138 -0
  222. package/src/fetchers/google-sheets.ts +189 -0
  223. package/src/fetchers/index.ts +32 -0
  224. package/src/fetchers/javascript.ts +150 -0
  225. package/src/fetchers/mariadb.ts +230 -0
  226. package/src/fetchers/mongodb.ts +239 -0
  227. package/src/fetchers/mysql.ts +237 -0
  228. package/src/fetchers/postgresql.ts +247 -0
  229. package/src/fetchers/redis.ts +152 -0
  230. package/src/fetchers/redshift.ts +138 -0
  231. package/src/fetchers/rest-api.ts +148 -0
  232. package/src/fetchers/static-collection.ts +149 -0
  233. package/src/fetchers/supabase.ts +246 -0
  234. package/src/fetchers/turso.ts +131 -0
  235. package/src/index.ts +352 -0
  236. package/src/pagination-plugin.ts +2335 -0
  237. package/src/pagination-with-count.ts +89 -0
  238. package/src/utils.ts +1013 -0
  239. package/src/validation.ts +32 -0
  240. package/tsconfig.json +9 -0
package/src/index.ts ADDED
@@ -0,0 +1,352 @@
1
+ import { ComponentPlugin, ComponentPluginFactory } from '@teleporthq/teleport-types'
2
+ import { UIDLUtils } from '@teleporthq/teleport-shared'
3
+ import { extractDataSourceIntoNextAPIFolder, extractDataSourceIntoGetStaticProps } from './utils'
4
+ import { createNextArrayMapperPaginationPlugin } from './pagination-plugin'
5
+
6
+ interface SearchConfig {
7
+ searchEnabled: boolean
8
+ searchDebounce: number
9
+ }
10
+
11
+ interface PaginationConfig {
12
+ perPageMap: Map<string, number>
13
+ searchConfigMap: Map<string, SearchConfig>
14
+ queryColumnsMap: Map<string, string[]>
15
+ }
16
+
17
+ function extractPaginationConfigEarly(uidlNode: any, resources: any): PaginationConfig {
18
+ const perPageMap = new Map<string, number>()
19
+ const searchConfigMap = new Map<string, SearchConfig>()
20
+ const queryColumnsMap = new Map<string, string[]>()
21
+
22
+ const dataSourceToRenderProp = new Map<string, string>()
23
+
24
+ const traverse = (node: any): void => {
25
+ if (!node || typeof node !== 'object') {
26
+ return
27
+ }
28
+
29
+ if (
30
+ node.type === 'data-source-list' &&
31
+ node.content?.renderPropIdentifier &&
32
+ node.content?.resource?.id
33
+ ) {
34
+ const renderProp = node.content.renderPropIdentifier
35
+ const resourceId = node.content.resource.id
36
+ dataSourceToRenderProp.set(resourceId, renderProp)
37
+
38
+ // Try to get queryColumns from the node's resource params first
39
+ if (node.content?.resource?.params?.queryColumns) {
40
+ const queryColumnsValue = node.content.resource.params.queryColumns
41
+ if (queryColumnsValue.type === 'static' && Array.isArray(queryColumnsValue.content)) {
42
+ queryColumnsMap.set(renderProp, queryColumnsValue.content)
43
+ }
44
+ } else if (resources?.items?.[resourceId]?.params?.queryColumns) {
45
+ const queryColumnsValue = resources.items[resourceId].params.queryColumns
46
+ if (queryColumnsValue.type === 'static' && Array.isArray(queryColumnsValue.content)) {
47
+ queryColumnsMap.set(renderProp, queryColumnsValue.content)
48
+ }
49
+ }
50
+ }
51
+
52
+ if (node.type === 'cms-list-repeater') {
53
+ const perPage = node.content?.perPage
54
+ const paginated = node.content?.paginated
55
+ const renderProp = node.content?.renderPropIdentifier
56
+ const searchEnabled = node.content?.searchEnabled
57
+ const searchDebounce = node.content?.searchDebounce
58
+
59
+ if (paginated && perPage && renderProp) {
60
+ perPageMap.set(renderProp, perPage)
61
+ }
62
+
63
+ if (searchEnabled && renderProp) {
64
+ searchConfigMap.set(renderProp, {
65
+ searchEnabled: true,
66
+ searchDebounce: searchDebounce || 300,
67
+ })
68
+ }
69
+
70
+ if (node.content?.nodes?.list) {
71
+ traverse(node.content.nodes.list)
72
+ }
73
+ if (node.content?.nodes?.empty) {
74
+ traverse(node.content.nodes.empty)
75
+ }
76
+ if (node.content?.nodes?.loading) {
77
+ traverse(node.content.nodes.loading)
78
+ }
79
+ return
80
+ }
81
+
82
+ if (node.content) {
83
+ if (node.content.children && Array.isArray(node.content.children)) {
84
+ for (const child of node.content.children) {
85
+ traverse(child)
86
+ }
87
+ }
88
+ if (node.content.node) {
89
+ traverse(node.content.node)
90
+ }
91
+ if (node.content.nodes) {
92
+ if (node.content.nodes.success) {
93
+ traverse(node.content.nodes.success)
94
+ }
95
+ if (node.content.nodes.error) {
96
+ traverse(node.content.nodes.error)
97
+ }
98
+ if (node.content.nodes.loading) {
99
+ traverse(node.content.nodes.loading)
100
+ }
101
+ }
102
+ }
103
+
104
+ if (Array.isArray(node.children)) {
105
+ for (const child of node.children) {
106
+ traverse(child)
107
+ }
108
+ }
109
+ }
110
+
111
+ traverse(uidlNode)
112
+
113
+ return { perPageMap, searchConfigMap, queryColumnsMap }
114
+ }
115
+
116
+ export const createNextPagesDataSourcePlugin: ComponentPluginFactory<{}> = () => {
117
+ const nextPagesDataSourcePlugin: ComponentPlugin = async (structure) => {
118
+ const { uidl, chunks, options, dependencies } = structure
119
+
120
+ // Early return if no options or dataSources
121
+ if (!options || !options.dataSources) {
122
+ return structure
123
+ }
124
+
125
+ const { dataSources } = options
126
+
127
+ // Check if dataSources is empty
128
+ if (!dataSources || Object.keys(dataSources).length === 0) {
129
+ return structure
130
+ }
131
+
132
+ const componentChunk = chunks.find((chunk) => chunk.name === 'jsx-component')
133
+ if (!componentChunk) {
134
+ return structure
135
+ }
136
+
137
+ // Check if extractedResources exists
138
+ if (!options.extractedResources) {
139
+ return structure
140
+ }
141
+
142
+ // Extract pagination and search config EARLY, before any transformations happen
143
+ const opts = options as any
144
+ if (!opts.paginationConfig) {
145
+ opts.paginationConfig = {
146
+ perPageMap: new Map<string, number>(),
147
+ searchConfigMap: new Map<string, SearchConfig>(),
148
+ queryColumnsMap: new Map<string, string[]>(),
149
+ }
150
+ }
151
+
152
+ // Extract for THIS page and merge with existing maps
153
+ const pageConfig = extractPaginationConfigEarly(uidl.node, (uidl as any).resources)
154
+ pageConfig.perPageMap.forEach((perPage, dataSourceId) => {
155
+ opts.paginationConfig.perPageMap.set(dataSourceId, perPage)
156
+ })
157
+ pageConfig.searchConfigMap.forEach((searchConfig, dataSourceId) => {
158
+ opts.paginationConfig.searchConfigMap.set(dataSourceId, searchConfig)
159
+ })
160
+ pageConfig.queryColumnsMap.forEach((queryColumns, dataSourceId) => {
161
+ opts.paginationConfig.queryColumnsMap.set(dataSourceId, queryColumns)
162
+ })
163
+
164
+ let getStaticPropsChunk = chunks.find((chunk) => chunk.name === 'getStaticProps')
165
+
166
+ // Track which dataSourceId + tableName combinations have been processed
167
+ const processedDataSources = new Set<string>()
168
+
169
+ UIDLUtils.traverseNodes(uidl.node, (node) => {
170
+ // Data source nodes can be either:
171
+ // 1. Direct: node.type === 'data-source-item' or 'data-source-list'
172
+ // 2. Wrapped in element: node.type === 'element' && node.content.type === 'data-source-item' or 'data-source-list'
173
+
174
+ let dataSourceNode = null
175
+
176
+ if (node.type === 'data-source-item' || node.type === 'data-source-list') {
177
+ // Direct data source node
178
+ dataSourceNode = node
179
+ } else if (
180
+ node.type === 'element' &&
181
+ node.content &&
182
+ typeof node.content === 'object' &&
183
+ 'type' in node.content &&
184
+ (node.content.type === 'data-source-item' || node.content.type === 'data-source-list')
185
+ ) {
186
+ // Element node wrapping a data source node
187
+ // tslint:disable-next-line:no-any
188
+ dataSourceNode = node.content as any
189
+ }
190
+
191
+ if (!dataSourceNode) {
192
+ return
193
+ }
194
+
195
+ // Check if node has initialData (means it's already connected to getStaticProps)
196
+ if (
197
+ dataSourceNode.content.initialData !== undefined ||
198
+ dataSourceNode.content.resource === undefined
199
+ ) {
200
+ return
201
+ }
202
+
203
+ // Get dataSourceId and tableName to create unique key
204
+ const resourceDef = dataSourceNode.content.resourceDefinition
205
+ if (!resourceDef) {
206
+ return
207
+ }
208
+
209
+ const dataSourceKey = `${resourceDef.dataSourceId}:${resourceDef.tableName || 'data'}`
210
+
211
+ // Check if resource has dynamic parameters
212
+ // tslint:disable-next-line:no-any
213
+ const hasResourceDynamicParams = dataSourceNode.content.resource?.params
214
+ ? Object.values(dataSourceNode.content.resource.params).some(
215
+ (param: any) => param.type === 'expr' || param.type === 'dynamic'
216
+ )
217
+ : false
218
+
219
+ // If no dynamic params, extract to getStaticProps (server-side)
220
+ // Otherwise, extract to API route (client-side)
221
+ if (!hasResourceDynamicParams) {
222
+ // Skip if we've already processed this dataSource + table combination
223
+ if (processedDataSources.has(dataSourceKey)) {
224
+ return
225
+ }
226
+
227
+ const result = extractDataSourceIntoGetStaticProps(
228
+ dataSourceNode,
229
+ dataSources,
230
+ componentChunk,
231
+ getStaticPropsChunk,
232
+ chunks,
233
+ options.extractedResources,
234
+ dependencies
235
+ )
236
+
237
+ if (result.success && result.chunk) {
238
+ getStaticPropsChunk = result.chunk
239
+ // Mark this dataSource + table as processed
240
+ processedDataSources.add(dataSourceKey)
241
+ }
242
+ } else {
243
+ extractDataSourceIntoNextAPIFolder(
244
+ dataSourceNode,
245
+ dataSources,
246
+ componentChunk,
247
+ options.extractedResources
248
+ )
249
+ }
250
+ })
251
+
252
+ const paginationPlugin = createNextArrayMapperPaginationPlugin()
253
+ return paginationPlugin(structure)
254
+ }
255
+
256
+ return nextPagesDataSourcePlugin
257
+ }
258
+
259
+ export const createNextComponentDataSourcePlugin: ComponentPluginFactory<{}> = () => {
260
+ const nextComponentDataSourcePlugin: ComponentPlugin = async (structure) => {
261
+ const { uidl, chunks, options } = structure
262
+
263
+ // Early return if no options or dataSources
264
+ if (!options || !options.dataSources) {
265
+ return structure
266
+ }
267
+
268
+ const { dataSources } = options
269
+
270
+ // Check if dataSources is empty
271
+ if (!dataSources || Object.keys(dataSources).length === 0) {
272
+ return structure
273
+ }
274
+
275
+ // Extract pagination and search config EARLY, before any transformations happen
276
+ const opts = options as any
277
+ if (!opts.paginationConfig) {
278
+ opts.paginationConfig = {
279
+ perPageMap: new Map<string, number>(),
280
+ searchConfigMap: new Map<string, SearchConfig>(),
281
+ queryColumnsMap: new Map<string, string[]>(),
282
+ }
283
+ }
284
+
285
+ // Extract for THIS component and merge with existing maps
286
+ const componentConfig = extractPaginationConfigEarly(uidl.node, (uidl as any).resources)
287
+ componentConfig.perPageMap.forEach((perPage, dataSourceId) => {
288
+ opts.paginationConfig.perPageMap.set(dataSourceId, perPage)
289
+ })
290
+ componentConfig.searchConfigMap.forEach((searchConfig, dataSourceId) => {
291
+ opts.paginationConfig.searchConfigMap.set(dataSourceId, searchConfig)
292
+ })
293
+ componentConfig.queryColumnsMap.forEach((queryColumns, dataSourceId) => {
294
+ opts.paginationConfig.queryColumnsMap.set(dataSourceId, queryColumns)
295
+ })
296
+
297
+ const componentChunk = chunks.find((chunk) => chunk.name === 'jsx-component')
298
+ if (!componentChunk) {
299
+ return structure
300
+ }
301
+
302
+ // Check if extractedResources exists
303
+ if (!options.extractedResources) {
304
+ return structure
305
+ }
306
+
307
+ UIDLUtils.traverseNodes(uidl.node, (node) => {
308
+ // Data source nodes can be either:
309
+ // 1. Direct: node.type === 'data-source-item' or 'data-source-list'
310
+ // 2. Wrapped in element: node.type === 'element' && node.content.type === 'data-source-item' or 'data-source-list'
311
+
312
+ let dataSourceNode = null
313
+
314
+ if (node.type === 'data-source-item' || node.type === 'data-source-list') {
315
+ // Direct data source node
316
+ dataSourceNode = node
317
+ } else if (
318
+ node.type === 'element' &&
319
+ node.content &&
320
+ typeof node.content === 'object' &&
321
+ 'type' in node.content &&
322
+ (node.content.type === 'data-source-item' || node.content.type === 'data-source-list')
323
+ ) {
324
+ // Element node wrapping a data source node
325
+ // tslint:disable-next-line:no-any
326
+ dataSourceNode = node.content as any
327
+ }
328
+
329
+ if (!dataSourceNode) {
330
+ return
331
+ }
332
+
333
+ extractDataSourceIntoNextAPIFolder(
334
+ dataSourceNode,
335
+ dataSources,
336
+ componentChunk,
337
+ options.extractedResources
338
+ )
339
+ })
340
+
341
+ const paginationPlugin = createNextArrayMapperPaginationPlugin()
342
+ return paginationPlugin(structure)
343
+ }
344
+
345
+ return nextComponentDataSourcePlugin
346
+ }
347
+
348
+ export * from './data-source-fetchers'
349
+ export * from './utils'
350
+ export * from './array-mapper-pagination'
351
+ export * from './pagination-plugin'
352
+ export * from './count-fetchers'