@teleporthq/teleport-plugin-next-data-source 0.43.74 → 0.44.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 (231) hide show
  1. package/__tests__/_helpers/pagination-widget-fixture.ts +95 -5
  2. package/__tests__/blog-adjacent-arranged.test.ts +176 -0
  3. package/__tests__/blog-post-contents.test.ts +212 -0
  4. package/__tests__/blog-post-page-enrichment.test.ts +28 -5
  5. package/__tests__/blog-post-picture-stand-in.test.ts +48 -0
  6. package/__tests__/blog-post-reading-time.test.ts +55 -0
  7. package/__tests__/booking-item-transform.test.ts +120 -0
  8. package/__tests__/browser-row-policy.test.ts +13 -3
  9. package/__tests__/content-preset-wiring.test.ts +108 -0
  10. package/__tests__/fetchers.test.ts +1 -1
  11. package/__tests__/fixed-list-sort.test.ts +183 -0
  12. package/__tests__/infinite-scroll.test.ts +154 -5
  13. package/__tests__/list-sort-order.test.ts +61 -0
  14. package/__tests__/null-filter-where.test.ts +132 -0
  15. package/__tests__/pagination-filter-groups.test.ts +186 -0
  16. package/__tests__/pg-date-parser.test.ts +73 -0
  17. package/__tests__/plain-list-sort.test.ts +215 -0
  18. package/__tests__/product-price-sort.ts +58 -25
  19. package/__tests__/range-control.test.ts +159 -0
  20. package/__tests__/rest-api-key-header.test.ts +18 -0
  21. package/__tests__/search-input-marker.test.ts +86 -0
  22. package/__tests__/search-url-sync.test.ts +61 -16
  23. package/__tests__/shared-resource-prefetch.test.ts +65 -0
  24. package/__tests__/table-read-route-protected-tables.test.ts +33 -3
  25. package/dist/cjs/count-effect.d.ts +7 -1
  26. package/dist/cjs/count-effect.d.ts.map +1 -1
  27. package/dist/cjs/count-effect.js +15 -5
  28. package/dist/cjs/count-effect.js.map +1 -1
  29. package/dist/cjs/fetchers/pg-client-import.d.ts +12 -0
  30. package/dist/cjs/fetchers/pg-client-import.d.ts.map +1 -0
  31. package/dist/cjs/fetchers/pg-client-import.js +15 -0
  32. package/dist/cjs/fetchers/pg-client-import.js.map +1 -0
  33. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  34. package/dist/cjs/fetchers/postgresql.js +4 -1
  35. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  36. package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
  37. package/dist/cjs/fetchers/raw-query.js +2 -1
  38. package/dist/cjs/fetchers/raw-query.js.map +1 -1
  39. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  40. package/dist/cjs/fetchers/rest-api.js +3 -1
  41. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  42. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  43. package/dist/cjs/fetchers/teleport.js +5 -2
  44. package/dist/cjs/fetchers/teleport.js.map +1 -1
  45. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts +7 -6
  46. package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -1
  47. package/dist/cjs/fetchers/utils/browser-row-policy.js +7 -33
  48. package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -1
  49. package/dist/cjs/filter-utils.d.ts +19 -7
  50. package/dist/cjs/filter-utils.d.ts.map +1 -1
  51. package/dist/cjs/filter-utils.js +49 -13
  52. package/dist/cjs/filter-utils.js.map +1 -1
  53. package/dist/cjs/infinite-scroll.d.ts +25 -2
  54. package/dist/cjs/infinite-scroll.d.ts.map +1 -1
  55. package/dist/cjs/infinite-scroll.js +144 -33
  56. package/dist/cjs/infinite-scroll.js.map +1 -1
  57. package/dist/cjs/list-sort-order.d.ts +14 -0
  58. package/dist/cjs/list-sort-order.d.ts.map +1 -0
  59. package/dist/cjs/list-sort-order.js +36 -0
  60. package/dist/cjs/list-sort-order.js.map +1 -0
  61. package/dist/cjs/pagination-controls.d.ts +22 -3
  62. package/dist/cjs/pagination-controls.d.ts.map +1 -1
  63. package/dist/cjs/pagination-controls.js +29 -3
  64. package/dist/cjs/pagination-controls.js.map +1 -1
  65. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  66. package/dist/cjs/pagination-plugin.js +267 -212
  67. package/dist/cjs/pagination-plugin.js.map +1 -1
  68. package/dist/cjs/product-price-sort.d.ts +0 -9
  69. package/dist/cjs/product-price-sort.d.ts.map +1 -1
  70. package/dist/cjs/product-price-sort.js +1 -13
  71. package/dist/cjs/product-price-sort.js.map +1 -1
  72. package/dist/cjs/range-control.d.ts +45 -0
  73. package/dist/cjs/range-control.d.ts.map +1 -0
  74. package/dist/cjs/range-control.js +165 -0
  75. package/dist/cjs/range-control.js.map +1 -0
  76. package/dist/cjs/row-order.d.ts +20 -0
  77. package/dist/cjs/row-order.d.ts.map +1 -0
  78. package/dist/cjs/row-order.js +46 -0
  79. package/dist/cjs/row-order.js.map +1 -0
  80. package/dist/cjs/search-input.d.ts +42 -0
  81. package/dist/cjs/search-input.d.ts.map +1 -0
  82. package/dist/cjs/search-input.js +158 -0
  83. package/dist/cjs/search-input.js.map +1 -0
  84. package/dist/cjs/sort-utils.d.ts +10 -0
  85. package/dist/cjs/sort-utils.d.ts.map +1 -1
  86. package/dist/cjs/sort-utils.js +22 -1
  87. package/dist/cjs/sort-utils.js.map +1 -1
  88. package/dist/cjs/transformations/blog-adjacent-posts.d.ts +11 -1
  89. package/dist/cjs/transformations/blog-adjacent-posts.d.ts.map +1 -1
  90. package/dist/cjs/transformations/blog-adjacent-posts.js +14 -1
  91. package/dist/cjs/transformations/blog-adjacent-posts.js.map +1 -1
  92. package/dist/cjs/transformations/blog-comments.d.ts +1 -1
  93. package/dist/cjs/transformations/blog-comments.d.ts.map +1 -1
  94. package/dist/cjs/transformations/blog-comments.js +1 -1
  95. package/dist/cjs/transformations/blog-comments.js.map +1 -1
  96. package/dist/cjs/transformations/blog-post.d.ts +14 -0
  97. package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
  98. package/dist/cjs/transformations/blog-post.js +4 -1
  99. package/dist/cjs/transformations/blog-post.js.map +1 -1
  100. package/dist/cjs/transformations/booking-item.d.ts +24 -0
  101. package/dist/cjs/transformations/booking-item.d.ts.map +1 -0
  102. package/dist/cjs/transformations/booking-item.js +27 -0
  103. package/dist/cjs/transformations/booking-item.js.map +1 -0
  104. package/dist/cjs/transformations/heading-anchors.d.ts +32 -8
  105. package/dist/cjs/transformations/heading-anchors.d.ts.map +1 -1
  106. package/dist/cjs/transformations/heading-anchors.js +34 -10
  107. package/dist/cjs/transformations/heading-anchors.js.map +1 -1
  108. package/dist/cjs/transformations/index.d.ts +27 -13
  109. package/dist/cjs/transformations/index.d.ts.map +1 -1
  110. package/dist/cjs/transformations/index.js +73 -16
  111. package/dist/cjs/transformations/index.js.map +1 -1
  112. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  113. package/dist/cjs/utils.d.ts.map +1 -1
  114. package/dist/cjs/utils.js +52 -3
  115. package/dist/cjs/utils.js.map +1 -1
  116. package/dist/esm/count-effect.d.ts +7 -1
  117. package/dist/esm/count-effect.d.ts.map +1 -1
  118. package/dist/esm/count-effect.js +15 -5
  119. package/dist/esm/count-effect.js.map +1 -1
  120. package/dist/esm/fetchers/pg-client-import.d.ts +12 -0
  121. package/dist/esm/fetchers/pg-client-import.d.ts.map +1 -0
  122. package/dist/esm/fetchers/pg-client-import.js +12 -0
  123. package/dist/esm/fetchers/pg-client-import.js.map +1 -0
  124. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  125. package/dist/esm/fetchers/postgresql.js +5 -2
  126. package/dist/esm/fetchers/postgresql.js.map +1 -1
  127. package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
  128. package/dist/esm/fetchers/raw-query.js +2 -1
  129. package/dist/esm/fetchers/raw-query.js.map +1 -1
  130. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  131. package/dist/esm/fetchers/rest-api.js +3 -1
  132. package/dist/esm/fetchers/rest-api.js.map +1 -1
  133. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  134. package/dist/esm/fetchers/teleport.js +6 -3
  135. package/dist/esm/fetchers/teleport.js.map +1 -1
  136. package/dist/esm/fetchers/utils/browser-row-policy.d.ts +7 -6
  137. package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -1
  138. package/dist/esm/fetchers/utils/browser-row-policy.js +5 -31
  139. package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -1
  140. package/dist/esm/filter-utils.d.ts +19 -7
  141. package/dist/esm/filter-utils.d.ts.map +1 -1
  142. package/dist/esm/filter-utils.js +46 -12
  143. package/dist/esm/filter-utils.js.map +1 -1
  144. package/dist/esm/infinite-scroll.d.ts +25 -2
  145. package/dist/esm/infinite-scroll.d.ts.map +1 -1
  146. package/dist/esm/infinite-scroll.js +142 -32
  147. package/dist/esm/infinite-scroll.js.map +1 -1
  148. package/dist/esm/list-sort-order.d.ts +14 -0
  149. package/dist/esm/list-sort-order.d.ts.map +1 -0
  150. package/dist/esm/list-sort-order.js +32 -0
  151. package/dist/esm/list-sort-order.js.map +1 -0
  152. package/dist/esm/pagination-controls.d.ts +22 -3
  153. package/dist/esm/pagination-controls.d.ts.map +1 -1
  154. package/dist/esm/pagination-controls.js +28 -2
  155. package/dist/esm/pagination-controls.js.map +1 -1
  156. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  157. package/dist/esm/pagination-plugin.js +271 -216
  158. package/dist/esm/pagination-plugin.js.map +1 -1
  159. package/dist/esm/product-price-sort.d.ts +0 -9
  160. package/dist/esm/product-price-sort.d.ts.map +1 -1
  161. package/dist/esm/product-price-sort.js +0 -11
  162. package/dist/esm/product-price-sort.js.map +1 -1
  163. package/dist/esm/range-control.d.ts +45 -0
  164. package/dist/esm/range-control.d.ts.map +1 -0
  165. package/dist/esm/range-control.js +137 -0
  166. package/dist/esm/range-control.js.map +1 -0
  167. package/dist/esm/row-order.d.ts +20 -0
  168. package/dist/esm/row-order.d.ts.map +1 -0
  169. package/dist/esm/row-order.js +41 -0
  170. package/dist/esm/row-order.js.map +1 -0
  171. package/dist/esm/search-input.d.ts +42 -0
  172. package/dist/esm/search-input.d.ts.map +1 -0
  173. package/dist/esm/search-input.js +129 -0
  174. package/dist/esm/search-input.js.map +1 -0
  175. package/dist/esm/sort-utils.d.ts +10 -0
  176. package/dist/esm/sort-utils.d.ts.map +1 -1
  177. package/dist/esm/sort-utils.js +20 -0
  178. package/dist/esm/sort-utils.js.map +1 -1
  179. package/dist/esm/transformations/blog-adjacent-posts.d.ts +11 -1
  180. package/dist/esm/transformations/blog-adjacent-posts.d.ts.map +1 -1
  181. package/dist/esm/transformations/blog-adjacent-posts.js +14 -1
  182. package/dist/esm/transformations/blog-adjacent-posts.js.map +1 -1
  183. package/dist/esm/transformations/blog-comments.d.ts +1 -1
  184. package/dist/esm/transformations/blog-comments.d.ts.map +1 -1
  185. package/dist/esm/transformations/blog-comments.js +1 -1
  186. package/dist/esm/transformations/blog-comments.js.map +1 -1
  187. package/dist/esm/transformations/blog-post.d.ts +14 -0
  188. package/dist/esm/transformations/blog-post.d.ts.map +1 -1
  189. package/dist/esm/transformations/blog-post.js +4 -1
  190. package/dist/esm/transformations/blog-post.js.map +1 -1
  191. package/dist/esm/transformations/booking-item.d.ts +24 -0
  192. package/dist/esm/transformations/booking-item.d.ts.map +1 -0
  193. package/dist/esm/transformations/booking-item.js +23 -0
  194. package/dist/esm/transformations/booking-item.js.map +1 -0
  195. package/dist/esm/transformations/heading-anchors.d.ts +32 -8
  196. package/dist/esm/transformations/heading-anchors.d.ts.map +1 -1
  197. package/dist/esm/transformations/heading-anchors.js +33 -9
  198. package/dist/esm/transformations/heading-anchors.js.map +1 -1
  199. package/dist/esm/transformations/index.d.ts +27 -13
  200. package/dist/esm/transformations/index.d.ts.map +1 -1
  201. package/dist/esm/transformations/index.js +72 -16
  202. package/dist/esm/transformations/index.js.map +1 -1
  203. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  204. package/dist/esm/utils.d.ts.map +1 -1
  205. package/dist/esm/utils.js +52 -3
  206. package/dist/esm/utils.js.map +1 -1
  207. package/package.json +5 -5
  208. package/src/count-effect.ts +31 -8
  209. package/src/fetchers/pg-client-import.ts +16 -0
  210. package/src/fetchers/postgresql.ts +25 -23
  211. package/src/fetchers/raw-query.ts +2 -1
  212. package/src/fetchers/rest-api.ts +3 -1
  213. package/src/fetchers/teleport.ts +22 -23
  214. package/src/fetchers/utils/browser-row-policy.ts +10 -20
  215. package/src/filter-utils.ts +102 -28
  216. package/src/infinite-scroll.ts +240 -79
  217. package/src/list-sort-order.ts +34 -0
  218. package/src/pagination-controls.ts +26 -3
  219. package/src/pagination-plugin.ts +370 -306
  220. package/src/product-price-sort.ts +0 -11
  221. package/src/range-control.ts +207 -0
  222. package/src/row-order.ts +55 -0
  223. package/src/search-input.ts +190 -0
  224. package/src/sort-utils.ts +25 -0
  225. package/src/transformations/blog-adjacent-posts.ts +89 -3
  226. package/src/transformations/blog-comments.ts +5 -5
  227. package/src/transformations/blog-post.ts +64 -13
  228. package/src/transformations/booking-item.ts +71 -0
  229. package/src/transformations/heading-anchors.ts +79 -16
  230. package/src/transformations/index.ts +104 -14
  231. package/src/utils.ts +74 -3
