@teleporthq/teleport-plugin-next-data-source 0.42.35 → 0.43.0

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 (239) hide show
  1. package/__tests__/ecommerce-product-out-of-stock.test.ts +112 -0
  2. package/__tests__/fetchers.test.ts +0 -42
  3. package/__tests__/filter-utils.test.ts +149 -0
  4. package/__tests__/mocks.ts +0 -12
  5. package/__tests__/utils.test.ts +0 -2
  6. package/dist/cjs/array-mapper-registry.d.ts +2 -0
  7. package/dist/cjs/array-mapper-registry.d.ts.map +1 -1
  8. package/dist/cjs/array-mapper-registry.js +9 -1
  9. package/dist/cjs/array-mapper-registry.js.map +1 -1
  10. package/dist/cjs/count-fetchers.d.ts +2 -2
  11. package/dist/cjs/count-fetchers.d.ts.map +1 -1
  12. package/dist/cjs/count-fetchers.js +5 -5
  13. package/dist/cjs/count-fetchers.js.map +1 -1
  14. package/dist/cjs/data-source-fetchers.d.ts +2 -1
  15. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  16. package/dist/cjs/data-source-fetchers.js +11 -9
  17. package/dist/cjs/data-source-fetchers.js.map +1 -1
  18. package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
  19. package/dist/cjs/fetchers/airtable.js +1 -1
  20. package/dist/cjs/fetchers/airtable.js.map +1 -1
  21. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  22. package/dist/cjs/fetchers/clickhouse.js +1 -1
  23. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  24. package/dist/cjs/fetchers/csv-file.js +1 -1
  25. package/dist/cjs/fetchers/csv-file.js.map +1 -1
  26. package/dist/cjs/fetchers/firestore.js +1 -1
  27. package/dist/cjs/fetchers/firestore.js.map +1 -1
  28. package/dist/cjs/fetchers/google-sheets.js +1 -1
  29. package/dist/cjs/fetchers/google-sheets.js.map +1 -1
  30. package/dist/cjs/fetchers/index.d.ts +2 -1
  31. package/dist/cjs/fetchers/index.d.ts.map +1 -1
  32. package/dist/cjs/fetchers/index.js +8 -5
  33. package/dist/cjs/fetchers/index.js.map +1 -1
  34. package/dist/cjs/fetchers/javascript.js +1 -1
  35. package/dist/cjs/fetchers/javascript.js.map +1 -1
  36. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
  37. package/dist/cjs/fetchers/mariadb.js +3 -3
  38. package/dist/cjs/fetchers/mariadb.js.map +1 -1
  39. package/dist/cjs/fetchers/mongodb.js +1 -1
  40. package/dist/cjs/fetchers/mongodb.js.map +1 -1
  41. package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
  42. package/dist/cjs/fetchers/mysql.js +2 -2
  43. package/dist/cjs/fetchers/mysql.js.map +1 -1
  44. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  45. package/dist/cjs/fetchers/postgresql.js +2 -2
  46. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  47. package/dist/cjs/fetchers/raw-query.d.ts +18 -0
  48. package/dist/cjs/fetchers/raw-query.d.ts.map +1 -0
  49. package/dist/cjs/fetchers/raw-query.js +70 -0
  50. package/dist/cjs/fetchers/raw-query.js.map +1 -0
  51. package/dist/cjs/fetchers/redis.js +1 -1
  52. package/dist/cjs/fetchers/redis.js.map +1 -1
  53. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  54. package/dist/cjs/fetchers/redshift.js +2 -2
  55. package/dist/cjs/fetchers/redshift.js.map +1 -1
  56. package/dist/cjs/fetchers/rest-api.js +1 -1
  57. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  58. package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
  59. package/dist/cjs/fetchers/supabase.js +62 -2
  60. package/dist/cjs/fetchers/supabase.js.map +1 -1
  61. package/dist/cjs/fetchers/teleport.d.ts +7 -0
  62. package/dist/cjs/fetchers/teleport.d.ts.map +1 -0
  63. package/dist/cjs/fetchers/teleport.js +63 -0
  64. package/dist/cjs/fetchers/teleport.js.map +1 -0
  65. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  66. package/dist/cjs/fetchers/turso.js +1 -1
  67. package/dist/cjs/fetchers/turso.js.map +1 -1
  68. package/dist/cjs/filter-utils.d.ts +13 -0
  69. package/dist/cjs/filter-utils.d.ts.map +1 -0
  70. package/dist/cjs/filter-utils.js +95 -0
  71. package/dist/cjs/filter-utils.js.map +1 -0
  72. package/dist/cjs/index.d.ts.map +1 -1
  73. package/dist/cjs/index.js +112 -9
  74. package/dist/cjs/index.js.map +1 -1
  75. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  76. package/dist/cjs/pagination-plugin.js +389 -128
  77. package/dist/cjs/pagination-plugin.js.map +1 -1
  78. package/dist/cjs/sort-utils.d.ts +10 -0
  79. package/dist/cjs/sort-utils.d.ts.map +1 -0
  80. package/dist/cjs/sort-utils.js +141 -0
  81. package/dist/cjs/sort-utils.js.map +1 -0
  82. package/dist/cjs/transformations/blog-post.d.ts +7 -0
  83. package/dist/cjs/transformations/blog-post.d.ts.map +1 -0
  84. package/dist/cjs/transformations/blog-post.js +13 -0
  85. package/dist/cjs/transformations/blog-post.js.map +1 -0
  86. package/dist/cjs/transformations/ecommerce-product.d.ts +7 -0
  87. package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -0
  88. package/dist/cjs/transformations/ecommerce-product.js +13 -0
  89. package/dist/cjs/transformations/ecommerce-product.js.map +1 -0
  90. package/dist/cjs/transformations/index.d.ts +26 -0
  91. package/dist/cjs/transformations/index.d.ts.map +1 -0
  92. package/dist/cjs/transformations/index.js +81 -0
  93. package/dist/cjs/transformations/index.js.map +1 -0
  94. package/dist/cjs/transformations/shared-utils.d.ts +7 -0
  95. package/dist/cjs/transformations/shared-utils.d.ts.map +1 -0
  96. package/dist/cjs/transformations/shared-utils.js +13 -0
  97. package/dist/cjs/transformations/shared-utils.js.map +1 -0
  98. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  99. package/dist/cjs/utils.d.ts +30 -1
  100. package/dist/cjs/utils.d.ts.map +1 -1
  101. package/dist/cjs/utils.js +173 -10
  102. package/dist/cjs/utils.js.map +1 -1
  103. package/dist/esm/array-mapper-registry.d.ts +2 -0
  104. package/dist/esm/array-mapper-registry.d.ts.map +1 -1
  105. package/dist/esm/array-mapper-registry.js +9 -1
  106. package/dist/esm/array-mapper-registry.js.map +1 -1
  107. package/dist/esm/count-fetchers.d.ts +2 -2
  108. package/dist/esm/count-fetchers.d.ts.map +1 -1
  109. package/dist/esm/count-fetchers.js +4 -4
  110. package/dist/esm/count-fetchers.js.map +1 -1
  111. package/dist/esm/data-source-fetchers.d.ts +2 -1
  112. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  113. package/dist/esm/data-source-fetchers.js +10 -9
  114. package/dist/esm/data-source-fetchers.js.map +1 -1
  115. package/dist/esm/fetchers/airtable.d.ts.map +1 -1
  116. package/dist/esm/fetchers/airtable.js +1 -1
  117. package/dist/esm/fetchers/airtable.js.map +1 -1
  118. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  119. package/dist/esm/fetchers/clickhouse.js +1 -1
  120. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  121. package/dist/esm/fetchers/csv-file.js +1 -1
  122. package/dist/esm/fetchers/csv-file.js.map +1 -1
  123. package/dist/esm/fetchers/firestore.js +1 -1
  124. package/dist/esm/fetchers/firestore.js.map +1 -1
  125. package/dist/esm/fetchers/google-sheets.js +1 -1
  126. package/dist/esm/fetchers/google-sheets.js.map +1 -1
  127. package/dist/esm/fetchers/index.d.ts +2 -1
  128. package/dist/esm/fetchers/index.d.ts.map +1 -1
  129. package/dist/esm/fetchers/index.js +2 -1
  130. package/dist/esm/fetchers/index.js.map +1 -1
  131. package/dist/esm/fetchers/javascript.js +1 -1
  132. package/dist/esm/fetchers/javascript.js.map +1 -1
  133. package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
  134. package/dist/esm/fetchers/mariadb.js +4 -4
  135. package/dist/esm/fetchers/mariadb.js.map +1 -1
  136. package/dist/esm/fetchers/mongodb.js +1 -1
  137. package/dist/esm/fetchers/mongodb.js.map +1 -1
  138. package/dist/esm/fetchers/mysql.d.ts.map +1 -1
  139. package/dist/esm/fetchers/mysql.js +3 -3
  140. package/dist/esm/fetchers/mysql.js.map +1 -1
  141. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  142. package/dist/esm/fetchers/postgresql.js +3 -3
  143. package/dist/esm/fetchers/postgresql.js.map +1 -1
  144. package/dist/esm/fetchers/raw-query.d.ts +18 -0
  145. package/dist/esm/fetchers/raw-query.d.ts.map +1 -0
  146. package/dist/esm/fetchers/raw-query.js +65 -0
  147. package/dist/esm/fetchers/raw-query.js.map +1 -0
  148. package/dist/esm/fetchers/redis.js +1 -1
  149. package/dist/esm/fetchers/redis.js.map +1 -1
  150. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  151. package/dist/esm/fetchers/redshift.js +3 -3
  152. package/dist/esm/fetchers/redshift.js.map +1 -1
  153. package/dist/esm/fetchers/rest-api.js +1 -1
  154. package/dist/esm/fetchers/rest-api.js.map +1 -1
  155. package/dist/esm/fetchers/supabase.d.ts.map +1 -1
  156. package/dist/esm/fetchers/supabase.js +63 -3
  157. package/dist/esm/fetchers/supabase.js.map +1 -1
  158. package/dist/esm/fetchers/teleport.d.ts +7 -0
  159. package/dist/esm/fetchers/teleport.d.ts.map +1 -0
  160. package/dist/esm/fetchers/teleport.js +57 -0
  161. package/dist/esm/fetchers/teleport.js.map +1 -0
  162. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  163. package/dist/esm/fetchers/turso.js +2 -2
  164. package/dist/esm/fetchers/turso.js.map +1 -1
  165. package/dist/esm/filter-utils.d.ts +13 -0
  166. package/dist/esm/filter-utils.d.ts.map +1 -0
  167. package/dist/esm/filter-utils.js +66 -0
  168. package/dist/esm/filter-utils.js.map +1 -0
  169. package/dist/esm/index.d.ts.map +1 -1
  170. package/dist/esm/index.js +113 -10
  171. package/dist/esm/index.js.map +1 -1
  172. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  173. package/dist/esm/pagination-plugin.js +389 -128
  174. package/dist/esm/pagination-plugin.js.map +1 -1
  175. package/dist/esm/sort-utils.d.ts +10 -0
  176. package/dist/esm/sort-utils.d.ts.map +1 -0
  177. package/dist/esm/sort-utils.js +113 -0
  178. package/dist/esm/sort-utils.js.map +1 -0
  179. package/dist/esm/transformations/blog-post.d.ts +7 -0
  180. package/dist/esm/transformations/blog-post.d.ts.map +1 -0
  181. package/dist/esm/transformations/blog-post.js +9 -0
  182. package/dist/esm/transformations/blog-post.js.map +1 -0
  183. package/dist/esm/transformations/ecommerce-product.d.ts +7 -0
  184. package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -0
  185. package/dist/esm/transformations/ecommerce-product.js +9 -0
  186. package/dist/esm/transformations/ecommerce-product.js.map +1 -0
  187. package/dist/esm/transformations/index.d.ts +26 -0
  188. package/dist/esm/transformations/index.d.ts.map +1 -0
  189. package/dist/esm/transformations/index.js +74 -0
  190. package/dist/esm/transformations/index.js.map +1 -0
  191. package/dist/esm/transformations/shared-utils.d.ts +7 -0
  192. package/dist/esm/transformations/shared-utils.d.ts.map +1 -0
  193. package/dist/esm/transformations/shared-utils.js +9 -0
  194. package/dist/esm/transformations/shared-utils.js.map +1 -0
  195. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  196. package/dist/esm/utils.d.ts +30 -1
  197. package/dist/esm/utils.d.ts.map +1 -1
  198. package/dist/esm/utils.js +170 -9
  199. package/dist/esm/utils.js.map +1 -1
  200. package/package.json +6 -5
  201. package/src/array-mapper-registry.ts +13 -0
  202. package/src/count-fetchers.ts +5 -5
  203. package/src/data-source-fetchers.ts +15 -11
  204. package/src/fetchers/airtable.ts +54 -8
  205. package/src/fetchers/clickhouse.ts +25 -19
  206. package/src/fetchers/csv-file.ts +2 -2
  207. package/src/fetchers/firestore.ts +2 -2
  208. package/src/fetchers/google-sheets.ts +2 -2
  209. package/src/fetchers/index.ts +6 -5
  210. package/src/fetchers/javascript.ts +2 -2
  211. package/src/fetchers/mariadb.ts +27 -12
  212. package/src/fetchers/mongodb.ts +2 -2
  213. package/src/fetchers/mysql.ts +27 -12
  214. package/src/fetchers/postgresql.ts +31 -18
  215. package/src/fetchers/raw-query.ts +178 -0
  216. package/src/fetchers/redis.ts +2 -2
  217. package/src/fetchers/redshift.ts +14 -10
  218. package/src/fetchers/rest-api.ts +2 -2
  219. package/src/fetchers/supabase.ts +97 -14
  220. package/src/fetchers/teleport.ts +485 -0
  221. package/src/fetchers/turso.ts +15 -7
  222. package/src/filter-utils.ts +111 -0
  223. package/src/index.ts +146 -6
  224. package/src/pagination-plugin.ts +547 -308
  225. package/src/sort-utils.ts +150 -0
  226. package/src/transformations/blog-post.ts +128 -0
  227. package/src/transformations/ecommerce-product.ts +173 -0
  228. package/src/transformations/index.ts +97 -0
  229. package/src/transformations/shared-utils.ts +271 -0
  230. package/src/utils.ts +227 -11
  231. package/dist/cjs/fetchers/static-collection.d.ts +0 -7
  232. package/dist/cjs/fetchers/static-collection.d.ts.map +0 -1
  233. package/dist/cjs/fetchers/static-collection.js +0 -25
  234. package/dist/cjs/fetchers/static-collection.js.map +0 -1
  235. package/dist/esm/fetchers/static-collection.d.ts +0 -7
  236. package/dist/esm/fetchers/static-collection.d.ts.map +0 -1
  237. package/dist/esm/fetchers/static-collection.js +0 -19
  238. package/dist/esm/fetchers/static-collection.js.map +0 -1
  239. package/src/fetchers/static-collection.ts +0 -231
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Generates JavaScript code for shared data transformation utilities.
3
+ * These are included in the generated data source fetcher files
4
+ * when the table requires blog post or e-commerce product transformations.
5
+ */
6
+ export const generateSharedTransformationCode = (): string => {
7
+ return `
8
+ // ============================================================
9
+ // Shared Data Transformation Utilities
10
+ // ============================================================
11
+
12
+ var CURRENCY_SYMBOLS = {
13
+ USD: { symbol: '$', position: 'before' },
14
+ EUR: { symbol: '€', position: 'before' },
15
+ GBP: { symbol: '£', position: 'before' },
16
+ JPY: { symbol: '¥', position: 'before' },
17
+ CAD: { symbol: 'C$', position: 'before' },
18
+ AUD: { symbol: 'A$', position: 'before' },
19
+ CHF: { symbol: 'CHF', position: 'before' },
20
+ CNY: { symbol: '¥', position: 'before' },
21
+ INR: { symbol: '₹', position: 'before' },
22
+ BRL: { symbol: 'R$', position: 'before' },
23
+ MXN: { symbol: 'MX$', position: 'before' },
24
+ KRW: { symbol: '₩', position: 'before' },
25
+ SGD: { symbol: 'S$', position: 'before' },
26
+ HKD: { symbol: 'HK$', position: 'before' },
27
+ NOK: { symbol: 'kr', position: 'after' },
28
+ SEK: { symbol: 'kr', position: 'after' },
29
+ DKK: { symbol: 'kr', position: 'after' },
30
+ PLN: { symbol: 'zł', position: 'after' },
31
+ CZK: { symbol: 'Kč', position: 'after' },
32
+ HUF: { symbol: 'Ft', position: 'after' },
33
+ RON: { symbol: 'lei', position: 'after' },
34
+ TRY: { symbol: '₺', position: 'before' },
35
+ THB: { symbol: '฿', position: 'before' },
36
+ IDR: { symbol: 'Rp', position: 'before' },
37
+ PHP: { symbol: '₱', position: 'before' },
38
+ ZAR: { symbol: 'R', position: 'before' },
39
+ RUB: { symbol: '₽', position: 'after' },
40
+ NZD: { symbol: 'NZ$', position: 'before' },
41
+ TWD: { symbol: 'NT$', position: 'before' },
42
+ ILS: { symbol: '₪', position: 'before' },
43
+ AED: { symbol: 'د.إ', position: 'before' },
44
+ SAR: { symbol: '﷼', position: 'before' },
45
+ MYR: { symbol: 'RM', position: 'before' },
46
+ VND: { symbol: '₫', position: 'after' },
47
+ CLP: { symbol: '$', position: 'before' },
48
+ COP: { symbol: '$', position: 'before' },
49
+ ARS: { symbol: '$', position: 'before' },
50
+ PEN: { symbol: 'S/', position: 'before' },
51
+ UAH: { symbol: '₴', position: 'after' },
52
+ BGN: { symbol: 'лв', position: 'after' },
53
+ HRK: { symbol: 'kn', position: 'after' },
54
+ ISK: { symbol: 'kr', position: 'after' },
55
+ NGN: { symbol: '₦', position: 'before' },
56
+ KES: { symbol: 'KSh', position: 'before' },
57
+ EGP: { symbol: 'E£', position: 'before' },
58
+ PKR: { symbol: '₨', position: 'before' },
59
+ BDT: { symbol: '৳', position: 'before' },
60
+ LKR: { symbol: '₨', position: 'before' },
61
+ GHS: { symbol: 'GH₵', position: 'before' },
62
+ }
63
+
64
+ function getCurrencyInfo(currencyCode) {
65
+ if (!currencyCode) return { symbol: '$', position: 'before' }
66
+ var upper = currencyCode.toUpperCase()
67
+ var entry = CURRENCY_SYMBOLS[upper]
68
+ return entry || { symbol: upper, position: 'before' }
69
+ }
70
+
71
+ function getCurrencySymbol(currencyCode) {
72
+ return getCurrencyInfo(currencyCode).symbol
73
+ }
74
+
75
+ function normalizeTimestamp(value) {
76
+ if (value == null) return Date.now()
77
+ if (typeof value === 'number') {
78
+ if (isNaN(value)) return Date.now()
79
+ return value < 100000000000 ? value * 1000 : value
80
+ }
81
+ if (typeof value === 'string') {
82
+ var parsed = Date.parse(value)
83
+ return isNaN(parsed) ? Date.now() : parsed
84
+ }
85
+ return Date.now()
86
+ }
87
+
88
+ function safeNumber(value, defaultValue) {
89
+ if (value == null) return defaultValue
90
+ var n = Number(value)
91
+ return isNaN(n) ? defaultValue : n
92
+ }
93
+
94
+ function parseJsonArray(value) {
95
+ if (!value) return []
96
+ if (Array.isArray(value)) return value.filter(function(item) { return typeof item === 'string' })
97
+ if (typeof value === 'string') {
98
+ try {
99
+ var parsed = JSON.parse(value)
100
+ if (Array.isArray(parsed)) return parsed.filter(function(item) { return typeof item === 'string' })
101
+ return []
102
+ } catch (e) {
103
+ return value.split(',').map(function(s) { return s.trim() }).filter(Boolean)
104
+ }
105
+ }
106
+ return []
107
+ }
108
+
109
+ function parseJsonObject(value) {
110
+ if (value == null) return {}
111
+ if (typeof value === 'object' && !Array.isArray(value)) return value
112
+ if (typeof value === 'string') {
113
+ try {
114
+ var parsed = JSON.parse(value)
115
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) return parsed
116
+ return {}
117
+ } catch (e) {
118
+ return {}
119
+ }
120
+ }
121
+ return {}
122
+ }
123
+
124
+ var HTML_ENTITY_MAP = {
125
+ '&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"',
126
+ '&#39;': "'", '&#x27;': "'", '&apos;': "'", '&nbsp;': ' ',
127
+ '&#160;': ' ', '&copy;': '©', '&reg;': '®', '&trade;': '™',
128
+ '&hellip;': '…', '&mdash;': '—', '&ndash;': '–',
129
+ }
130
+
131
+ function decodeHtmlEntities(str) {
132
+ if (!str) return str
133
+ // Decode named and numeric entities
134
+ return str
135
+ .replace(/&(?:#x([0-9a-fA-F]+)|#([0-9]+)|([a-zA-Z]+));/g, function(match, hex, dec, named) {
136
+ if (hex) return String.fromCharCode(parseInt(hex, 16))
137
+ if (dec) return String.fromCharCode(parseInt(dec, 10))
138
+ var namedRef = '&' + named + ';'
139
+ return HTML_ENTITY_MAP[namedRef] || match
140
+ })
141
+ }
142
+
143
+ function stripHtmlTags(html) {
144
+ if (!html || typeof html !== 'string') return ''
145
+ // Remove script and style blocks entirely (including content)
146
+ var cleaned = html
147
+ .replace(/<script[\\s\\S]*?<\\/script>/gi, ' ')
148
+ .replace(/<style[\\s\\S]*?<\\/style>/gi, ' ')
149
+ // Strip remaining tags
150
+ cleaned = cleaned.replace(/<[^>]*>/g, ' ')
151
+ // Decode HTML entities
152
+ cleaned = decodeHtmlEntities(cleaned)
153
+ // Collapse whitespace
154
+ return cleaned.replace(/\\s+/g, ' ').trim()
155
+ }
156
+
157
+ function coerceBoolean(value, defaultValue) {
158
+ if (value === true || value === 'true' || value === 1 || value === '1') return true
159
+ if (value === false || value === 'false' || value === 0 || value === '0') return false
160
+ return defaultValue
161
+ }
162
+
163
+ function pickFirst() {
164
+ for (var i = 0; i < arguments.length; i++) {
165
+ var val = arguments[i]
166
+ if (val !== undefined && val !== null) return val
167
+ }
168
+ return null
169
+ }
170
+
171
+ function resolveI18nField(record, snakeCol, camelCol, currentLang, mainLang) {
172
+ if (currentLang && mainLang && currentLang !== mainLang) {
173
+ // Try language-prefixed snake_case column first, then camelCase
174
+ var langSnakeKey = currentLang + '_' + snakeCol
175
+ if (record[langSnakeKey] !== undefined && record[langSnakeKey] !== null && record[langSnakeKey] !== '') {
176
+ return record[langSnakeKey]
177
+ }
178
+ if (snakeCol !== camelCol) {
179
+ var langCamelKey = currentLang + '_' + camelCol
180
+ if (record[langCamelKey] !== undefined && record[langCamelKey] !== null && record[langCamelKey] !== '') {
181
+ return record[langCamelKey]
182
+ }
183
+ }
184
+ }
185
+ if (record[snakeCol] !== undefined && record[snakeCol] !== null) return record[snakeCol]
186
+ if (snakeCol !== camelCol && record[camelCol] !== undefined && record[camelCol] !== null) return record[camelCol]
187
+ return null
188
+ }
189
+
190
+ // Asset URL Resolution with TTL-based caching
191
+ var __assetUrlCache = {}
192
+ var __assetMapCache = null
193
+ var __assetMapTimestamp = 0
194
+ var ASSET_CACHE_TTL_MS = 5 * 60 * 1000 // 5 minutes
195
+
196
+ function isUrl(value) {
197
+ if (!value || typeof value !== 'string') return false
198
+ return value.startsWith('http://') || value.startsWith('https://') || value.startsWith('data:')
199
+ }
200
+
201
+ function resolveAssetUrl(value, assetMap) {
202
+ if (!value || typeof value !== 'string') return null
203
+ if (isUrl(value)) return value
204
+ // Also treat absolute paths (starting with /) as URLs
205
+ if (value.charAt(0) === '/') return value
206
+ if (__assetUrlCache[value]) return __assetUrlCache[value]
207
+ if (assetMap && assetMap[value]) {
208
+ var asset = assetMap[value]
209
+ var resolved = asset.remoteSrc || asset.imageSrc || asset.src || asset.url || value
210
+ __assetUrlCache[value] = resolved
211
+ return resolved
212
+ }
213
+ // Not found in asset map - return as-is (might already be a usable reference)
214
+ return value
215
+ }
216
+
217
+ function resolveAssetUrls(values, assetMap) {
218
+ if (!Array.isArray(values)) return []
219
+ return values
220
+ .map(function(v) { return resolveAssetUrl(v, assetMap) })
221
+ .filter(function(v) { return v != null && typeof v === 'string' })
222
+ }
223
+
224
+ function deduplicateStrings(arr) {
225
+ var seen = {}
226
+ return arr.filter(function(v) {
227
+ if (!v || typeof v !== 'string' || seen[v]) return false
228
+ seen[v] = true
229
+ return true
230
+ })
231
+ }
232
+
233
+ // Fetches the asset map from the database if available, with TTL-based caching
234
+ async function getAssetMap(getClientFn) {
235
+ var now = Date.now()
236
+ if (__assetMapCache && (now - __assetMapTimestamp) < ASSET_CACHE_TTL_MS) {
237
+ return __assetMapCache
238
+ }
239
+ // Reset per-URL cache when asset map is refreshed
240
+ __assetUrlCache = {}
241
+ var map = {}
242
+ var client
243
+ try {
244
+ client = getClientFn()
245
+ await client.connect()
246
+ var result = await client.query('SELECT id, src, remote_src, image_src, url FROM teleport_assets')
247
+ if (result && result.rows) {
248
+ result.rows.forEach(function(row) {
249
+ map[row.id] = {
250
+ src: row.src || null,
251
+ remoteSrc: row.remote_src || null,
252
+ imageSrc: row.image_src || null,
253
+ url: row.url || null,
254
+ }
255
+ })
256
+ }
257
+ __assetMapCache = map
258
+ __assetMapTimestamp = now
259
+ } catch (e) {
260
+ // teleport_assets table may not exist - cache empty map with short TTL
261
+ __assetMapCache = map
262
+ __assetMapTimestamp = now
263
+ } finally {
264
+ if (client) {
265
+ try { await client.end() } catch (e) { /* ignore */ }
266
+ }
267
+ }
268
+ return map
269
+ }
270
+ `
271
+ }
package/src/utils.ts CHANGED
@@ -15,6 +15,7 @@ import { generateDataSourceFetcherWithCore } from './data-source-fetchers'
15
15
 