@@ -40,7 +40,7 @@ const makeComponentChunk = (): ChunkDefinition => {
40
40
  // A `data-source-list > cms-list-repeater` UIDL: a paginated + search-enabled
41
41
  // products list, optionally bound to a URL search-param key.
42
42
  // tslint:disable-next-line:no-any
43
- const makeUidlNode = (searchUrlParamKey?: string): any => ({
43
+ const makeUidlNode = (searchUrlParamKey?: string, pageUrlParamKey?: string): any => ({
44
44
  type: 'data-source-list',
45
45
  content: {
46
46
  renderPropIdentifier: 'items',
@@ -60,6 +60,7 @@ const makeUidlNode = (searchUrlParamKey?: string): any => ({
60
60
  searchEnabled: true,
61
61
  searchDebounce: 300,
62
62
  ...(searchUrlParamKey ? { searchUrlParamKey } : {}),
63
+ ...(pageUrlParamKey ? { pageUrlParamKey } : {}),
63
64
  nodes: { list: { type: 'element', content: { elementType: 'div' } } },
64
65
  },
65
66
  },
@@ -67,10 +68,19 @@ const makeUidlNode = (searchUrlParamKey?: string): any => ({
67
68
  },
68
69
  })
69
70
 
70
- const runPlugin = async (searchUrlParamKey?: string): Promise<string> => {
71
+ interface RunOptions {
72
+ paginated?: boolean
73
+ pageUrlParamKey?: string
74
+ infiniteScroll?: boolean
75
+ }
76
+
77
+ const runPlugin = async (searchUrlParamKey?: string, options: RunOptions = {}): Promise<string> => {
71
78
  const chunk = makeComponentChunk()
79
+ const node = makeUidlNode(searchUrlParamKey, options.pageUrlParamKey)
80
+ node.content.nodes.success.content.paginated = options.paginated ?? true
81
+ node.content.nodes.success.content.infiniteScroll = !!options.infiniteScroll
72
82
  const structure: ComponentStructure = {
73
- uidl: { name: 'TestComponent', node: makeUidlNode(searchUrlParamKey) },
83
+ uidl: { name: 'TestComponent', node },
74
84
  chunks: [chunk],
75
85
  dependencies: {},
76
86
  options: { dataSources: {}, extractedResources: {} },
@@ -81,33 +91,68 @@ const runPlugin = async (searchUrlParamKey?: string): Promise<string> => {
81
91
  }
82
92
 
83
93
  describe('pagination plugin — search input URL two-way sync (searchUrlParamKey)', () => {
84
- it('seeds the query from window.location.search and emits paired read-back/write-back effects', async () => {
94
+ it('starts from the default and adopts the address after mount, with paired read-back/write-back effects', async () => {
85
95
  const code = await runPlugin('searchKeyword')
86
96
 
87
- // Initial value seeded from the URL on the client (both the immediate input
88
- // state AND the debounced value, so a deep link fetches filtered on mount).
89
- const seedMatches = code.match(
90
- /new URLSearchParams\(window\.location\.search\)\.get\("searchKeyword"\)/g
91
- )
92
- expect(seedMatches).not.toBeNull()
93
- expect((seedMatches || []).length).toBe(2)
94
- expect(code).toContain('typeof window !== "undefined"')
97
+ // ⛔ Never seeded from the address: a statically generated page is rendered
98
+ // on the server without the visitor's query, and the first browser render
99
+ // must match it — a seeded query filled the input and skipped the
100
+ // prefetched rows there, and React warned of a hydration mismatch.
101
+ expect(code).not.toContain('window.location.search')
102
+ expect(code).toContain('const [ds_0_searchQuery, setDs_0_searchQuery] = useState("")')
103
+ expect(code).toContain('debouncedQuery: ""')
95
104
 
96
105
  // useRouter is injected for the effects.
97
106
  expect(code).toContain('const router = useRouter()')
98
107
 
99
- // Write-back (debounced query → URL), keyed on the DEBOUNCED value and
100
- // routed through the shared writer so it cannot race the page's own write.
108
+ // Write-back (debounced query → URL), keyed on the DEBOUNCED value, routed
109
+ // through the shared writer, and silent until the address was adopted —
110
+ // its first run would otherwise delete the key the read-back adopts.
111
+ expect(code).toContain('const ds_0_searchUrlAdopted = useRef(false)')
101
112
  expect(code).toContain('const __tqQuerySyncRef = useRef(')
113
+ expect(code).toContain('if (!ds_0_searchUrlAdopted.current) return;')
102
114
  expect(code).toContain(
103
115
  '__tqWriteQueryParam("searchKeyword", ds_0_state.debouncedQuery === "" || ds_0_state.debouncedQuery == null ? undefined : ds_0_state.debouncedQuery)'
104
116
  )
105
117
  expect(code).toContain('}, [ds_0_state.debouncedQuery, router.isReady])')
106
118
 
107
- // Read-back (URL → input), functional setState bail-out (loop-free).
119
+ // Read-back (URL → input AND applied query at once, from page 1: the page
120
+ // is not in the address), functional setState bail-out (loop-free), then
121
+ // the handshake flag.
108
122
  expect(code).toContain('const __urlValue = router.query.searchKeyword')
109
- expect(code).toContain('setDs_0_searchQuery(prev => prev === __nextValue ? prev : __nextValue)')
123
+ expect(code).toContain('ds_0_adoptUrlSearch(prev => prev === __nextValue ? prev : __nextValue)')
124
+ expect(code).toContain('ds_0_searchUrlAdopted.current = true')
110
125
  expect(code).toContain('}, [router.query.searchKeyword, router.isReady])')
126
+ expect(code.replace(/\s+/g, ' ')).toContain(
127
+ 'const ds_0_adoptUrlSearch = update => { setDs_0_searchQuery(update); setDs_0_state(state => { const next = update(state.debouncedQuery); return next === state.debouncedQuery ? state : { ...state, page: 1, debouncedQuery: next }; }); };'
128
+ )
129
+ })
130
+
131
+ it('starts an appending list on page 1 when the address brings a query', async () => {
132
+ // The scroll sentinel has usually fetched page 2 before the router is
133
+ // ready: kept, the query's first answer was its page 2 — empty when only a
134
+ // few rows match.
135
+ const code = await runPlugin('q', { infiniteScroll: true })
136
+ expect(code.replace(/\s+/g, ' ')).toContain(
137
+ 'return next === state.debouncedQuery ? state : { ...state, page: 1, debouncedQuery: next };'
138
+ )
139
+ })
140
+
141
+ it('keeps the page of a list whose page is in the address too', async () => {
142
+ const code = await runPlugin('searchKeyword', { pageUrlParamKey: 'page' })
143
+ expect(code.replace(/\s+/g, ' ')).toContain(
144
+ 'return next === state.debouncedQuery ? state : { ...state, debouncedQuery: next };'
145
+ )
146
+ })
147
+
148
+ it('adopts the address into both queries of a list without pages too', async () => {
149
+ const code = await runPlugin('searchKeyword', { paginated: false })
150
+ expect(code).not.toContain('window.location.search')
151
+ expect(code.replace(/\s+/g, ' ')).toContain(
152
+ 'const ds_0_adoptUrlSearch = update => { setDs_0_searchQuery(update); setDs_0_debouncedQuery(update); };'
153
+ )
154
+ expect(code).toContain('ds_0_adoptUrlSearch(prev => prev === __nextValue ? prev : __nextValue)')
155
+ expect(code).toContain('if (!ds_0_searchUrlAdopted.current) return;')
111
156
  })
112
157
 
113
158
  it('does NOT emit any URL sync when the repeater has no searchUrlParamKey (unchanged behaviour)', async () => {
@@ -109,3 +109,68 @@ describe('getStaticProps prefetch of providers sharing one resource', () => {
109
109
  expect(code.match(/fetchData\(/g)).toHaveLength(1)
110
110
  })
111
111
  })
112
+
113
+ /**
114
+ * A plain list's server prefetch carries the sort its repeater fixed: the page
115
+ * is pre-rendered with those rows and the browser keeps them (`initialData`
116
+ * skips the first fetch), so a prefetch without it showed the rows in the
117
+ * table's own order — "the latest three posts" as the first three ever.
118
+ */
119
+ describe('getStaticProps prefetch of a sorted plain list', () => {
120
+ const listNode = (
121
+ sort?: string,
122
+ params: Record<string, unknown> = {}
123
+ ): UIDLDataSourceItemNode => {
124
+ const node = nodeWithParams(params)
125
+ ;(node.content as { children: unknown[] }).children = [
126
+ {
127
+ type: 'cms-list-repeater',
128
+ content: {
129
+ renderPropIdentifier: 'post',
130
+ nodes: { list: { type: 'element', content: { elementType: 'div' } } },
131
+ ...(sort
132
+ ? {
133
+ sort: { type: 'static', content: sort },
134
+ sortDirection: { type: 'static', content: 'desc' },
135
+ }
136
+ : {}),
137
+ },
138
+ },
139
+ ]
140
+ return node
141
+ }
142
+
143
+ it('prefetches the rows in the order the list shows them', () => {
144
+ const code = prefetch([{ node: listNode('created_at') }], [providerWithLimit()])
145
+ expect(code).toContain(
146
+ 'fetchData({ "sorts": JSON.stringify([{ field: "created_at", order: "desc" }]) })'
147
+ )
148
+ })
149
+
150
+ it('keeps the sort the resource itself names', () => {
151
+ const code = prefetch(
152
+ [
153
+ {
154
+ node: listNode('created_at', {
155
+ sorts: { type: 'static', content: [{ field: 'title', order: 'asc' }] },
156
+ }),
157
+ },
158
+ ],
159
+ [providerWithLimit()]
160
+ )
161
+ expect(code).toContain('"sorts": JSON.stringify([{ "field": "title", "order": "asc" }])')
162
+ expect(code).not.toContain('created_at')
163
+ })
164
+
165
+ it('gives two lists sorted differently their own prefetch', () => {
166
+ const newest = providerWithLimit()
167
+ const oldest = providerWithLimit()
168
+ const code = prefetch(
169
+ [{ node: listNode('created_at') }, { node: listNode('title') }],
170
+ [newest, oldest]
171
+ )
172
+ expect(initialDataOf(newest)).toBe('{props.data_dsjsdata}')
173
+ expect(initialDataOf(oldest)).toBe('{props.data_dsjsdata_2}')
174
+ expect(code.match(/fetchData\(/g)).toHaveLength(2)
175
+ })
176
+ })
@@ -62,7 +62,10 @@ function bootTableRoute(
62
62
  })
63
63
  // The route is an ES module; run it as a script with the same bindings.
64
64
  const code = esm
65
- .replace("import { Client } from 'pg'", "const { Client } = require('pg')")
65
+ .replace(
66
+ "import { Client, types as pgTypes } from 'pg'",
67
+ "const { Client, types: pgTypes } = require('pg')"
68
+ )
66
69
  .replace(/^export default async function handler/m, 'async function handler')
67
70
  .replace(/^export \{[^}]*\}\s*$/m, '')
68
71
  .replace(/^export default \{[^}]*\}\s*$/m, '')
@@ -436,7 +439,7 @@ describe('buildProductTransformOptions — the roles reach the emitted module',
436
439
  })
437
440
 
438
441
  describe('resolveTrustedReaderRoles', () => {
439
- it('reads the roles off the admin folder and the admin pages, and nothing else', () => {
442
+ it("reads the roles off the admin folder, never off one admin page's own roles", () => {
440
443
  const roles = TableAccess.resolveTrustedReaderRoles({
441
444
  enabled: true,
442
445
  dataSourceId: 'ds-1',
@@ -487,7 +490,34 @@ describe('resolveTrustedReaderRoles', () => {
487
490
  envKeys: {},
488
491
  customUserProperties: [],
489
492
  })
490
- expect(roles).toEqual(['admin', 'staff'])
493
+ // `staff` opens `/admin/orders` only: a page's role is no reader of every
494
+ // protected table (an admin page may also admit staff).
495
+ expect(roles).toEqual(['admin'])
491
496
  expect(TableAccess.resolveTrustedReaderRoles(undefined)).toEqual([])
492
497
  })
498
+
499
+ it('refuses staff admitted to some admin pages the accounts table on its read route', async () => {
500
+ const staffPagesAuth: UIDLAuthentication = {
501
+ ...ADMIN_PANEL_AUTH,
502
+ roles: ['admin', 'staff', 'user'],
503
+ pageProtection: {
504
+ dashboard: {
505
+ requiresAuth: true,
506
+ allowedRoles: ['admin', 'staff'],
507
+ pageName: 'dashboard',
508
+ route: '/admin/dashboard',
509
+ },
510
+ tasks: {
511
+ requiresAuth: true,
512
+ allowedRoles: ['admin', 'staff'],
513
+ pageName: 'tasks',
514
+ route: '/admin/tasks',
515
+ },
516
+ },
517
+ }
518
+ const options = buildProductTransformOptions({ authentication: staffPagesAuth })
519
+ const users = bootTableRoute('users', options.trustedReaderRoles || [])
520
+ expect((await users({ handler: 'handler', session: { role: 'staff' } })).status).toBe(403)
521
+ expect((await users({ handler: 'handler', session: { role: 'admin' } })).status).toBe(200)
522
+ })
493
523
  })
@@ -19,6 +19,12 @@ interface CountEffectOptions {
19
19
  perPage: number;
20
20
  /** Name of the `setDs_N_maxPages` setter. */
21
21
  setMaxPagesVar: string;
22
+ /**
23
+ * Name of the `setDs_N_total` setter, declared only when the component draws
24
+ * a `range` control ("Showing 1–8 of 12"): the page count alone cannot say
25
+ * how many rows there are.
26
+ */
27
+ setTotalVar?: string;
22
28
  /**
23
29
  * Params sent to the count endpoint: the search query (when the list has
24
30
  * one), `queryColumns`, and the filter array. Built by the caller because
@@ -38,7 +44,7 @@ interface CountEffectOptions {
38
44
  }
39
45
  /** `const ds_N_countSeq = useRef(0)` */
40
46
  export declare const buildCountSeqDeclaration: (countSeqRefVar: string) => types.Statement;
41
- export declare const buildCountFetchStatement: (options: Pick<CountEffectOptions, 'fileName' | 'perPage' | 'setMaxPagesVar' | 'urlParams' | 'countSeqRefVar'>) => types.Statement;
47
+ export declare const buildCountFetchStatement: (options: Pick<CountEffectOptions, 'fileName' | 'perPage' | 'setMaxPagesVar' | 'setTotalVar' | 'urlParams' | 'countSeqRefVar'>) => types.Statement;
42
48
  /**
43
49
  * The whole `useEffect(...)` wrapper.
44
50
  *
@@ -1 +1 @@
1
- {"version":3,"file":"count-effect.d.ts","sourceRoot":"","sources":["../../src/count-effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;;;GAYG;AAEH,UAAU,kBAAkB;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,SAAS,EAAE,KAAK,CAAC,cAAc,EAAE,CAAA;IACjC,iDAAiD;IACjD,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,CAAA;IACxB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,wCAAwC;AACxC,eAAO,MAAM,wBAAwB,mBAAoB,MAAM,KAAG,MAAM,SAMpE,CAAA;AAqDJ,eAAO,MAAM,wBAAwB,YAC1B,KACP,kBAAkB,EAClB,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,WAAW,GAAG,gBAAgB,CAC3E,KACA,MAAM,SA2DN,CAAA;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,YAAa,kBAAkB,KAAG,MAAM,mBAYvE,CAAA"}
1
+ {"version":3,"file":"count-effect.d.ts","sourceRoot":"","sources":["../../src/count-effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;;;GAYG;AAEH,UAAU,kBAAkB;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,SAAS,EAAE,KAAK,CAAC,cAAc,EAAE,CAAA;IACjC,iDAAiD;IACjD,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,CAAA;IACxB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,wCAAwC;AACxC,eAAO,MAAM,wBAAwB,mBAAoB,MAAM,KAAG,MAAM,SAMpE,CAAA;AA4EJ,eAAO,MAAM,wBAAwB,YAC1B,KACP,kBAAkB,EAClB,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,aAAa,GAAG,WAAW,GAAG,gBAAgB,CAC3F,KACA,MAAM,SAqDN,CAAA;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,YAAa,kBAAkB,KAAG,MAAM,mBAYvE,CAAA"}
@@ -61,6 +61,20 @@ var buildCountSeqCapture = function (countSeqRefVar) {
61
61
  var buildStaleCountGuard = function (countSeqRefVar) {
62
62
  return types.ifStatement(types.binaryExpression('!==', types.identifier(COUNT_SEQ_LOCAL), refCurrent(countSeqRefVar)), types.returnStatement());
63
63
  };
64
+ /** `setDs_N_maxPages(...)` and, for a component with a range control, `setDs_N_total(data.count)`. */
65
+ var buildCountSetters = function (options) {
66
+ var setters = [
67
+ types.expressionStatement(types.callExpression(types.identifier(options.setMaxPagesVar), [
68
+ buildMaxPagesExpression(options.perPage),
69
+ ])),
70
+ ];
71
+ if (options.setTotalVar) {
72
+ setters.push(types.expressionStatement(types.callExpression(types.identifier(options.setTotalVar), [
73
+ types.memberExpression(types.identifier('data'), types.identifier('count')),
74
+ ])));
75
+ }
76
+ return setters;
77
+ };
64
78
  var buildCountFetchStatement = function (options) {
65
79
  return types.expressionStatement(types.callExpression(types.memberExpression(types.callExpression(types.memberExpression(types.callExpression(types.identifier('fetch'), [
66
80
  types.templateLiteral([
@@ -79,11 +93,7 @@ var buildCountFetchStatement = function (options) {
79
93
  ]), types.identifier('then')), [
80
94
  types.arrowFunctionExpression([types.identifier('data')], types.blockStatement([
81
95
  buildStaleCountGuard(options.countSeqRefVar),
82
- types.ifStatement(types.logicalExpression('&&', types.identifier('data'), types.binaryExpression('in', types.stringLiteral('count'), types.identifier('data'))), types.blockStatement([
83
- types.expressionStatement(types.callExpression(types.identifier(options.setMaxPagesVar), [
84
- buildMaxPagesExpression(options.perPage),
85
- ])),
86
- ])),
96
+ types.ifStatement(types.logicalExpression('&&', types.identifier('data'), types.binaryExpression('in', types.stringLiteral('count'), types.identifier('data'))), types.blockStatement(buildCountSetters(options))),
87
97
  ])),
88
98
  ]));
89
99
  };
@@ -1 +1 @@
1
- {"version":3,"file":"count-effect.js","sourceRoot":"","sources":["../../src/count-effect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"count-effect.js","sourceRoot":"","sources":["../../src/count-effect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The `pg` import of a generated Postgres fetcher.
3
+ *
4
+ * A Postgres DATE is a calendar day, not an instant. node-pg reads it as
5
+ * midnight in the server's time zone, so a server east of UTC sends
6
+ * `2026-10-09` as `2026-10-08T21:00:00.000Z`: a list shows the day before, and
7
+ * a form that loads the row saves that day back. The day is kept as its own
8
+ * text (`YYYY-MM-DD`), which every reader of the value already understands.
9
+ * A stand-in driver without `types` leaves the parsers alone.
10
+ */
11
+ export declare const PG_CLIENT_IMPORT = "import { Client, types as pgTypes } from 'pg'\n\n// A DATE stays the day it names, whatever the server's time zone.\nif (pgTypes && typeof pgTypes.setTypeParser === 'function') {\n pgTypes.setTypeParser(1082, (value) => value)\n}";
12
+ //# sourceMappingURL=pg-client-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-client-import.d.ts","sourceRoot":"","sources":["../../../src/fetchers/pg-client-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,2OAK3B,CAAA"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PG_CLIENT_IMPORT = void 0;
4
+ /**
5
+ * The `pg` import of a generated Postgres fetcher.
6
+ *
7
+ * A Postgres DATE is a calendar day, not an instant. node-pg reads it as
8
+ * midnight in the server's time zone, so a server east of UTC sends
9
+ * `2026-10-09` as `2026-10-08T21:00:00.000Z`: a list shows the day before, and
10
+ * a form that loads the row saves that day back. The day is kept as its own
11
+ * text (`YYYY-MM-DD`), which every reader of the value already understands.
12
+ * A stand-in driver without `types` leaves the parsers alone.
13
+ */
14
+ exports.PG_CLIENT_IMPORT = "import { Client, types as pgTypes } from 'pg'\n\n// A DATE stays the day it names, whatever the server's time zone.\nif (pgTypes && typeof pgTypes.setTypeParser === 'function') {\n pgTypes.setTypeParser(1082, (value) => value)\n}";
15
+ //# sourceMappingURL=pg-client-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-client-import.js","sourceRoot":"","sources":["../../../src/fetchers/pg-client-import.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACU,QAAA,gBAAgB,GAAG,wOAK9B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,uBACG,cAAc,MAAM,CAAC,KACxC,MAmSF,CAAA;AAED,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAkGF,CAAA"}
1
+ {"version":3,"file":"postgresql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,uBACG,cAAc,MAAM,CAAC,KACxC,MAsSF,CAAA;AAED,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAkGF,CAAA"}
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generatePostgreSQLCountFetcher = exports.generatePostgreSQLFetcher = void 0;
4
4
  var utils_1 = require("../utils");
5
5
  var product_price_sort_1 = require("../product-price-sort");
6
+ var list_sort_order_1 = require("../list-sort-order");
7
+ var row_order_1 = require("../row-order");
6
8
  var product_filter_fields_1 = require("../product-filter-fields");
7
9
  var table_access_guard_1 = require("./utils/table-access-guard");
8
10
  var request_sql_guards_1 = require("./utils/request-sql-guards");
9
11
  var array_overlap_sql_1 = require("../array-overlap-sql");
12
+ var pg_client_import_1 = require("./pg-client-import");
10
13
  var generatePostgreSQLFetcher = function (config, tableName, trustedReaderRoles) {
11
14
  var _a;
12
15
  if (trustedReaderRoles === void 0) { trustedReaderRoles = []; }
@@ -19,7 +22,7 @@ var generatePostgreSQLFetcher = function (config, tableName, trustedReaderRoles)
19
22
  : pgConfig.sslConfig
20
23
  ? "{\n ".concat(pgConfig.sslConfig.ca ? "ca: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.ca), ",") : '', "\n ").concat(pgConfig.sslConfig.cert ? "cert: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.cert), ",") : '', "\n ").concat(pgConfig.sslConfig.key ? "key: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.key), ",") : '', "\n rejectUnauthorized: false\n }")
21
24
  : '{ rejectUnauthorized: false }', "\n }");
22
- return "import { Client } from 'pg'\n\n".concat((0, table_access_guard_1.generateTableAccessPreamble)(trustedReaderRoles), "\n\nconst getClient = () => {\n return new Client(").concat(clientConfig, ")\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateFilterTreeHelpersCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n").concat((0, array_overlap_sql_1.generateArrayOverlapSqlCode)(), "\n\n// Builds one SQL clause for the whole filter tree, so an OR group nested in\n// the root AND keeps its meaning instead of being flattened into ANDs.\n").concat((0, request_sql_guards_1.generateRequestSqlGuardsCode)(), "\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const filterTree = normalizeFilterTree(safeJSONParse(filters))\n if (!filterTree) return paramIndex\n \n const buildCondition = (condition) => {\n const field = condition.source\n const normalizedCondition = normalizeInOperand(condition.operand, condition.destination)\n if (normalizedCondition === null) return null\n const value = normalizedCondition.value\n const operand = normalizedCondition.operand\n \n // The products table's virtual fields (effective price, rating bucket,\n // on-sale flag, variant axes) are whole clauses, not columns - so they are\n // answered before any branch below can interpolate the field name raw.\n const productClause = productFilterClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (productClause !== null) return productClause\n assertRequestColumn(field, 'filter field')\n \n if (Array.isArray(value)) {\n if (value.length === 0) return null\n if (operand === 'array_overlap') {\n // The row's list (see array-overlap-sql.ts) shares any value with the set.\n const clause = arrayOverlapSql([field], '$' + paramIndex)\n queryParams.push(value.map((entry) => String(entry)))\n paramIndex++\n return clause\n }\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n return operand === '!='\n ? `${field} NOT IN (${placeholders.join(', ')})`\n : `${field} IN (${placeholders.join(', ')})`\n }\n \n if (operand === 'array_overlap') {\n if (value === '' || value === null || value === undefined) return null\n // A single comma-joined string (the multi-select Category Filter's\n // ?categoryFilter=a,b,c) expands to multiple ids; one id stays one.\n const overlapValues = String(value).split(',').map((entry) => entry.trim()).filter(Boolean)\n if (overlapValues.length === 0) return null\n const clause = arrayOverlapSql([field], '$' + paramIndex)\n queryParams.push(overlapValues)\n paramIndex++\n return clause\n }\n \n if (value === null) {\n if (operand === '=') return `${field} IS NULL`\n if (operand === '!=') return `${field} IS NOT NULL`\n return null\n }\n \n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n const clause = `${field} ${sqlOperator} $${paramIndex}`\n queryParams.push(value)\n paramIndex++\n return clause\n }\n \n const clause = buildFilterTreeClause(filterTree, buildCondition)\n if (clause) conditions.push(clause)\n \n return paramIndex\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\n").concat((0, product_price_sort_1.generateSortFieldSqlHelper)(tableName), "\n\n").concat((0, product_price_sort_1.generateSortFallbackFieldHelper)(tableName), "\n\n").concat((0, product_filter_fields_1.generateProductFilterClauseHelper)(tableName), "\n\nexport default async function handler(req, res) {\n").concat((0, table_access_guard_1.generateReadGuardCall)(tableName, null), "\n const client = getClient()\n \n try {\n await client.connect()\n ").concat(schema ? "await client.query('SET search_path TO ".concat(schema, "')") : '', "\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n // A visitor never filters, sorts or searches by a column it is not served.\n if (__rowPolicy) __brpAssertVisibleFields(__rowPolicy, req.query)\n \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns. Wrap non-arrays so that a single\n // column passed as a bare string doesn't get iterated as chars.\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : [])\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const schemaQuery = `\n SELECT column_name\n FROM information_schema.columns\n WHERE table_name = $1\n ").concat(schema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = schema \n ? [").concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(schema), "]\n : [").concat(JSON.stringify(tableName), "]\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n columns = schemaResult.rows.map(row => row.column_name)\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n if (columns.length > 0) {\n const pattern = '%' + escapeLikePattern(query) + '%'\n const placeholder = '$' + paramIndex\n paramIndex++\n queryParams.push(pattern)\n const searchConditions = columns.map(\n (col) => '\"' + sanitizeSearchIdentifier(col) + '\"::text ILIKE ' + placeholder + \" ESCAPE '|'\"\n )\n conditions.push('(' + searchConditions.join(' OR ') + ')')\n }\n }\n\n // Apply filters using helper function\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n \n let sql = `SELECT * FROM \"").concat(tableName, "\"`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format. Two ORDER BY clauses are built: the one\n // actually used, and a plain-column twin kept only as the fallback below.\n let orderBySql = ''\n let plainOrderBySql = ''\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const valid = parsedSorts.filter((sort) => sort && sort.field)\n valid.forEach((sort) => assertRequestColumn(sort.field, 'sort field'))\n const orderOf = (sort) => (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const orderClauses = valid.map((sort) => `${sortFieldSql(sort.field)} ${orderOf(sort)}`)\n const plainClauses = valid.map((sort) => `${sortFallbackField(sort.field)} ${orderOf(sort)}`)\n\n if (orderClauses.length > 0) {\n // A deterministic tiebreaker keeps pagination stable: \"sort by\n // discount\" ties every undiscounted product at zero, and equal rows\n // with no defined order can repeat across pages or vanish between them.\n orderBySql = ` ORDER BY ${orderClauses.join(', ')}").concat((0, product_price_sort_1.generateSortTiebreakSql)(tableName), "`\n plainOrderBySql = ` ORDER BY ${plainClauses.join(', ')}").concat((0, product_price_sort_1.generateSortTiebreakSql)(tableName), "`\n }\n }\n } else if (sortBy) {\n assertRequestColumn(sortBy, 'sort field')\n orderBySql = ` ORDER BY ${sortBy} ${(sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'}`\n plainOrderBySql = orderBySql\n }\n const usedDiscountAwareSort = orderBySql !== plainOrderBySql\n\n const limitValue = requestRowCount(limit || perPage)\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n\n let sqlTail = ''\n if (limitValue !== undefined) {\n sqlTail += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sqlTail += ` OFFSET ${offsetValue}`\n }\n\n const baseSql = sql\n sql = baseSql + orderBySql + sqlTail\n \n // The discount-aware price ordering is an inline sub-select over a JSON\n // column. It is written to be unraisable, but it runs inside ORDER BY for\n // the whole table \u2014 so if a database ever rejects it, fall back to ordering\n // by the stored list price rather than serving an empty products page.\n let result\n try {\n result = await client.query(sql, queryParams)\n } catch (sortError) {\n if (!usedDiscountAwareSort) throw sortError\n console.warn(\n 'Discount-aware price sort failed; falling back to the list price:',\n sortError && sortError.message\n )\n result = await client.query(baseSql + plainOrderBySql + sqlTail, queryParams)\n }\n const rows = Array.isArray(result?.rows) ? result.rows : []\n const plainRows = rows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))\n\n return res.status(200).json({\n success: true,\n data: __taWithoutCredentials(\n __rowPolicy ? __brpStripHidden(__rowPolicy, safeData) : safeData,\n ").concat(JSON.stringify(tableName), "\n ),\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('PostgreSQL fetch error:', error)\n // A database error names tables, columns and values: it stays in the server\n // log. Only an error this route raised for the caller (it carries a status)\n // is repeated to it.\n return res.status(error.status || 500).json({\n success: false,\n error: error.status ? error.message : 'Failed to fetch data',\n timestamp: Date.now()\n })\n } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing PostgreSQL client:', error)\n }\n }\n }\n}\n");
25
+ return "".concat(pg_client_import_1.PG_CLIENT_IMPORT, "\n\n").concat((0, table_access_guard_1.generateTableAccessPreamble)(trustedReaderRoles), "\n\nconst getClient = () => {\n return new Client(").concat(clientConfig, ")\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateFilterTreeHelpersCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n").concat((0, array_overlap_sql_1.generateArrayOverlapSqlCode)(), "\n\n// Builds one SQL clause for the whole filter tree, so an OR group nested in\n// the root AND keeps its meaning instead of being flattened into ANDs.\n").concat((0, request_sql_guards_1.generateRequestSqlGuardsCode)(), "\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const filterTree = normalizeFilterTree(safeJSONParse(filters))\n if (!filterTree) return paramIndex\n \n const buildCondition = (condition) => {\n const field = condition.source\n const normalizedCondition = normalizeInOperand(condition.operand, condition.destination)\n if (normalizedCondition === null) return null\n const value = normalizedCondition.value\n const operand = normalizedCondition.operand\n \n // The products table's virtual fields (effective price, rating bucket,\n // on-sale flag, variant axes) are whole clauses, not columns - so they are\n // answered before any branch below can interpolate the field name raw.\n const productClause = productFilterClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (productClause !== null) return productClause\n assertRequestColumn(field, 'filter field')\n \n if (Array.isArray(value)) {\n if (value.length === 0) return null\n if (operand === 'array_overlap') {\n // The row's list (see array-overlap-sql.ts) shares any value with the set.\n const clause = arrayOverlapSql([field], '$' + paramIndex)\n queryParams.push(value.map((entry) => String(entry)))\n paramIndex++\n return clause\n }\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n return operand === '!='\n ? `${field} NOT IN (${placeholders.join(', ')})`\n : `${field} IN (${placeholders.join(', ')})`\n }\n \n if (operand === 'array_overlap') {\n if (value === '' || value === null || value === undefined) return null\n // A single comma-joined string (the multi-select Category Filter's\n // ?categoryFilter=a,b,c) expands to multiple ids; one id stays one.\n const overlapValues = String(value).split(',').map((entry) => entry.trim()).filter(Boolean)\n if (overlapValues.length === 0) return null\n const clause = arrayOverlapSql([field], '$' + paramIndex)\n queryParams.push(overlapValues)\n paramIndex++\n return clause\n }\n \n if (value === null) {\n if (operand === '=') return `${field} IS NULL`\n if (operand === '!=') return `${field} IS NOT NULL`\n return null\n }\n \n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n const clause = `${field} ${sqlOperator} $${paramIndex}`\n queryParams.push(value)\n paramIndex++\n return clause\n }\n \n const clause = buildFilterTreeClause(filterTree, buildCondition)\n if (clause) conditions.push(clause)\n \n return paramIndex\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\n").concat((0, product_price_sort_1.generateSortFieldSqlHelper)(tableName), "\n\n").concat((0, product_price_sort_1.generateSortFallbackFieldHelper)(tableName), "\n\n").concat((0, row_order_1.generateRowOrderTiebreakHelper)((0, row_order_1.rowIdentityColumn)(config, tableName)), "\n\n").concat((0, product_filter_fields_1.generateProductFilterClauseHelper)(tableName), "\n\nexport default async function handler(req, res) {\n").concat((0, table_access_guard_1.generateReadGuardCall)(tableName, null), "\n const client = getClient()\n \n try {\n await client.connect()\n ").concat(schema ? "await client.query('SET search_path TO ".concat(schema, "')") : '', "\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n // A visitor never filters, sorts or searches by a column it is not served.\n if (__rowPolicy) __brpAssertVisibleFields(__rowPolicy, req.query)\n \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns. Wrap non-arrays so that a single\n // column passed as a bare string doesn't get iterated as chars.\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : [])\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const schemaQuery = `\n SELECT column_name\n FROM information_schema.columns\n WHERE table_name = $1\n ").concat(schema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = schema \n ? [").concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(schema), "]\n : [").concat(JSON.stringify(tableName), "]\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n columns = schemaResult.rows.map(row => row.column_name)\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n if (columns.length > 0) {\n const pattern = '%' + escapeLikePattern(query) + '%'\n const placeholder = '$' + paramIndex\n paramIndex++\n queryParams.push(pattern)\n const searchConditions = columns.map(\n (col) => '\"' + sanitizeSearchIdentifier(col) + '\"::text ILIKE ' + placeholder + \" ESCAPE '|'\"\n )\n conditions.push('(' + searchConditions.join(' OR ') + ')')\n }\n }\n\n // Apply filters using helper function\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n \n let sql = `SELECT * FROM \"").concat(tableName, "\"`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format. Two ORDER BY clauses are built: the one\n // actually used (the products table's price rewrites, rows without a value\n // last), and a plain-column twin kept only as the fallback below.\n let orderBySql = ''\n let plainOrderBySql = ''\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const valid = parsedSorts.filter((sort) => sort && sort.field)\n valid.forEach((sort) => assertRequestColumn(sort.field, 'sort field'))\n const orderOf = (sort) => (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const orderClauses = valid.map((sort) => `${sortFieldSql(sort.field)} ${orderOf(sort)}").concat(list_sort_order_1.SORT_NULLS_LAST_SQL, "`)\n const plainClauses = valid.map((sort) => `${sortFallbackField(sort.field)} ${orderOf(sort)}`)\n\n if (orderClauses.length > 0) {\n // The row's own key last, so equal rows can't repeat across pages\n // or vanish between them.\n const tiebreak = rowOrderTiebreak(valid.map((sort) => sort.field), orderOf(valid[valid.length - 1]))\n orderBySql = ` ORDER BY ${orderClauses.join(', ')}${tiebreak}`\n plainOrderBySql = ` ORDER BY ${plainClauses.join(', ')}${tiebreak}`\n }\n }\n } else if (sortBy) {\n assertRequestColumn(sortBy, 'sort field')\n const sortByDirection = (sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const tiebreak = rowOrderTiebreak([sortBy], sortByDirection)\n orderBySql = ` ORDER BY ${sortBy} ${sortByDirection}").concat(list_sort_order_1.SORT_NULLS_LAST_SQL, "${tiebreak}`\n plainOrderBySql = ` ORDER BY ${sortBy} ${sortByDirection}${tiebreak}`\n }\n const usedRewrittenSort = orderBySql !== plainOrderBySql\n\n const limitValue = requestRowCount(limit || perPage)\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n\n let sqlTail = ''\n if (limitValue !== undefined) {\n sqlTail += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sqlTail += ` OFFSET ${offsetValue}`\n }\n\n const baseSql = sql\n sql = baseSql + orderBySql + sqlTail\n \n // The discount-aware price ordering is an inline sub-select over a JSON\n // column. It is written to be unraisable, but it runs inside ORDER BY for\n // the whole table \u2014 so if a database ever rejects it, fall back to ordering\n // by the stored list price rather than serving an empty products page. The\n // empty-values-last ordering takes the same exit, for a Postgres-compatible\n // database that does not know NULLS LAST.\n let result\n try {\n result = await client.query(sql, queryParams)\n } catch (sortError) {\n if (!usedRewrittenSort) throw sortError\n console.warn(\n 'Rewritten sort failed; falling back to the plain column:',\n sortError && sortError.message\n )\n result = await client.query(baseSql + plainOrderBySql + sqlTail, queryParams)\n }\n const rows = Array.isArray(result?.rows) ? result.rows : []\n const plainRows = rows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))\n\n return res.status(200).json({\n success: true,\n data: __taWithoutCredentials(\n __rowPolicy ? __brpStripHidden(__rowPolicy, safeData) : safeData,\n ").concat(JSON.stringify(tableName), "\n ),\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('PostgreSQL fetch error:', error)\n // A database error names tables, columns and values: it stays in the server\n // log. Only an error this route raised for the caller (it carries a status)\n // is repeated to it.\n return res.status(error.status || 500).json({\n success: false,\n error: error.status ? error.message : 'Failed to fetch data',\n timestamp: Date.now()\n })\n } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing PostgreSQL client:', error)\n }\n }\n }\n}\n");
23
26
  };
24
27
  exports.generatePostgreSQLFetcher = generatePostgreSQLFetcher;
25
28
  var generatePostgreSQLCountFetcher = function (config, tableName) {
@@ -1 +1 @@
1
- {"version":3,"file":"postgresql.js","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgresql.js","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"raw-query.d.ts","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"AA4BA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,SACxB,MAAM,eACA,MAAM,EAAE,KACpB,MA6IF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,UAC/B,MAAM;wBACU,MAAM;iBAAe,MAAM,EAAE;CAoCrD,CAAA"}
1
+ {"version":3,"file":"raw-query.d.ts","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,SACxB,MAAM,eACA,MAAM,EAAE,KACpB,MA6IF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,UAC/B,MAAM;wBACU,MAAM;iBAAe,MAAM,EAAE;CAoCrD,CAAA"}
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.parseQueryTemplateVariables = exports.generateRawQueryFetcher = void 0;
13
13
  var teleport_shared_1 = require("@teleporthq/teleport-shared");
14
14
  var utils_1 = require("../utils");
15
+ var pg_client_import_1 = require("./pg-client-import");
15
16
  var FORBIDDEN_KEYWORDS = ['CREATE', 'ALTER', 'DROP', 'TRUNCATE', 'RENAME', 'GRANT', 'REVOKE'];
16
17
  /** The param a `{{Current User.<field>}}` token becomes: `currentUser` + the field, capitalised. */
17
18
  var CURRENT_USER_PARAM_PREFIX = 'currentUser';
@@ -64,7 +65,7 @@ var generateRawQueryFetcher = function (config, query, paramFields) {
64
65
  ? "{\n ".concat(pgConfig.sslConfig.ca ? "ca: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.ca), ",") : '', "\n ").concat(pgConfig.sslConfig.cert ? "cert: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.cert), ",") : '', "\n ").concat(pgConfig.sslConfig.key ? "key: ".concat((0, utils_1.replaceSecretReference)(pgConfig.sslConfig.key), ",") : '', "\n rejectUnauthorized: false\n }")
65
66
  : '{ rejectUnauthorized: false }'
66
67
  : 'false';
67
- return "import { Client } from 'pg'\n\nconst FORBIDDEN_KEYWORDS = ".concat(JSON.stringify(FORBIDDEN_KEYWORDS), "\n").concat(sessionHelpers, "\nconst getClient = () => {\n const connStr = process.env.TELEPORT_DB_CONNECTION_STRING\n if (connStr) {\n const sslEnv = process.env.TELEPORT_DB_SSL\n const sslOpt = sslEnv === 'false' ? false : sslEnv === 'true' ? { rejectUnauthorized: false } : undefined\n return new Client(Object.assign({ connectionString: connStr }, sslOpt !== undefined ? { ssl: sslOpt } : {}))\n }\n return new Client({\n host: process.env.TELEPORT_DB_HOST || ").concat(JSON.stringify((_a = pgConfig.host) !== null && _a !== void 0 ? _a : null), ",\n port: parseInt(process.env.TELEPORT_DB_PORT || '").concat(pgConfig.port || 5432, "', 10),\n user: process.env.TELEPORT_DB_USER || ").concat(JSON.stringify((_c = (_b = pgConfig.user) !== null && _b !== void 0 ? _b : pgConfig.username) !== null && _c !== void 0 ? _c : null), ",\n password: process.env.TELEPORT_DB_PASSWORD || ").concat((0, utils_1.replaceSecretReference)(pgConfig.password) !== 'undefined'
68
+ return "".concat(pg_client_import_1.PG_CLIENT_IMPORT, "\n\nconst FORBIDDEN_KEYWORDS = ").concat(JSON.stringify(FORBIDDEN_KEYWORDS), "\n").concat(sessionHelpers, "\nconst getClient = () => {\n const connStr = process.env.TELEPORT_DB_CONNECTION_STRING\n if (connStr) {\n const sslEnv = process.env.TELEPORT_DB_SSL\n const sslOpt = sslEnv === 'false' ? false : sslEnv === 'true' ? { rejectUnauthorized: false } : undefined\n return new Client(Object.assign({ connectionString: connStr }, sslOpt !== undefined ? { ssl: sslOpt } : {}))\n }\n return new Client({\n host: process.env.TELEPORT_DB_HOST || ").concat(JSON.stringify((_a = pgConfig.host) !== null && _a !== void 0 ? _a : null), ",\n port: parseInt(process.env.TELEPORT_DB_PORT || '").concat(pgConfig.port || 5432, "', 10),\n user: process.env.TELEPORT_DB_USER || ").concat(JSON.stringify((_c = (_b = pgConfig.user) !== null && _b !== void 0 ? _b : pgConfig.username) !== null && _c !== void 0 ? _c : null), ",\n password: process.env.TELEPORT_DB_PASSWORD || ").concat((0, utils_1.replaceSecretReference)(pgConfig.password) !== 'undefined'
68
69
  ? (0, utils_1.replaceSecretReference)(pgConfig.password)
69
70
  : 'null', ",\n database: process.env.TELEPORT_DB_NAME || ").concat(JSON.stringify((_d = pgConfig.database) !== null && _d !== void 0 ? _d : null), ",\n ssl: ").concat(sslValue, "\n })\n}\n\nconst validateQuery = (query) => {\n const trimmed = query.trim().toUpperCase()\n for (const keyword of FORBIDDEN_KEYWORDS) {\n if (trimmed.startsWith(keyword)) {\n return false\n }\n }\n return true\n}\n\nexport default async function handler(req, res) {\n try {\n ").concat(paramDestructure, "\n ").concat(paramValidation, "\n\n const query = ").concat(JSON.stringify(query), "\n\n if (!validateQuery(query)) {\n return res.status(400).json({\n success: false,\n error: 'Only SELECT queries are allowed',\n timestamp: Date.now()\n })\n }\n\n const client = getClient()\n await client.connect()\n\n try {\n const result = await client.query(query, ").concat(paramArray, ")\n\n return res.status(200).json({\n success: true,\n data: result.rows,\n timestamp: Date.now()\n })\n } finally {\n await client.end()\n }\n } catch (error) {\n // A database error names tables, columns and values: server log only.\n console.error('Raw query fetch error:', error)\n return res.status(500).json({\n success: false,\n error: 'Failed to fetch data',\n timestamp: Date.now()\n })\n }\n}\n");
70
71
  };
@@ -1 +1 @@
1
- {"version":3,"file":"raw-query.js","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"raw-query.js","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../../src/fetchers/rest-api.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,qBAAqB,WACxB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA0BpC,CAAA;AAuED,eAAO,MAAM,sBAAsB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAyOxE,CAAA"}
1
+ {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../../src/fetchers/rest-api.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,qBAAqB,WACxB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA0BpC,CAAA;AAyED,eAAO,MAAM,sBAAsB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAyOxE,CAAA"}
@@ -35,7 +35,9 @@ var generateAuthCode = function (authorization) {
35
35
  var type = authorization.type, credentials = authorization.credentials;
36
36
  switch (type) {
37
37
  case 'api-key':
38
- return "headers['Authorization'] = 'ApiKey ".concat(credentials.apiKey, "'");
38
+ // The same header the editor's data fetcher sends, so a source that works
39
+ // on the canvas works on the live site.
40
+ return "headers['X-API-Key'] = '".concat(credentials.apiKey, "'");
39
41
  case 'bearer-token':
40
42
  case 'jwt-bearer':
41
43
  return "headers['Authorization'] = 'Bearer ".concat(credentials.token, "'");
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.js","sourceRoot":"","sources":["../../../src/fetchers/rest-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rest-api.js","sourceRoot":"","sources":["../../../src/fetchers/rest-api.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"teleport.d.ts","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAA;AA2C3B,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAMpC,CAAA;AAED,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,qBACC,sBAAsB,KACvC,MA2bF,CAAA;AAED,eAAO,MAAM,4BAA4B,WAC/B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8FF,CAAA"}
1
+ {"version":3,"file":"teleport.d.ts","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAA;AA0C3B,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAMpC,CAAA;AAED,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,qBACC,sBAAsB,KACvC,MA2bF,CAAA;AAED,eAAO,MAAM,4BAA4B,WAC/B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8FF,CAAA"}