16
16
  const VALID_DATA_SOURCE_TYPES: DataSourceType[] = [
17
17
  'rest-api',
18
+ 'teleport',
18
19
  'postgresql',
19
20
  'mysql',
20
21
  'mariadb',
@@ -31,7 +32,6 @@ const VALID_DATA_SOURCE_TYPES: DataSourceType[] = [
31
32
  'javascript',
32
33
  'google-sheets',
33
34
  'csv-file',
34
- 'static-collection',
35
35
  ]
36
36
 
37
37
  export const sanitizeFileName = (input: string): string => {
@@ -460,7 +460,7 @@ export default dataSourceModule.handler
460
460
  }
461
461
 
462
462
  export const isEmbeddedDataSource = (dataSourceType: string): boolean => {
463
- return ['javascript', 'csv-file', 'static-collection'].includes(dataSourceType)
463
+ return ['javascript', 'csv-file'].includes(dataSourceType)
464
464
  }
465
465
 
466
466
  export const replaceSecretReference = (
@@ -510,6 +510,41 @@ export const replaceSecretReference = (
510
510
  }
511
511
  }
512
512
 
513
+ /**
514
+ * Emit runtime helpers that every SQL-based fetcher needs to safely
515
+ * apply the `{ query, queryColumns }` search contract:
516
+ *
517
+ * - `SEARCH_LIKE_ESCAPE_CHAR` — the char we register via `ESCAPE '|'`
518
+ * in LIKE / ILIKE expressions. `|` is not special in any SQL
519
+ * dialect's string-literal grammar, so the emitted SQL parses
520
+ * unambiguously across Postgres, MySQL (regardless of
521
+ * `NO_BACKSLASH_ESCAPES`), and SQLite.
522
+ *
523
+ * - `escapeLikePattern(term)` — prefixes `|` to `|`, `%`, `_` so a
524
+ * user typing `50%` matches a literal `%` rather than any-chars.
525
+ *
526
+ * - `sanitizeSearchIdentifier(name)` — validates column identifiers
527
+ * against `[A-Za-z_][A-Za-z0-9_]*` and throws on anything else. The
528
+ * caller is responsible for wrapping in the dialect's quote chars.
529
+ *
530
+ * Kept as a single snippet so every fetcher imports the exact same
531
+ * contract and the canvas preview (data-fetcher-worker /
532
+ * database-provider-worker) and the generated Next.js app emit
533
+ * byte-identical search SQL.
534
+ */
535
+ export const generateSearchEscapeHelpersCode = (): string => {
536
+ return `const SEARCH_LIKE_ESCAPE_CHAR = '|'
537
+ const escapeLikePattern = (term) => {
538
+ return String(term == null ? '' : term).replace(/[|%_]/g, (m) => SEARCH_LIKE_ESCAPE_CHAR + m)
539
+ }
540
+ const sanitizeSearchIdentifier = (name) => {
541
+ if (typeof name !== 'string' || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
542
+ throw new Error('Invalid search column identifier: ' + String(name))
543
+ }
544
+ return name
545
+ }`
546
+ }
547
+
513
548
  export const generateSafeJSONParseCode = (): string => {
514
549
  return `const safeJSONParse = (value) => {
515
550
  if (!value) return value
@@ -706,6 +741,147 @@ export const sanitizeIdentifier = (identifier: unknown): string => {
706
741
  return identifier.replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 64)
707
742
  }
708
743
 
744
+ /**
745
+ * Checks if a dynamic param is resolvable from the route's dynamic attribute
746
+ * (i.e. available via context.params in getStaticProps/getServerSideProps).
747
+ */
748
+ const isDynamicParamRouteResolvable = (
749
+ param: { type: string; content?: { referenceType?: string; id?: string } },
750
+ dynamicRouteAttr: string
751
+ ): boolean => {
752
+ if (param.type !== 'dynamic') {
753
+ return false
754
+ }
755
+ return param.content?.referenceType === 'prop' && param.content?.id === dynamicRouteAttr
756
+ }
757
+
758
+ /**
759
+ * Checks if a filter destination (within a static filters array) is resolvable
760
+ * from the route's dynamic attribute.
761
+ */
762
+ const isFilterDestinationRouteResolvable = (
763
+ destination: unknown,
764
+ dynamicRouteAttr: string
765
+ ): boolean => {
766
+ if (!ASTUtils.isUIDLDynamicReference(destination)) {
767
+ return false
768
+ }
769
+ const content = (destination as { content: { referenceType: string; id: string } }).content
770
+ return content.referenceType === 'prop' && content.id === dynamicRouteAttr
771
+ }
772
+
773
+ /**
774
+ * Determines if any resource params have dynamic values that cannot be resolved
775
+ * server-side. Params whose dynamic references match the page's dynamicRouteAttribute
776
+ * can be resolved from context.params and are NOT considered unresolvable.
777
+ */
778
+ // tslint:disable-next-line:no-any
779
+ export const hasUnresolvableDynamicParams = (
780
+ params: Record<string, any>,
781
+ dynamicRouteAttr?: string
782
+ ): boolean => {
783
+ return Object.values(params).some((param: any) => {
784
+ if (param.type === 'expr') {
785
+ return true
786
+ }
787
+
788
+ if (param.type === 'dynamic') {
789
+ if (dynamicRouteAttr && isDynamicParamRouteResolvable(param, dynamicRouteAttr)) {
790
+ return false
791
+ }
792
+ return true
793
+ }
794
+
795
+ if (param.type === 'static' && Array.isArray(param.content)) {
796
+ const hasDynamicDestinations = param.content.some(
797
+ (item: any) =>
798
+ item && typeof item === 'object' && ASTUtils.isUIDLDynamicReference(item?.destination)
799
+ )
800
+
801
+ if (hasDynamicDestinations && dynamicRouteAttr) {
802
+ const allResolvable = param.content.every((item: any) => {
803
+ if (!item || typeof item !== 'object') {
804
+ return true
805
+ }
806
+ if (!ASTUtils.isUIDLDynamicReference(item.destination)) {
807
+ return true
808
+ }
809
+ return isFilterDestinationRouteResolvable(item.destination, dynamicRouteAttr)
810
+ })
811
+ return !allResolvable
812
+ }
813
+
814
+ return hasDynamicDestinations
815
+ }
816
+
817
+ return false
818
+ })
819
+ }
820
+
821
+ const isValidJSIdentifier = (name: string): boolean => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)
822
+
823
+ /**
824
+ * Generates context.params.attr or context.params['attr'] depending on
825
+ * whether the attribute name is a valid JS identifier.
826
+ */
827
+ const createContextParamsAccess = (attr: string): types.MemberExpression => {
828
+ const contextParams = types.memberExpression(
829
+ types.identifier('context'),
830
+ types.identifier('params')
831
+ )
832
+ return isValidJSIdentifier(attr)
833
+ ? types.memberExpression(contextParams, types.identifier(attr))
834
+ : types.memberExpression(contextParams, types.stringLiteral(attr), true)
835
+ }
836
+
837
+ /**
838
+ * Builds an AST ObjectExpression for a filter item, resolving dynamic destinations
839
+ * that reference the route attribute to context.params[attr].
840
+ */
841
+ const buildFilterObjectAST = (
842
+ filterItem: Record<string, unknown>,
843
+ dynamicRouteAttr?: string
844
+ ): types.ObjectExpression => {
845
+ const properties: types.ObjectProperty[] = []
846
+
847
+ for (const [key, value] of Object.entries(filterItem)) {
848
+ if (value === undefined) {
849
+ continue
850
+ }
851
+
852
+ if (key === 'destination' && dynamicRouteAttr && ASTUtils.isUIDLDynamicReference(value)) {
853
+ const content = (value as { content: { id: string } }).content
854
+ properties.push(
855
+ types.objectProperty(types.stringLiteral(key), createContextParamsAccess(content.id))
856
+ )
857
+ } else if (typeof value === 'string') {
858
+ properties.push(types.objectProperty(types.stringLiteral(key), types.stringLiteral(value)))
859
+ } else if (typeof value === 'number') {
860
+ properties.push(types.objectProperty(types.stringLiteral(key), types.numericLiteral(value)))
861
+ } else if (typeof value === 'boolean') {
862
+ properties.push(types.objectProperty(types.stringLiteral(key), types.booleanLiteral(value)))
863
+ } else if (value === null) {
864
+ properties.push(types.objectProperty(types.stringLiteral(key), types.nullLiteral()))
865
+ } else if (Array.isArray(value)) {
866
+ properties.push(
867
+ types.objectProperty(
868
+ types.stringLiteral(key),
869
+ types.arrayExpression(value.map((v) => ASTUtils.convertValueToLiteral(v)))
870
+ )
871
+ )
872
+ } else if (typeof value === 'object') {
873
+ properties.push(
874
+ types.objectProperty(
875
+ types.stringLiteral(key),
876
+ ASTUtils.objectToObjectExpression(value as Record<string, unknown>)
877
+ )
878
+ )
879
+ }
880
+ }
881
+
882
+ return types.objectExpression(properties)
883
+ }
884
+
709
885
  // tslint:disable-next-line:no-any
710
886
  export const extractDataSourceIntoGetStaticProps = (
711
887
  node: UIDLDataSourceItemNode | UIDLDataSourceListNode,
@@ -714,7 +890,9 @@ export const extractDataSourceIntoGetStaticProps = (
714
890
  getStaticPropsChunk: any,
715
891
  chunks: any[],
716
892
  extractedResources: GeneratorOptions['extractedResources'],
717
- dependencies: Record<string, any>
893
+ dependencies: Record<string, any>,
894
+ dynamicRouteAttr?: string,
895
+ folderPath?: string[]
718
896
  ): { success: boolean; chunk?: any } => {
719
897
  try {
720
898
  // Validate node content
@@ -1061,9 +1239,16 @@ export const extractDataSourceIntoGetStaticProps = (
1061
1239
 
1062
1240
  // Add dependency for the fetcher
1063
1241
  const fetcherImportName = StringUtils.dashCaseToCamelCase(fileName)
1242
+ // Calculate the correct relative path based on page folder depth.
1243
+ // folderPath contains subfolders within pages/ (e.g. ['admin'] for pages/admin/X.js).
1244
+ // We add 1 for the pages/ directory itself.
1245
+ // Pages at pages/X.js (folderPath=[]) need '../' (1 level up)
1246
+ // Pages at pages/admin/X.js (folderPath=['admin']) need '../../' (2 levels up)
1247
+ const depth = (folderPath ? folderPath.length : 0) + 1
1248
+ const relativePrefix = '../'.repeat(depth)
1064
1249
  dependencies[fetcherImportName] = {
1065
1250
  type: 'local',
1066
- path: `../utils/data-sources/${fileName}`,
1251
+ path: `${relativePrefix}utils/data-sources/${fileName}`,
1067
1252
  }
1068
1253
 
1069
1254
  // Build params object from resource params
@@ -1092,18 +1277,34 @@ export const extractDataSourceIntoGetStaticProps = (
1092
1277
 
1093
1278
  // For sorts, filters, and queryColumns, stringify the array for consistency with API handler
1094
1279
  if (key === 'sorts' || key === 'filters' || key === 'queryColumns') {
1095
- // For filters, filter out items with dynamic destinations (can't be resolved at build time)
1096
1280
  let itemsToProcess = validItems
1097
1281
  if (key === 'filters') {
1098
- itemsToProcess = validItems.filter(
1099
- (item: any) => !ASTUtils.isUIDLDynamicReference(item?.destination)
1100
- )
1101
- // Skip entirely if no static filters remain
1282
+ // Keep filter items that are either static or route-resolvable (via dynamicRouteAttr)
1283
+ // Filter out items with unresolvable dynamic destinations
1284
+ itemsToProcess = validItems.filter((item: any) => {
1285
+ if (!ASTUtils.isUIDLDynamicReference(item?.destination)) {
1286
+ return true
1287
+ }
1288
+ if (dynamicRouteAttr) {
1289
+ return isFilterDestinationRouteResolvable(item.destination, dynamicRouteAttr)
1290
+ }
1291
+ return false
1292
+ })
1102
1293
  if (itemsToProcess.length === 0) {
1103
1294
  return
1104
1295
  }
1105
1296
  }
1106
1297
 
1298
+ const hasRouteResolvableFilters =
1299
+ key === 'filters' &&
1300
+ dynamicRouteAttr &&
1301
+ itemsToProcess.some(
1302
+ (item: any) =>
1303
+ item &&
1304
+ typeof item === 'object' &&
1305
+ ASTUtils.isUIDLDynamicReference(item?.destination)
1306
+ )
1307
+
1107
1308
  const arrayExpr = types.arrayExpression(
1108
1309
  itemsToProcess.map((item: any) => {
1109
1310
  if (typeof item === 'string') {
@@ -1116,6 +1317,12 @@ export const extractDataSourceIntoGetStaticProps = (
1116
1317
  return types.booleanLiteral(item)
1117
1318
  }
1118
1319
  if (typeof item === 'object' && item !== null) {
1320
+ if (
1321
+ hasRouteResolvableFilters &&
1322
+ ASTUtils.isUIDLDynamicReference(item?.destination)
1323
+ ) {
1324
+ return buildFilterObjectAST(item, dynamicRouteAttr)
1325
+ }
1119
1326
  return ASTUtils.objectToObjectExpression(item)
1120
1327
  }
1121
1328
  return types.nullLiteral()
@@ -1159,9 +1366,18 @@ export const extractDataSourceIntoGetStaticProps = (
1159
1366
  }
1160
1367
 
1161
1368
  paramsProperties.push(types.objectProperty(types.stringLiteral(key), astValue))
1369
+ } else if (
1370
+ value.type === 'dynamic' &&
1371
+ dynamicRouteAttr &&
1372
+ isDynamicParamRouteResolvable(value, dynamicRouteAttr)
1373
+ ) {
1374
+ paramsProperties.push(
1375
+ types.objectProperty(
1376
+ types.stringLiteral(key),
1377
+ createContextParamsAccess(value.content.id)
1378
+ )
1379
+ )
1162
1380
  }
1163
- // Note: We don't handle 'expr' or 'dynamic' params in getStaticProps
1164
- // as those should be detected by hasResourceDynamicParams check earlier
1165
1381
  })
1166
1382
 
1167
1383
  const fetchCallExpression = types.callExpression(
@@ -1,7 +0,0 @@
1
- export declare const validateStaticCollectionConfig: (config: Record<string, unknown>) => {
2
- isValid: boolean;
3
- error?: string;
4
- };
5
- export declare const generateStaticCollectionFetcher: (config: Record<string, unknown>) => string;
6
- export declare const generateStaticCollectionCountFetcher: (_config: any) => string;
7
- //# sourceMappingURL=static-collection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"static-collection.d.ts","sourceRoot":"","sources":["../../../src/fetchers/static-collection.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAUpC,CAAA;AAMD,eAAO,MAAM,+BAA+B,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MA4JjF,CAAA;AAGD,eAAO,MAAM,oCAAoC,YAAa,GAAG,KAAG,MA+CnE,CAAA"}
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateStaticCollectionCountFetcher = exports.generateStaticCollectionFetcher = exports.validateStaticCollectionConfig = void 0;
4
- var utils_1 = require("../utils");
5
- var validateStaticCollectionConfig = function (config) {
6
- if (!config || typeof config !== 'object') {
7
- return { isValid: false, error: 'Config must be a valid object' };
8
- }
9
- if (!config.data || !Array.isArray(config.data)) {
10
- return { isValid: false, error: 'Data must be an array' };
11
- }
12
- return { isValid: true };
13
- };
14
- exports.validateStaticCollectionConfig = validateStaticCollectionConfig;
15
- var generateStaticCollectionFetcher = function (config) {
16
- var staticConfig = config;
17
- return "const data = ".concat(JSON.stringify(staticConfig.data || []), "\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\n").concat((0, utils_1.generateSortFilterHelperCode)(), "\n\nexport default async function handler(req, res) {\n try {\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset: offsetParam } = req.query\n \n let filteredData = [...data]\n \n if (query) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n const columns = safeJSONParse(queryColumns)\n filteredData = filteredData.filter((item) => {\n return columns.some((col) => {\n const value = getNestedValue(item, col)\n return value && String(value).toLowerCase().includes(searchQuery)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n try {\n const stringified = JSON.stringify(item).toLowerCase()\n return stringified.includes(searchQuery)\n } catch {\n return false\n }\n })\n }\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n filteredData = filteredData.filter((item) => {\n return parsedFilters.every((filter) => {\n if (!filter.source || filter.destination === undefined) return true\n \n const field = filter.source\n const value = getNestedValue(item, field)\n const target = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(target)) {\n if (operand === '!=') {\n return !target.includes(value)\n }\n return target.includes(value)\n }\n \n return compareValues(value, target, operand)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n const itemValue = getNestedValue(item, key)\n if (Array.isArray(value)) {\n return value.includes(itemValue)\n }\n return compareValues(itemValue, value, '=')\n })\n })\n }\n }\n \n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n filteredData.sort((a, b) => {\n for (const sort of parsedSorts) {\n if (!sort.field) continue\n const aVal = getNestedValue(a, sort.field)\n const bVal = getNestedValue(b, sort.field)\n const sortOrderValue = sort.order?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n if (comparison !== 0) return comparison * sortOrderValue\n }\n return 0\n })\n }\n } else if (sortBy) {\n filteredData.sort((a, b) => {\n const aVal = getNestedValue(a, sortBy)\n const bVal = getNestedValue(b, sortBy)\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n return comparison * sortOrderValue\n })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offsetParam !== undefined ? parseInt(offsetParam) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : 0)\n \n if (limitValue) {\n filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))\n }\n \n const safeData = JSON.parse(JSON.stringify(filteredData, dateReplacer))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Static collection fetch error:', error)\n return res.status(500).json({\n success: false,\n error: error.message || 'Failed to fetch data',\n timestamp: Date.now()\n })\n }\n}\n");
18
- };
19
- exports.generateStaticCollectionFetcher = generateStaticCollectionFetcher;
20
- // tslint:disable-next-line:variable-name
21
- var generateStaticCollectionCountFetcher = function (_config) {
22
- return "\nasync function getCount(req, res) {\n try {\n const { query, queryColumns, filters } = req.query\n const fakeReq = { query: { query, queryColumns, filters }, method: 'GET' }\n let result = null\n let statusCode = 200\n \n const fakeRes = {\n status: (code) => {\n statusCode = code\n return fakeRes\n },\n json: (data) => {\n result = data\n return fakeRes\n },\n }\n \n await handler(fakeReq, fakeRes)\n \n if (statusCode !== 200 || !result || !result.success) {\n return res.status(500).json({\n success: false,\n error: 'Failed to get data for counting',\n timestamp: Date.now()\n })\n }\n \n const count = Array.isArray(result.data) ? result.data.length : 0\n \n return res.status(200).json({\n success: true,\n count: count,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Error getting count:', error)\n return res.status(500).json({\n success: false,\n error: error.message || 'Failed to get count',\n timestamp: Date.now()\n })\n }\n}\n";
23
- };
24
- exports.generateStaticCollectionCountFetcher = generateStaticCollectionCountFetcher;
25
- //# sourceMappingURL=static-collection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"static-collection.js","sourceRoot":"","sources":["../../../src/fetchers/static-collection.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,IAAM,8BAA8B,GAAG,UAC5C,MAA+B;IAE/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAA;KAClE;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC/C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAA;KAC1D;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAZY,QAAA,8BAA8B,kCAY1C;AAMM,IAAM,+BAA+B,GAAG,UAAC,MAA+B;IAC7E,IAAM,YAAY,GAAG,MAAgC,CAAA;IACrD,OAAO,uBAAgB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC,iBAE9D,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,oCAA4B,GAAE,ypKAmJ/B,CAAA;AACD,CAAC,CAAA;AA5JY,QAAA,+BAA+B,mCA4J3C;AAED,yCAAyC;AAClC,IAAM,oCAAoC,GAAG,UAAC,OAAY;IAC/D,OAAO,knCA6CR,CAAA;AACD,CAAC,CAAA;AA/CY,QAAA,oCAAoC,wCA+ChD"}
@@ -1,7 +0,0 @@
1
- export declare const validateStaticCollectionConfig: (config: Record<string, unknown>) => {
2
- isValid: boolean;
3
- error?: string;
4
- };
5
- export declare const generateStaticCollectionFetcher: (config: Record<string, unknown>) => string;
6
- export declare const generateStaticCollectionCountFetcher: (_config: any) => string;
7
- //# sourceMappingURL=static-collection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"static-collection.d.ts","sourceRoot":"","sources":["../../../src/fetchers/static-collection.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAUpC,CAAA;AAMD,eAAO,MAAM,+BAA+B,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MA4JjF,CAAA;AAGD,eAAO,MAAM,oCAAoC,YAAa,GAAG,KAAG,MA+CnE,CAAA"}