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

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
@@ -1 +1 @@
1
- {"version":3,"file":"mongodb.js","sourceRoot":"","sources":["../../../src/fetchers/mongodb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mongodb.js","sourceRoot":"","sources":["../../../src/fetchers/mongodb.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mysql.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,oBAAoB,WACvB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8MF,CAAA;AAED,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA4EF,CAAA"}
1
+ {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mysql.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,oBAAoB,WACvB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAsNF,CAAA;AAED,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAkFF,CAAA"}
@@ -19,12 +19,12 @@ var generateMySQLFetcher = function (config, tableName) {
19
19
  : defaultSSLEnabled
20
20
  ? "{ rejectUnauthorized: true }"
21
21
  : 'false';
22
- return "import mysql from 'mysql2/promise'\n\nconst getConnection = () => {\n return mysql.createConnection({\n host: ".concat(JSON.stringify(mysqlConfig.host), ",\n port: ").concat(mysqlConfig.port || 3306, ",\n user: ").concat(resolvedUser !== null ? JSON.stringify(resolvedUser) : 'undefined', ",\n password: ").concat((0, utils_1.replaceSecretReference)(mysqlConfig.password), ",\n database: ").concat(JSON.stringify(mysqlConfig.database), ",\n ssl: ").concat(sslConfigString, "\n })\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n// Helper function to process filters and build conditions\nconst processFilters = (filters, conditions, queryParams) => {\n if (!filters) return\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = mysql.escapeId(filter.source)\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => '?').join(', ')\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders})`)\n } else {\n conditions.push(`${field} IN (${placeholders})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n // Validate operator to prevent SQL injection\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} ?`)\n queryParams.push(value)\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const placeholders = value.map(() => '?').join(', ')\n queryParams.push(...value)\n conditions.push(`${mysql.escapeId(key)} IN (${placeholders})`)\n } else {\n conditions.push(`${mysql.escapeId(key)} = ?`)\n queryParams.push(value)\n }\n })\n }\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n const connection = await getConnection()\n \n try {\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n const conditions = []\n const queryParams = []\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n columns = safeJSONParse(queryColumns)\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const [schemaRows] = await connection.query(\n `SELECT COLUMN_NAME FROM information_schema.COLUMNS \n WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? \n ORDER BY ORDINAL_POSITION`,\n [").concat(JSON.stringify(database), ", ").concat(JSON.stringify(tableName), "]\n )\n columns = schemaRows.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 \n if (columns.length > 0) {\n const searchConditions = columns.map((col) => `CAST(${mysql.escapeId(col)} AS CHAR) LIKE ?`)\n columns.forEach(() => queryParams.push(`%${query}%`))\n conditions.push(`(${searchConditions.join(' OR ')})`)\n }\n }\n \n // Apply filters using helper function\n processFilters(filters, conditions, queryParams)\n \n let sql = `SELECT * FROM ${mysql.escapeId('").concat(tableName, "')}`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = sort.order?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC'\n return `${mysql.escapeId(sort.field)} ${order}`\n }).filter(Boolean)\n \n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${mysql.escapeId(sortBy)} ${sortOrder?.toUpperCase() || 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const [rows] = await connection.query(sql, queryParams)\n const rowArray = Array.isArray(rows) ? rows : []\n const plainRows = rowArray.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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('MySQL 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 } finally {\n if (connection) {\n try {\n await connection.end()\n } catch (error) {\n console.error('Error closing MySQL connection:', error)\n }\n }\n }\n}\n");
22
+ return "import mysql from 'mysql2/promise'\n\nconst getConnection = () => {\n return mysql.createConnection({\n host: ".concat(JSON.stringify(mysqlConfig.host), ",\n port: ").concat(mysqlConfig.port || 3306, ",\n user: ").concat(resolvedUser !== null ? JSON.stringify(resolvedUser) : 'undefined', ",\n password: ").concat((0, utils_1.replaceSecretReference)(mysqlConfig.password), ",\n database: ").concat(JSON.stringify(mysqlConfig.database), ",\n ssl: ").concat(sslConfigString, "\n })\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n\n// Helper function to process filters and build conditions\nconst processFilters = (filters, conditions, queryParams) => {\n if (!filters) return\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = mysql.escapeId(filter.source)\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => '?').join(', ')\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders})`)\n } else {\n conditions.push(`${field} IN (${placeholders})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n // Validate operator to prevent SQL injection\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} ?`)\n queryParams.push(value)\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const placeholders = value.map(() => '?').join(', ')\n queryParams.push(...value)\n conditions.push(`${mysql.escapeId(key)} IN (${placeholders})`)\n } else {\n conditions.push(`${mysql.escapeId(key)} = ?`)\n queryParams.push(value)\n }\n })\n }\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n const connection = await getConnection()\n \n try {\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n const conditions = []\n const queryParams = []\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns. Wrap non-arrays so a single column\n // 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 [schemaRows] = await connection.query(\n `SELECT COLUMN_NAME FROM information_schema.COLUMNS \n WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? \n ORDER BY ORDINAL_POSITION`,\n [").concat(JSON.stringify(database), ", ").concat(JSON.stringify(tableName), "]\n )\n columns = schemaRows.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 \n if (columns.length > 0) {\n const pattern = \"%\" + escapeLikePattern(query) + \"%\"\n const searchConditions = columns.map(\n (col) =>\n \"LOWER(CAST(\" + mysql.escapeId(sanitizeSearchIdentifier(col)) + \" AS CHAR)) LIKE LOWER(?) ESCAPE '|'\"\n )\n columns.forEach(() => queryParams.push(pattern))\n conditions.push(\"(\" + searchConditions.join(\" OR \") + \")\")\n }\n }\n\n // Apply filters using helper function\n processFilters(filters, conditions, queryParams)\n \n let sql = `SELECT * FROM ${mysql.escapeId('").concat(tableName, "')}`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n return `${mysql.escapeId(sort.field)} ${order}`\n }).filter(Boolean)\n\n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${mysql.escapeId(sortBy)} ${(sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const [rows] = await connection.query(sql, queryParams)\n const rowArray = Array.isArray(rows) ? rows : []\n const plainRows = rowArray.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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('MySQL 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 } finally {\n if (connection) {\n try {\n await connection.end()\n } catch (error) {\n console.error('Error closing MySQL connection:', error)\n }\n }\n }\n}\n");
23
23
  };
24
24
  exports.generateMySQLFetcher = generateMySQLFetcher;
25
25
  var generateMySQLCountFetcher = function (config, tableName) {
26
26
  var mysqlConfig = config;
27
- return "\nasync function getCount(req, res) {\n const connection = await getConnection()\n\n try {\n const { query, queryColumns, filters } = req.query\n const conditions = []\n const queryParams = []\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const [schemaRows] = await connection.execute(\n `SELECT COLUMN_NAME FROM information_schema.COLUMNS \n WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? \n ORDER BY ORDINAL_POSITION`,\n [".concat(JSON.stringify(mysqlConfig.database), ", ").concat(JSON.stringify(tableName), "]\n )\n columns = schemaRows.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 \n if (columns.length > 0) {\n const searchConditions = columns.map(col => `CAST(${col} AS CHAR) LIKE ?`).join(' OR ')\n conditions.push(`(${searchConditions})`)\n columns.forEach(() => queryParams.push(`%${query}%`))\n }\n }\n\n // Apply filters using helper function\n processFilters(filters, conditions, queryParams)\n\n let countSql = `SELECT COUNT(*) as count FROM ").concat(tableName, "`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const [rows] = await connection.query(countSql, queryParams)\n const count = rows[0].count\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 } finally {\n if (connection) {\n try {\n await connection.end()\n } catch (error) {\n console.error('Error closing MySQL connection:', error)\n }\n }\n }\n}\n");
27
+ return "\nasync function getCount(req, res) {\n const connection = await getConnection()\n\n try {\n const { query, queryColumns, filters } = req.query\n const conditions = []\n const queryParams = []\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const [schemaRows] = await connection.execute(\n `SELECT COLUMN_NAME FROM information_schema.COLUMNS \n WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? \n ORDER BY ORDINAL_POSITION`,\n [".concat(JSON.stringify(mysqlConfig.database), ", ").concat(JSON.stringify(tableName), "]\n )\n columns = schemaRows.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 \n if (columns.length > 0) {\n const pattern = \"%\" + escapeLikePattern(query) + \"%\"\n const searchConditions = columns\n .map(\n (col) =>\n \"LOWER(CAST(\" + mysql.escapeId(sanitizeSearchIdentifier(col)) + \" AS CHAR)) LIKE LOWER(?) ESCAPE '|'\"\n )\n .join(\" OR \")\n conditions.push(\"(\" + searchConditions + \")\")\n columns.forEach(() => queryParams.push(pattern))\n }\n }\n\n // Apply filters using helper function\n processFilters(filters, conditions, queryParams)\n\n let countSql = `SELECT COUNT(*) as count FROM ").concat(tableName, "`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const [rows] = await connection.query(countSql, queryParams)\n const count = rows[0].count\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 } finally {\n if (connection) {\n try {\n await connection.end()\n } catch (error) {\n console.error('Error closing MySQL connection:', error)\n }\n }\n }\n}\n");
28
28
  };
29
29
  exports.generateMySQLCountFetcher = generateMySQLCountFetcher;
30
30
  //# sourceMappingURL=mysql.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../../src/fetchers/mysql.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAaV,IAAM,oBAAoB,GAAG,UAClC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAqB,CAAA;IACzC,IAAM,YAAY,GAAG,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,QAAQ,IAAI,IAAI,CAAA;IACrE,IAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,SAAS,CAAA;IAClD,IAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,KAAK,KAAK,CAAA;IACnD,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,IAAM,eAAe,GAAG,kBAAkB;QACxC,CAAC,CAAC,mBACE,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAE1F,WAAW,CAAC,SAAS,CAAC,IAAI;YACxB,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG;YAChE,CAAC,CAAC,EAAE,qBAGN,WAAW,CAAC,SAAS,CAAC,GAAG;YACvB,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG;YAC9D,CAAC,CAAC,EAAE,yCAGN,WAAW,CAAC,SAAS,CAAC,kBAAkB,KAAK,SAAS;YACpD,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,kBAAkB;YAC1C,CAAC,CAAC,IAAI,YAEV;QACF,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,OAAO,CAAA;IAEX,OAAO,4HAIG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,0BAChC,WAAW,CAAC,IAAI,IAAI,IAAI,0BACxB,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,8BAC9D,IAAA,8BAAsB,EAAC,WAAW,CAAC,QAAQ,CAAC,8BAC5C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,yBACzC,eAAe,0BAIxB,IAAA,iCAAyB,GAAE,q0DAuD3B,IAAA,iCAAyB,GAAE,qxBAwBd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,4uBAmBlB,SAAS,i9DAgE3D,CAAA;AACD,CAAC,CAAA;AAjNY,QAAA,oBAAoB,wBAiNhC;AAEM,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAqB,CAAA;IAEzC,OAAO,kwBAuBM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,qtBAmB5B,SAAS,ouBA8B7D,CAAA;AACD,CAAC,CAAA;AA/EY,QAAA,yBAAyB,6BA+ErC"}
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../../src/fetchers/mysql.ts"],"names":[],"mappings":";;;AAAA,kCAKiB;AAaV,IAAM,oBAAoB,GAAG,UAClC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAqB,CAAA;IACzC,IAAM,YAAY,GAAG,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,QAAQ,IAAI,IAAI,CAAA;IACrE,IAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,SAAS,CAAA;IAClD,IAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,KAAK,KAAK,CAAA;IACnD,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,IAAM,eAAe,GAAG,kBAAkB;QACxC,CAAC,CAAC,mBACE,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAE1F,WAAW,CAAC,SAAS,CAAC,IAAI;YACxB,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG;YAChE,CAAC,CAAC,EAAE,qBAGN,WAAW,CAAC,SAAS,CAAC,GAAG;YACvB,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG;YAC9D,CAAC,CAAC,EAAE,yCAGN,WAAW,CAAC,SAAS,CAAC,kBAAkB,KAAK,SAAS;YACpD,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,kBAAkB;YAC1C,CAAC,CAAC,IAAI,YAEV;QACF,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,OAAO,CAAA;IAEX,OAAO,4HAIG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,0BAChC,WAAW,CAAC,IAAI,IAAI,IAAI,0BACxB,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,8BAC9D,IAAA,8BAAsB,EAAC,WAAW,CAAC,QAAQ,CAAC,8BAC5C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,yBACzC,eAAe,0BAIxB,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,uCAA+B,GAAE,q0DAuDjC,IAAA,iCAAyB,GAAE,88BA0Bd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,+4BAuBlB,SAAS,0/DAgE3D,CAAA;AACD,CAAC,CAAA;AAzNY,QAAA,oBAAoB,wBAyNhC;AAEM,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAqB,CAAA;IAEzC,OAAO,kwBAuBM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,46BAyB5B,SAAS,ouBA8B7D,CAAA;AACD,CAAC,CAAA;AArFY,QAAA,yBAAyB,6BAqFrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAsNF,CAAA;AAED,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAuFF,CAAA"}
1
+ {"version":3,"file":"postgresql.d.ts","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA2NF,CAAA;AAED,eAAO,MAAM,8BAA8B,WACjC,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8FF,CAAA"}
@@ -13,7 +13,7 @@ var generatePostgreSQLFetcher = function (config, tableName) {
13
13
  : pgConfig.sslConfig
14
14
  ? "{\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 }")
15
15
  : '{ rejectUnauthorized: false }', "\n }");
16
- return "import { Client } from 'pg'\n\nconst getClient = () => {\n return new Client(".concat(clientConfig, ")\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n// Helper function to process filters and build conditions\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = filter.source\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n conditions.push(`${key} IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${key} = $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n })\n }\n \n return paramIndex\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\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 \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\n columns = safeJSONParse(queryColumns)\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 \n if (columns.length > 0) {\n const searchConditions = columns.map((col) => {\n const condition = `${col}::text ILIKE $${paramIndex}`\n paramIndex++\n return condition\n })\n columns.forEach(() => queryParams.push(`%${query}%`))\n conditions.push(`(${searchConditions.join(' OR ')})`)\n }\n }\n \n // Apply filters using helper function\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\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\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = sort.order?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC'\n return `${sort.field} ${order}`\n }).filter(Boolean)\n \n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${sortBy} ${sortOrder?.toUpperCase() || 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const result = await client.query(sql, queryParams)\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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('PostgreSQL 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 } 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");
16
+ return "import { Client } from 'pg'\n\nconst getClient = () => {\n return new Client(".concat(clientConfig, ")\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n\n// Helper function to process filters and build conditions\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = filter.source\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n conditions.push(`${key} IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${key} = $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n })\n }\n \n return paramIndex\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\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 \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 \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 \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\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n return `${sort.field} ${order}`\n }).filter(Boolean)\n\n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${sortBy} ${(sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const result = await client.query(sql, queryParams)\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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('PostgreSQL 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 } 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");
17
17
  };
18
18
  exports.generatePostgreSQLFetcher = generatePostgreSQLFetcher;
19
19
  var generatePostgreSQLCountFetcher = function (config, tableName) {
@@ -22,7 +22,7 @@ var generatePostgreSQLCountFetcher = function (config, tableName) {
22
22
  var hasSchema = !!((_a = pgConfig.options) === null || _a === void 0 ? void 0 : _a.schema);
23
23
  return "\nasync function getCount(req, res) {\n const client = getClient()\n\n try {\n await client.connect()\n const { query, queryColumns, filters } = req.query\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\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(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(hasSchema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = ").concat(hasSchema
24
24
  ? "[".concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(pgConfig.options.schema), "]")
25
- : "[".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 \n if (columns.length > 0) {\n const searchConditions = columns.map(col => `${col}::text ILIKE $${paramIndex++}`).join(' OR ')\n conditions.push(`(${searchConditions})`)\n columns.forEach(() => queryParams.push(`%${query}%`))\n }\n }\n\n // Apply filters using helper function\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n\n let countSql = `SELECT COUNT(*) FROM \"").concat(tableName, "\"`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const result = await client.query(countSql, queryParams)\n const count = parseInt(result.rows[0].count, 10)\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 } 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
+ : "[".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 \n if (columns.length > 0) {\n const pattern = '%' + escapeLikePattern(query) + '%'\n const placeholder = '$' + paramIndex\n paramIndex++\n queryParams.push(pattern)\n const searchConditions = columns\n .map(\n (col) => '\"' + sanitizeSearchIdentifier(col) + '\"::text ILIKE ' + placeholder + \" ESCAPE '|'\"\n )\n .join(' OR ')\n conditions.push('(' + searchConditions + ')')\n }\n }\n\n // Apply filters using helper function\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n\n let countSql = `SELECT COUNT(*) FROM \"").concat(tableName, "\"`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const result = await client.query(countSql, queryParams)\n const count = parseInt(result.rows[0].count, 10)\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 } 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");
26
26
  };
27
27
  exports.generatePostgreSQLCountFetcher = generatePostgreSQLCountFetcher;
28
28
  //# sourceMappingURL=postgresql.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgresql.js","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAeV,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,IAAM,MAAM,GAAG,MAAA,QAAQ,CAAC,OAAO,0CAAE,MAAM,CAAA;IAEvC,IAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB;QAC5C,CAAC,CAAC,mCACkB,IAAA,8BAAsB,EAAC,QAAQ,CAAC,gBAAgB,CAAC,WACrE;QACA,CAAC,CAAC,uBACM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,0BAC7B,QAAQ,CAAC,IAAI,IAAI,IAAI,0BACrB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,8BAC9C,IAAA,8BAAsB,EAAC,QAAQ,CAAC,QAAQ,CAAC,8BACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,yBAE3C,QAAQ,CAAC,GAAG,KAAK,KAAK;YACpB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,QAAQ,CAAC,SAAS;gBACpB,CAAC,CAAC,mBACF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACpF,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAC1F,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,6CAEzF;gBACE,CAAC,CAAC,+BAA+B,UAErC,CAAA;IAEF,OAAO,wFAGa,YAAY,qBAGhC,IAAA,iCAAyB,GAAE,63DA0D3B,IAAA,iCAAyB,GAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,0nBAqB1D,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,0HAIlC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,+BACpD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,65BAwBT,SAAS,i7DAgEzC,CAAA;AACD,CAAC,CAAA;AAzNY,QAAA,yBAAyB,6BAyNrC;AAEM,IAAM,8BAA8B,GAAG,UAC5C,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,IAAM,SAAS,GAAG,CAAC,CAAC,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,MAAM,CAAA,CAAA;IAE5C,OAAO,2tBAyBK,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,kGAI1C,SAAS;QACP,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAQ,CAAC,MAAM,CAAC,MAAG;QAC/E,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,k0BAqBH,SAAS,gvBA8BrD,CAAA;AACD,CAAC,CAAA;AA1FY,QAAA,8BAA8B,kCA0F1C"}
1
+ {"version":3,"file":"postgresql.js","sourceRoot":"","sources":["../../../src/fetchers/postgresql.ts"],"names":[],"mappings":";;;AAAA,kCAKiB;AAeV,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,IAAM,MAAM,GAAG,MAAA,QAAQ,CAAC,OAAO,0CAAE,MAAM,CAAA;IAEvC,IAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB;QAC5C,CAAC,CAAC,mCACkB,IAAA,8BAAsB,EAAC,QAAQ,CAAC,gBAAgB,CAAC,WACrE;QACA,CAAC,CAAC,uBACM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,0BAC7B,QAAQ,CAAC,IAAI,IAAI,IAAI,0BACrB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,8BAC9C,IAAA,8BAAsB,EAAC,QAAQ,CAAC,QAAQ,CAAC,8BACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,yBAE3C,QAAQ,CAAC,GAAG,KAAK,KAAK;YACpB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,QAAQ,CAAC,SAAS;gBACpB,CAAC,CAAC,mBACF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACpF,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAC1F,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,6CAEzF;gBACE,CAAC,CAAC,+BAA+B,UAErC,CAAA;IAEF,OAAO,wFAGa,YAAY,qBAGhC,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,uCAA+B,GAAE,63DA0DjC,IAAA,iCAAyB,GAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,szBAuB1D,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,0HAIlC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,+BACpD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,i/BAyBT,SAAS,09DAgEzC,CAAA;AACD,CAAC,CAAA;AA9NY,QAAA,yBAAyB,6BA8NrC;AAEM,IAAM,8BAA8B,GAAG,UAC5C,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,IAAM,SAAS,GAAG,CAAC,CAAC,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,MAAM,CAAA,CAAA;IAE5C,OAAO,2tBAyBK,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,kGAI1C,SAAS;QACP,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAQ,CAAC,MAAM,CAAC,MAAG;QAC/E,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,ohCA4BH,SAAS,gvBA8BrD,CAAA;AACD,CAAC,CAAA;AAjGY,QAAA,8BAA8B,kCAiG1C"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Generates an API route handler that executes a parameterized raw SQL query.
3
+ * Supports {{Current User.*}} substitution via query params.
4
+ *
5
+ * @param config - PostgreSQL connection config
6
+ * @param query - Raw SQL query string with {{Current User.*}} patterns already replaced to $N placeholders
7
+ * @param paramFields - Array of query param field names that map to $1, $2, etc. in order
8
+ */
9
+ export declare const generateRawQueryFetcher: (config: Record<string, unknown>, query: string, paramFields: string[]) => string;
10
+ /**
11
+ * Parses a SQL query string for {{Current User.*}} template patterns.
12
+ * Returns the parameterized query and an ordered list of field names.
13
+ */
14
+ export declare const parseQueryTemplateVariables: (query: string) => {
15
+ parameterizedQuery: string;
16
+ paramFields: string[];
17
+ };
18
+ //# sourceMappingURL=raw-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-query.d.ts","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"AAeA;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,SACxB,MAAM,eACA,MAAM,EAAE,KACpB,MA0GF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,UAC/B,MAAM;wBACU,MAAM;iBAAe,MAAM,EAAE;CAoCrD,CAAA"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseQueryTemplateVariables = exports.generateRawQueryFetcher = void 0;
4
+ var utils_1 = require("../utils");
5
+ var FORBIDDEN_KEYWORDS = ['CREATE', 'ALTER', 'DROP', 'TRUNCATE', 'RENAME', 'GRANT', 'REVOKE'];
6
+ /**
7
+ * Generates an API route handler that executes a parameterized raw SQL query.
8
+ * Supports {{Current User.*}} substitution via query params.
9
+ *
10
+ * @param config - PostgreSQL connection config
11
+ * @param query - Raw SQL query string with {{Current User.*}} patterns already replaced to $N placeholders
12
+ * @param paramFields - Array of query param field names that map to $1, $2, etc. in order
13
+ */
14
+ var generateRawQueryFetcher = function (config, query, paramFields) {
15
+ var _a, _b, _c, _d;
16
+ var pgConfig = config;
17
+ var paramDestructure = paramFields.length > 0 ? "const { ".concat(paramFields.join(', '), " } = req.query") : '';
18
+ var paramValidation = paramFields.length > 0
19
+ ? "\n if (".concat(paramFields.map(function (f) { return "!".concat(f); }).join(' || '), ") {\n return res.status(200).json({ success: true, data: [], timestamp: Date.now() })\n }")
20
+ : '';
21
+ var paramArray = paramFields.length > 0 ? "[".concat(paramFields.join(', '), "]") : '[]';
22
+ var sslValue = pgConfig.ssl === false
23
+ ? 'false'
24
+ : pgConfig.ssl === true || pgConfig.sslConfig
25
+ ? pgConfig.sslConfig
26
+ ? "{\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 }")
27
+ : '{ rejectUnauthorized: false }'
28
+ : 'false';
29
+ return "import { Client } from 'pg'\n\nconst FORBIDDEN_KEYWORDS = ".concat(JSON.stringify(FORBIDDEN_KEYWORDS), "\n\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'
30
+ ? (0, utils_1.replaceSecretReference)(pgConfig.password)
31
+ : '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 console.error('Raw query 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");
32
+ };
33
+ exports.generateRawQueryFetcher = generateRawQueryFetcher;
34
+ /**
35
+ * Parses a SQL query string for {{Current User.*}} template patterns.
36
+ * Returns the parameterized query and an ordered list of field names.
37
+ */
38
+ var parseQueryTemplateVariables = function (query) {
39
+ var captureRe = /\{\{Current User\.(\w+)\}\}/g;
40
+ var paramFields = [];
41
+ // First pass: collect unique fields in order
42
+ var tempRe = new RegExp(captureRe.source, 'g');
43
+ var match = tempRe.exec(query);
44
+ while (match !== null) {
45
+ var field = match[1];
46
+ if (!paramFields.includes(field)) {
47
+ paramFields.push(field);
48
+ }
49
+ match = tempRe.exec(query);
50
+ }
51
+ // Second pass: replace patterns with $N placeholders
52
+ var parameterizedQuery = query;
53
+ for (var i = 0; i < paramFields.length; i++) {
54
+ var field = paramFields[i];
55
+ // Replace both quoted ('{{...}}') and unquoted ({{...}}) variants
56
+ var quotedPattern = "'{{Current User.".concat(field, "}}'");
57
+ var unquotedPattern = "{{Current User.".concat(field, "}}");
58
+ if (parameterizedQuery.includes(quotedPattern)) {
59
+ parameterizedQuery = parameterizedQuery.split(quotedPattern).join("$".concat(i + 1));
60
+ }
61
+ else {
62
+ parameterizedQuery = parameterizedQuery.split(unquotedPattern).join("$".concat(i + 1));
63
+ }
64
+ }
65
+ // Convert field names to camelCase query param names
66
+ var queryParamNames = paramFields.map(function (f) { return "currentUser".concat(f.charAt(0).toUpperCase() + f.slice(1)); });
67
+ return { parameterizedQuery: parameterizedQuery, paramFields: queryParamNames };
68
+ };
69
+ exports.parseQueryTemplateVariables = parseQueryTemplateVariables;
70
+ //# sourceMappingURL=raw-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-query.js","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@ var generateRedisFetcher = function (config) {
40
40
  if (!connectionString) {
41
41
  connectionString = "redis://".concat(hasUsername ? "".concat(username, ":").concat(password, "@") : '').concat(host, ":").concat(port || 6379);
42
42
  }
43
- return "import { createClient } from 'redis'\n\n".concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n let client = null\n try {\n client = createClient({\n url: ").concat((0, utils_1.replaceSecretReference)(connectionString)).concat(database ? ",\n database: ".concat(database) : '', "\n })\n \n await client.connect()\n \n const { query, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n let pattern = query || '*'\n \n // Extract pattern from filters if available (new format)\n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n if (Array.isArray(parsedFilters)) {\n const patternFilter = parsedFilters.find(f => f.source === 'pattern')\n if (patternFilter) {\n pattern = patternFilter.destination || pattern\n }\n } else {\n pattern = parsedFilters.pattern || pattern\n }\n }\n \n const keys = await client.keys(pattern)\n \n const limitValue = limit || perPage || 100\n const skipValue = offset !== undefined ? parseInt(offset) : ((parseInt(page) || 1) - 1) * parseInt(limitValue)\n const paginatedKeys = keys.slice(skipValue, skipValue + parseInt(limitValue))\n \n const results = []\n for (const key of paginatedKeys) {\n const type = await client.type(key)\n const ttl = await client.ttl(key)\n let value\n \n switch (type) {\n case 'string':\n value = await client.get(key)\n break\n case 'list':\n value = await client.lRange(key, 0, -1)\n break\n case 'set':\n value = await client.sMembers(key)\n break\n case 'zset':\n value = await client.zRange(key, 0, -1)\n break\n case 'hash':\n value = await client.hGetAll(key)\n break\n default:\n value = null\n }\n \n results.push({\n key,\n type,\n value,\n ttl: ttl === -1 ? null : ttl\n })\n }\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const primarySort = parsedSorts[0]\n if (primarySort.field) {\n const sortOrderValue = primarySort.order?.toLowerCase() === 'desc' ? -1 : 1\n results.sort((a, b) => {\n const aVal = a[primarySort.field]\n const bVal = b[primarySort.field]\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n }\n } else if (sortBy) {\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n results.sort((a, b) => {\n const aVal = a[sortBy]\n const bVal = b[sortBy]\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n \n const safeData = JSON.parse(JSON.stringify(results, 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('Redis 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 } finally {\n if (client) {\n await client.quit()\n }\n }\n}\n");
43
+ return "import { createClient } from 'redis'\n\n".concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n let client = null\n try {\n client = createClient({\n url: ").concat((0, utils_1.replaceSecretReference)(connectionString)).concat(database ? ",\n database: ".concat(database) : '', "\n })\n \n await client.connect()\n \n const { query, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n let pattern = query || '*'\n \n // Extract pattern from filters if available (new format)\n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n if (Array.isArray(parsedFilters)) {\n const patternFilter = parsedFilters.find(f => f.source === 'pattern')\n if (patternFilter) {\n pattern = patternFilter.destination || pattern\n }\n } else {\n pattern = parsedFilters.pattern || pattern\n }\n }\n \n const keys = await client.keys(pattern)\n \n const limitValue = limit || perPage || 100\n const skipValue = offset !== undefined ? parseInt(offset) : ((parseInt(page) || 1) - 1) * parseInt(limitValue)\n const paginatedKeys = keys.slice(skipValue, skipValue + parseInt(limitValue))\n \n const results = []\n for (const key of paginatedKeys) {\n const type = await client.type(key)\n const ttl = await client.ttl(key)\n let value\n \n switch (type) {\n case 'string':\n value = await client.get(key)\n break\n case 'list':\n value = await client.lRange(key, 0, -1)\n break\n case 'set':\n value = await client.sMembers(key)\n break\n case 'zset':\n value = await client.zRange(key, 0, -1)\n break\n case 'hash':\n value = await client.hGetAll(key)\n break\n default:\n value = null\n }\n \n results.push({\n key,\n type,\n value,\n ttl: ttl === -1 ? null : ttl\n })\n }\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const primarySort = parsedSorts[0]\n if (primarySort.field) {\n const sortOrderValue = (primarySort.order || '').toLowerCase().startsWith('desc') ? -1 : 1\n results.sort((a, b) => {\n const aVal = a[primarySort.field]\n const bVal = b[primarySort.field]\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n }\n } else if (sortBy) {\n const sortOrderValue = (sortOrder || '').toLowerCase().startsWith('desc') ? -1 : 1\n results.sort((a, b) => {\n const aVal = a[sortBy]\n const bVal = b[sortBy]\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n \n const safeData = JSON.parse(JSON.stringify(results, 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('Redis 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 } finally {\n if (client) {\n await client.quit()\n }\n }\n}\n");
44
44
  };
45
45
  exports.generateRedisFetcher = generateRedisFetcher;
46
46
  //# sourceMappingURL=redis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/fetchers/redis.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,IAAM,mBAAmB,GAAG,UACjC,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,+CAA+C;IAC/C,IAAI,MAAM,CAAC,gBAAgB,EAAE;QAC3B,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACxF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAA;SACjF;QAED,uFAAuF;QACvF,IAAM,OAAO,GAAG,MAAM,CAAC,gBAA0B,CAAA;QACjD,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC;YAC1C,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;YAC/B,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,EAChC;YACA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAA;SAC3E;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;KACzB;IAED,kEAAkE;IAClE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;QACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8DAA8D,EAAE,CAAA;KACjG;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAhCY,QAAA,mBAAmB,uBAgC/B;AAYM,IAAM,oBAAoB,GAAG,UAAC,MAA+B;IAClE,IAAM,WAAW,GAAG,MAAqB,CAAA;IACzC,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAA;IAC7B,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAA;IAC7B,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,WAAW,GAAG,QAAQ,CAAA;IAE5B,qDAAqD;IACrD,IAAI,gBAAgB,GAAG,WAAW,CAAC,gBAAgB,CAAA;IACnD,IAAI,CAAC,gBAAgB,EAAE;QACrB,gBAAgB,GAAG,kBAAW,WAAW,CAAC,CAAC,CAAC,UAAG,QAAQ,cAAI,QAAQ,MAAG,CAAC,CAAC,CAAC,EAAE,SAAG,IAAI,cAChF,IAAI,IAAI,IAAI,CACZ,CAAA;KACH;IAED,OAAO,kDAEP,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,0IAMhB,IAAA,8BAAsB,EAAC,gBAAgB,CAAC,SACjD,QAAQ,CAAC,CAAC,CAAC,6BAAsB,QAAQ,CAAE,CAAC,CAAC,CAAC,EAAE,8oGA8GnD,CAAA;AACD,CAAC,CAAA;AA3IY,QAAA,oBAAoB,wBA2IhC"}
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/fetchers/redis.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,IAAM,mBAAmB,GAAG,UACjC,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,+CAA+C;IAC/C,IAAI,MAAM,CAAC,gBAAgB,EAAE;QAC3B,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACxF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAA;SACjF;QAED,uFAAuF;QACvF,IAAM,OAAO,GAAG,MAAM,CAAC,gBAA0B,CAAA;QACjD,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC;YAC1C,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;YAC/B,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,EAChC;YACA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAA;SAC3E;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;KACzB;IAED,kEAAkE;IAClE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;QACnD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8DAA8D,EAAE,CAAA;KACjG;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAhCY,QAAA,mBAAmB,uBAgC/B;AAYM,IAAM,oBAAoB,GAAG,UAAC,MAA+B;IAClE,IAAM,WAAW,GAAG,MAAqB,CAAA;IACzC,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAA;IAC7B,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAA;IAC7B,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,WAAW,GAAG,QAAQ,CAAA;IAE5B,qDAAqD;IACrD,IAAI,gBAAgB,GAAG,WAAW,CAAC,gBAAgB,CAAA;IACnD,IAAI,CAAC,gBAAgB,EAAE;QACrB,gBAAgB,GAAG,kBAAW,WAAW,CAAC,CAAC,CAAC,UAAG,QAAQ,cAAI,QAAQ,MAAG,CAAC,CAAC,CAAC,EAAE,SAAG,IAAI,cAChF,IAAI,IAAI,IAAI,CACZ,CAAA;KACH;IAED,OAAO,kDAEP,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,0IAMhB,IAAA,8BAAsB,EAAC,gBAAgB,CAAC,SACjD,QAAQ,CAAC,CAAC,CAAC,6BAAsB,QAAQ,CAAE,CAAC,CAAC,CAAC,EAAE,4qGA8GnD,CAAA;AACD,CAAC,CAAA;AA3IY,QAAA,oBAAoB,wBA2IhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"redshift.d.ts","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAqNF,CAAA"}
1
+ {"version":3,"file":"redshift.d.ts","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAwNF,CAAA"}
@@ -18,9 +18,9 @@ var generateRedshiftFetcher = function (config, tableName) {
18
18
  : sslConfig
19
19
  ? "{\n ".concat(sslConfig.ca ? "ca: ".concat((0, utils_1.replaceSecretReference)(sslConfig.ca), ",") : '', "\n ").concat(sslConfig.cert ? "cert: ".concat((0, utils_1.replaceSecretReference)(sslConfig.cert), ",") : '', "\n ").concat(sslConfig.key ? "key: ".concat((0, utils_1.replaceSecretReference)(sslConfig.key), ",") : '', "\n rejectUnauthorized: ").concat(sslConfig.rejectUnauthorized !== false, "\n }")
20
20
  : '{ rejectUnauthorized: false }' // Default to SSL with no cert verification for Redshift
21
- , "\n })\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\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 \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const schemaQuery = 'SELECT column_name FROM information_schema.columns WHERE table_name = $1' + \n ").concat(schema ? "' AND table_schema = $2'" : "''", " + \n ' ORDER BY ordinal_position'\n const schemaParams = ").concat(schema
21
+ , "\n })\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\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 \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get all columns from information_schema\n try {\n const schemaQuery = 'SELECT column_name FROM information_schema.columns WHERE table_name = $1' + \n ").concat(schema ? "' AND table_schema = $2'" : "''", " + \n ' ORDER BY ordinal_position'\n const schemaParams = ").concat(schema
22
22
  ? "[".concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(schema), "]")
23
- : "[".concat(JSON.stringify(tableName), "]"), "\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 }\n }\n \n if (columns.length > 0) {\n const searchConditions = columns.map((col) => {\n const condition = `${col}::text ILIKE $${paramIndex}`\n paramIndex++\n return condition\n })\n columns.forEach(() => queryParams.push(`%${query}%`))\n conditions.push(`(${searchConditions.join(' OR ')})`)\n }\n }\n \n // Helper to sanitize identifier (prevent SQL injection in column names)\n const sanitizeIdentifier = (name) => {\n // Only allow alphanumeric, underscore, and dot (for schema.table)\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n throw new Error(`Invalid identifier: ${name}`)\n }\n return `\"${name}\"`\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = sanitizeIdentifier(filter.source)\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n const field = sanitizeIdentifier(key)\n if (Array.isArray(value)) {\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} = $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n })\n }\n }\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\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = sort.order?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC'\n return `${sanitizeIdentifier(sort.field)} ${order}`\n }).filter(Boolean)\n \n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${sanitizeIdentifier(sortBy)} ${sortOrder?.toUpperCase() || 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const result = await client.query(sql, queryParams)\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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Redshift 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 } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing Redshift client:', error)\n }\n }\n }\n}\n");
23
+ : "[".concat(JSON.stringify(tableName), "]"), "\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 }\n }\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 // Helper to sanitize identifier (prevent SQL injection in column names)\n const sanitizeIdentifier = (name) => {\n // Only allow alphanumeric, underscore, and dot (for schema.table)\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n throw new Error(`Invalid identifier: ${name}`)\n }\n return `\"${name}\"`\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = sanitizeIdentifier(filter.source)\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n }\n } else {\n if (value === null) {\n if (operand === '=') {\n conditions.push(`${field} IS NULL`)\n } else if (operand === '!=') {\n conditions.push(`${field} IS NOT NULL`)\n }\n } else {\n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n conditions.push(`${field} ${sqlOperator} $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n const field = sanitizeIdentifier(key)\n if (Array.isArray(value)) {\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n conditions.push(`${field} IN (${placeholders.join(', ')})`)\n } else {\n conditions.push(`${field} = $${paramIndex}`)\n queryParams.push(value)\n paramIndex++\n }\n })\n }\n }\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\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const orderClauses = parsedSorts.map((sort) => {\n if (!sort.field) return null\n const order = (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n return `${sanitizeIdentifier(sort.field)} ${order}`\n }).filter(Boolean)\n\n if (orderClauses.length > 0) {\n sql += ` ORDER BY ${orderClauses.join(', ')}`\n }\n }\n } else if (sortBy) {\n sql += ` ORDER BY ${sanitizeIdentifier(sortBy)} ${(sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'}`\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (limitValue) {\n sql += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sql += ` OFFSET ${offsetValue}`\n }\n \n const result = await client.query(sql, queryParams)\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: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Redshift 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 } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing Redshift client:', error)\n }\n }\n }\n}\n");
24
24
  };
25
25
  exports.generateRedshiftFetcher = generateRedshiftFetcher;
26
26
  //# sourceMappingURL=redshift.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redshift.js","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAaV,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;IAC9B,IAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;IAC1C,IAAM,MAAM,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,MAAM,CAAA;IAE7C,OAAO,qGAIG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BACpB,IAAI,IAAI,IAAI,0BACZ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAChB,IAAA,8BAAsB,EAAC,QAAQ,CAAC,8BAChC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,yBAElC,GAAG,KAAK,KAAK;QACX,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,mBACF,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAClE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACxE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,yCACjD,SAAS,CAAC,kBAAkB,KAAK,KAAK,YAC5D;YACE,CAAC,CAAC,+BAA+B,CAAC,wDAAwD;8BAKhG,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,onBAkB1D,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,2FAG5C,MAAM;QACJ,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAG;QAC7D,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,2/FAiFhB,SAAS,m9DAgExC,CAAA;AACD,CAAC,CAAA;AAxNY,QAAA,uBAAuB,2BAwNnC"}
1
+ {"version":3,"file":"redshift.js","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":";;;AAAA,kCAKiB;AAaV,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;IAC9B,IAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;IAC1C,IAAM,MAAM,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,MAAM,CAAA;IAE7C,OAAO,qGAIG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BACpB,IAAI,IAAI,IAAI,0BACZ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAChB,IAAA,8BAAsB,EAAC,QAAQ,CAAC,8BAChC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,yBAElC,GAAG,KAAK,KAAK;QACX,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,mBACF,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,IAAA,8BAAsB,EAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAClE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,IAAA,8BAAsB,EAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACxE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,IAAA,8BAAsB,EAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,yCACjD,SAAS,CAAC,kBAAkB,KAAK,KAAK,YAC5D;YACE,CAAC,CAAC,+BAA+B,CAAC,wDAAwD;8BAKhG,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,uCAA+B,GAAE,iBAEjC,IAAA,iCAAyB,GAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,onBAkB1D,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,2FAG5C,MAAM;QACJ,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAG;QAC7D,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,mlGAkFhB,SAAS,4/DAgExC,CAAA;AACD,CAAC,CAAA;AA3NY,QAAA,uBAAuB,2BA2NnC"}
@@ -53,7 +53,7 @@ var generateRESTAPIFetcher = function (config) {
53
53
  ? "\n if (req.body) {\n options.body = ".concat(restConfig.bodyType === 'json' || !restConfig.bodyType
54
54
  ? 'JSON.stringify(req.body)'
55
55
  : 'req.body', "\n }\n ")
56
- : '', "\n \n const response = await fetch(url, options)\n \n if (!response.ok) {\n return res.status(response.status).json({\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n timestamp: Date.now()\n })\n }\n \n let data = await response.json()\n \n if (Array.isArray(data)) {\n if (query && query.trim()) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n try {\n const parsed = safeJSONParse(queryColumns)\n const columns = Array.isArray(parsed) ? parsed : [parsed]\n data = data.filter((item) => {\n return columns.some((col) => {\n const value = getNestedValue(item, col)\n if (value === null || value === undefined) return false\n return String(value).toLowerCase().includes(searchQuery)\n })\n })\n } catch (err) {\n console.error('Error parsing queryColumns:', err)\n }\n } else {\n data = data.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 try {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n data = data.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 data = data.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 } catch (err) {\n console.error('Error parsing filters:', err)\n }\n }\n \n if (sorts) {\n try {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n data.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 } catch (err) {\n console.error('Error parsing sorts:', err)\n }\n } else if (sortBy && sortBy.trim()) {\n data.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 pageValue = page ? Math.max(1, parseInt(page)) : undefined\n const offsetValue = offset !== undefined ? Math.max(0, parseInt(offset)) : (pageValue && perPage ? (pageValue - 1) * Math.max(1, parseInt(perPage)) : 0)\n \n if (limitValue) {\n const limitInt = Math.max(1, parseInt(limitValue))\n data = data.slice(offsetValue, offsetValue + limitInt)\n } else if (offsetValue > 0) {\n data = data.slice(offsetValue)\n }\n }\n \n const safeData = JSON.parse(JSON.stringify(data, 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('REST API 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");
56
+ : '', "\n \n const response = await fetch(url, options)\n \n if (!response.ok) {\n return res.status(response.status).json({\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n timestamp: Date.now()\n })\n }\n \n let data = await response.json()\n \n if (Array.isArray(data)) {\n if (query && query.trim()) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n try {\n const parsed = safeJSONParse(queryColumns)\n const columns = Array.isArray(parsed) ? parsed : [parsed]\n data = data.filter((item) => {\n return columns.some((col) => {\n const value = getNestedValue(item, col)\n if (value === null || value === undefined) return false\n return String(value).toLowerCase().includes(searchQuery)\n })\n })\n } catch (err) {\n console.error('Error parsing queryColumns:', err)\n }\n } else {\n data = data.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 try {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n data = data.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 data = data.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 } catch (err) {\n console.error('Error parsing filters:', err)\n }\n }\n \n if (sorts) {\n try {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n data.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().startsWith('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 } catch (err) {\n console.error('Error parsing sorts:', err)\n }\n } else if (sortBy && sortBy.trim()) {\n data.sort((a, b) => {\n const aVal = getNestedValue(a, sortBy)\n const bVal = getNestedValue(b, sortBy)\n const sortOrderValue = (sortOrder || '').toLowerCase().startsWith('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 pageValue = page ? Math.max(1, parseInt(page)) : undefined\n const offsetValue = offset !== undefined ? Math.max(0, parseInt(offset)) : (pageValue && perPage ? (pageValue - 1) * Math.max(1, parseInt(perPage)) : 0)\n \n if (limitValue) {\n const limitInt = Math.max(1, parseInt(limitValue))\n data = data.slice(offsetValue, offsetValue + limitInt)\n } else if (offsetValue > 0) {\n data = data.slice(offsetValue)\n }\n }\n \n const safeData = JSON.parse(JSON.stringify(data, 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('REST API 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");
57
57
  };
58
58
  exports.generateRESTAPIFetcher = generateRESTAPIFetcher;
59
59
  //# sourceMappingURL=rest-api.js.map
@@ -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":"supabase.d.ts","sourceRoot":"","sources":["../../../src/fetchers/supabase.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA0BpC,CAAA;AAUD,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8OF,CAAA;AAGD,eAAO,MAAM,4BAA4B,YAAa,GAAG,aAAa,MAAM,KAAG,MAiF9E,CAAA"}
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../../src/fetchers/supabase.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA0BpC,CAAA;AAUD,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAyTF,CAAA;AAGD,eAAO,MAAM,4BAA4B,YAAa,GAAG,aAAa,MAAM,KAAG,MAwF9E,CAAA"}
@@ -31,12 +31,72 @@ var generateSupabaseFetcher = function (config, tableName) {
31
31
  var supabaseConfig = config;
32
32
  var supabaseUrl = supabaseConfig.supabaseUrl;
33
33
  var apiKey = supabaseConfig.serviceRoleKey || supabaseConfig.publicApiKey;
34
- return "import { createClient } from '@supabase/supabase-js'\n\nlet client = null\n\nconst getClient = () => {\n if (client) return client\n \n client = createClient(\n ".concat(JSON.stringify(supabaseUrl), ",\n ").concat((0, utils_1.replaceSecretReference)(apiKey), "\n )\n \n return client\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n// Helper function to process filter values\nconst processFilterValue = (value) => {\n if (typeof value === 'string' && !isNaN(Number(value))) {\n return Number(value)\n }\n return value\n}\n\n// Helper function to apply filters to a query\nconst applyFilters = (queryRef, filters) => {\n if (!filters) return queryRef\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = filter.source\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n const processedValues = value.map(processFilterValue)\n if (operand === '!=') {\n queryRef = queryRef.not(field, 'in', processedValues)\n } else {\n queryRef = queryRef.in(field, processedValues)\n }\n } else {\n const processedValue = processFilterValue(value)\n \n // Handle null values\n if (processedValue === null) {\n if (operand === '=') {\n queryRef = queryRef.is(field, null)\n } else if (operand === '!=') {\n queryRef = queryRef.not(field, 'is', null)\n }\n } else {\n // Map operand to Supabase methods\n switch (operand) {\n case '=':\n queryRef = queryRef.eq(field, processedValue)\n break\n case '!=':\n queryRef = queryRef.neq(field, processedValue)\n break\n case '>':\n queryRef = queryRef.gt(field, processedValue)\n break\n case '>=':\n queryRef = queryRef.gte(field, processedValue)\n break\n case '<':\n queryRef = queryRef.lt(field, processedValue)\n break\n case '<=':\n queryRef = queryRef.lte(field, processedValue)\n break\n default:\n queryRef = queryRef.eq(field, processedValue)\n }\n }\n }\n })\n } else {\n // Old format: object with key-value pairs (backward compatibility)\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const processedValues = value.map(processFilterValue)\n queryRef = queryRef.in(key, processedValues)\n } else if (typeof value === 'object' && value !== null) {\n const operator = Object.keys(value)[0]\n let operatorValue = value[operator]\n if (typeof operatorValue === 'string' && !isNaN(Number(operatorValue))) {\n operatorValue = Number(operatorValue)\n }\n switch (operator) {\n case 'eq': queryRef = queryRef.eq(key, operatorValue); break\n case 'neq': queryRef = queryRef.neq(key, operatorValue); break\n case 'gt': queryRef = queryRef.gt(key, operatorValue); break\n case 'gte': queryRef = queryRef.gte(key, operatorValue); break\n case 'lt': queryRef = queryRef.lt(key, operatorValue); break\n case 'lte': queryRef = queryRef.lte(key, operatorValue); break\n case 'like': queryRef = queryRef.like(key, operatorValue); break\n case 'ilike': queryRef = queryRef.ilike(key, operatorValue); break\n case 'in': queryRef = queryRef.in(key, operatorValue); break\n default: queryRef = queryRef.eq(key, operatorValue)\n }\n } else {\n let processedValue = value\n if (typeof value === 'string' && !isNaN(Number(value))) {\n processedValue = Number(value)\n }\n queryRef = queryRef.eq(key, processedValue)\n }\n })\n }\n \n return queryRef\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, select, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n let queryRef = client.from('").concat(tableName, "').select(select || '*')\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n columns = safeJSONParse(queryColumns)\n } else {\n // Fallback: Get text-searchable columns from a sample row\n try {\n const { data: sampleData, error: sampleError } = await client.from('").concat(tableName, "').select('*').limit(1).single()\n if (sampleError) {\n throw sampleError\n }\n if (sampleData) {\n // Filter out columns that are likely non-text types\n // Note: This is heuristic-based since we don't have schema info\n columns = Object.keys(sampleData).filter(col => {\n const value = sampleData[col]\n const colLower = col.toLowerCase()\n \n // Exclude common timestamp/date column names\n if (colLower.includes('_at') || colLower.includes('date') || colLower === 'timestamp') {\n return false\n }\n \n // Exclude if value is a number, boolean, null, or object (non-string)\n if (value === null || value === undefined) {\n return true // Include null columns, let the query handle it\n }\n \n const type = typeof value\n return type === 'string' // Only include string values\n })\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample row for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n const searchPattern = `%${query}%`\n // Note: Supabase PostgREST doesn't support ::text casting in .or() syntax\n // Only text/varchar columns will match; non-text columns will be skipped\n const orConditions = columns.map((col) => `${col}.ilike.${searchPattern}`).join(',')\n queryRef = queryRef.or(orConditions)\n }\n }\n \n // Apply filters using helper function\n queryRef = applyFilters(queryRef, filters)\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts)) {\n parsedSorts.forEach((sort) => {\n if (sort.field) {\n queryRef = queryRef.order(sort.field, { \n ascending: sort.order?.toLowerCase() !== 'desc' \n })\n }\n })\n }\n } else if (sortBy) {\n queryRef = queryRef.order(sortBy, { ascending: sortOrder !== 'desc' })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (offsetValue !== undefined && limitValue) {\n queryRef = queryRef.range(offsetValue, offsetValue + parseInt(limitValue) - 1)\n } else if (limitValue) {\n queryRef = queryRef.limit(parseInt(limitValue))\n }\n \n const { data, error } = await queryRef\n \n if (error) {\n return res.status(500).json({\n success: false,\n error: error.message,\n timestamp: Date.now()\n })\n }\n \n const safeData = JSON.parse(JSON.stringify(data, 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('Supabase 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");
34
+ /*
35
+ DO $$
36
+ DECLARE
37
+ first_account_id UUID;
38
+ first_team_id UUID;
39
+ BEGIN
40
+ -- Step 1: Select the first account's id
41
+ SELECT id INTO first_account_id
42
+ FROM accounts
43
+ ORDER BY id
44
+ LIMIT 1;
45
+
46
+ -- Step 2: Insert into subscriptions
47
+ INSERT INTO subscriptions (
48
+ "stripeSubscriptionId",
49
+ "accountId",
50
+ "stripeCurrentPeriodStart",
51
+ "stripeCurrentPeriodEnd",
52
+ "createdAt",
53
+ "updatedAt",
54
+ "percentOff"
55
+ ) VALUES (
56
+ 'abc',
57
+ first_account_id,
58
+ '2025-08-13 00:00:00+00'::timestamptz,
59
+ '2035-09-13 00:00:00+00'::timestamptz,
60
+ '2025-08-13 00:00:00+00'::timestamptz,
61
+ '2025-08-13 00:00:00+00'::timestamptz,
62
+ 100
63
+ );
64
+
65
+ -- Step 3: Insert into subscription-items
66
+ INSERT INTO "subscription-items" (
67
+ "stripeSubscriptionItemId",
68
+ "stripePriceId",
69
+ "stripeSubscriptionId",
70
+ "createdAt",
71
+ "updatedAt"
72
+ ) VALUES (
73
+ 'abc',
74
+ 'price_1KO3BuGd5V11xo4EFF8fKiVR',
75
+ 'abc',
76
+ '2025-08-13 00:00:00+00'::timestamptz,
77
+ '2025-08-13 00:00:00+00'::timestamptz
78
+ );
79
+
80
+ -- Step 4: Get first team id and update its subscriptionItemId
81
+ SELECT id INTO first_team_id
82
+ FROM teams
83
+ ORDER BY id
84
+ LIMIT 1;
85
+
86
+ UPDATE teams
87
+ SET "subscriptionItemId" = 'abc'
88
+ WHERE id = first_team_id;
89
+
90
+ RAISE NOTICE 'Script completed successfully. Account ID: %, Team ID: %', first_account_id, first_team_id;
91
+ END $$;
92
+
93
+ */
94
+ return "import { createClient } from '@supabase/supabase-js'\n\nlet client = null\n\nconst getClient = () => {\n if (client) return client\n \n client = createClient(\n ".concat(JSON.stringify(supabaseUrl), ",\n ").concat((0, utils_1.replaceSecretReference)(apiKey), "\n )\n \n return client\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateSearchEscapeHelpersCode)(), "\n\n// Helper function to process filter values\nconst processFilterValue = (value) => {\n if (typeof value === 'string' && !isNaN(Number(value))) {\n return Number(value)\n }\n return value\n}\n\n// Helper function to apply filters to a query\nconst applyFilters = (queryRef, filters) => {\n if (!filters) return queryRef\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filter) => {\n if (!filter.source || filter.destination === undefined) return\n \n const field = filter.source\n const value = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(value)) {\n const processedValues = value.map(processFilterValue)\n if (operand === '!=') {\n queryRef = queryRef.not(field, 'in', processedValues)\n } else {\n queryRef = queryRef.in(field, processedValues)\n }\n } else {\n const processedValue = processFilterValue(value)\n \n // Handle null values\n if (processedValue === null) {\n if (operand === '=') {\n queryRef = queryRef.is(field, null)\n } else if (operand === '!=') {\n queryRef = queryRef.not(field, 'is', null)\n }\n } else {\n // Map operand to Supabase methods\n switch (operand) {\n case '=':\n queryRef = queryRef.eq(field, processedValue)\n break\n case '!=':\n queryRef = queryRef.neq(field, processedValue)\n break\n case '>':\n queryRef = queryRef.gt(field, processedValue)\n break\n case '>=':\n queryRef = queryRef.gte(field, processedValue)\n break\n case '<':\n queryRef = queryRef.lt(field, processedValue)\n break\n case '<=':\n queryRef = queryRef.lte(field, processedValue)\n break\n default:\n queryRef = queryRef.eq(field, processedValue)\n }\n }\n }\n })\n } else {\n // Old format: object with key-value pairs (backward compatibility)\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const processedValues = value.map(processFilterValue)\n queryRef = queryRef.in(key, processedValues)\n } else if (typeof value === 'object' && value !== null) {\n const operator = Object.keys(value)[0]\n let operatorValue = value[operator]\n if (typeof operatorValue === 'string' && !isNaN(Number(operatorValue))) {\n operatorValue = Number(operatorValue)\n }\n switch (operator) {\n case 'eq': queryRef = queryRef.eq(key, operatorValue); break\n case 'neq': queryRef = queryRef.neq(key, operatorValue); break\n case 'gt': queryRef = queryRef.gt(key, operatorValue); break\n case 'gte': queryRef = queryRef.gte(key, operatorValue); break\n case 'lt': queryRef = queryRef.lt(key, operatorValue); break\n case 'lte': queryRef = queryRef.lte(key, operatorValue); break\n case 'like': queryRef = queryRef.like(key, operatorValue); break\n case 'ilike': queryRef = queryRef.ilike(key, operatorValue); break\n case 'in': queryRef = queryRef.in(key, operatorValue); break\n default: queryRef = queryRef.eq(key, operatorValue)\n }\n } else {\n let processedValue = value\n if (typeof value === 'string' && !isNaN(Number(value))) {\n processedValue = Number(value)\n }\n queryRef = queryRef.eq(key, processedValue)\n }\n })\n }\n \n return queryRef\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, select, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n let queryRef = client.from('").concat(tableName, "').select(select || '*')\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns. Wrap non-arrays so a single column\n // 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 text-searchable columns from a sample row\n try {\n const { data: sampleData, error: sampleError } = await client.from('").concat(tableName, "').select('*').limit(1).single()\n if (sampleError) {\n throw sampleError\n }\n if (sampleData) {\n // Filter out columns that are likely non-text types\n // Note: This is heuristic-based since we don't have schema info\n columns = Object.keys(sampleData).filter(col => {\n const value = sampleData[col]\n const colLower = col.toLowerCase()\n \n // Exclude common timestamp/date column names\n if (colLower.includes('_at') || colLower.includes('date') || colLower === 'timestamp') {\n return false\n }\n \n // Exclude if value is a number, boolean, null, or object (non-string)\n if (value === null || value === undefined) {\n return true // Include null columns, let the query handle it\n }\n \n const type = typeof value\n return type === 'string' // Only include string values\n })\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample row for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n // PostgREST .or() DSL separates conditions with comma and uses\n // dot to split field / operator / value, so we wrap the pattern\n // in double quotes and backslash-escape any embedded quotes or\n // backslashes in the user's search term. Columns go through the\n // shared identifier sanitizer to reject injection. Note:\n // PostgREST .ilike. does not expose a LIKE ESCAPE clause, so\n // raw % / _ in the user input still act as wildcards in this\n // backend; the canvas preview path escapes them explicitly.\n const rawPattern = \"%\" + String(query) + \"%\"\n const escapedForPostgrest = rawPattern\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n const searchPattern = '\"' + escapedForPostgrest + '\"'\n const orConditions = columns\n .map((col) => sanitizeSearchIdentifier(col) + \".ilike.\" + searchPattern)\n .join(\",\")\n queryRef = queryRef.or(orConditions)\n }\n }\n\n // Apply filters using helper function\n queryRef = applyFilters(queryRef, filters)\n \n // Handle sorts - new array format\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts)) {\n parsedSorts.forEach((sort) => {\n if (sort.field) {\n queryRef = queryRef.order(sort.field, {\n ascending: !(sort.order || '').toLowerCase().startsWith('desc')\n })\n }\n })\n }\n } else if (sortBy) {\n queryRef = queryRef.order(sortBy, { ascending: !(sortOrder || '').toLowerCase().startsWith('desc') })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (offsetValue !== undefined && limitValue) {\n queryRef = queryRef.range(offsetValue, offsetValue + parseInt(limitValue) - 1)\n } else if (limitValue) {\n queryRef = queryRef.limit(parseInt(limitValue))\n }\n \n const { data, error } = await queryRef\n \n if (error) {\n return res.status(500).json({\n success: false,\n error: error.message,\n timestamp: Date.now()\n })\n }\n \n const safeData = JSON.parse(JSON.stringify(data, 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('Supabase 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");
35
95
  };
36
96
  exports.generateSupabaseFetcher = generateSupabaseFetcher;
37
97
  // tslint:disable-next-line:variable-name
38
98
  var generateSupabaseCountFetcher = function (_config, tableName) {
39
- return "\nasync function getCount(req, res) {\n const supabase = getClient()\n\n try {\n const { query, queryColumns, filters } = req.query\n let countQuery = supabase.from('".concat(tableName, "').select('*', { count: 'exact', head: true })\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get text-searchable columns from a sample row\n try {\n const { data: sampleData, error: sampleError } = await supabase.from('").concat(tableName, "').select('*').limit(1).single()\n if (sampleError) {\n throw sampleError\n }\n if (sampleData) {\n // Filter out columns that are likely non-text types\n // Note: This is heuristic-based since we don't have schema info\n columns = Object.keys(sampleData).filter(col => {\n const value = sampleData[col]\n const colLower = col.toLowerCase()\n \n // Exclude common timestamp/date column names\n if (colLower.includes('_at') || colLower.includes('date') || colLower === 'timestamp') {\n return false\n }\n \n // Exclude if value is a number, boolean, null, or object (non-string)\n if (value === null || value === undefined) {\n return true // Include null columns, let the query handle it\n }\n \n const type = typeof value\n return type === 'string' // Only include string values\n })\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample row for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n const searchPattern = `%${query}%`\n // Note: Supabase PostgREST doesn't support ::text casting in .or() syntax\n // Only text/varchar columns will match; non-text columns will be skipped\n const orConditions = columns.map((col) => `${col}.ilike.${searchPattern}`).join(',')\n countQuery = countQuery.or(orConditions)\n }\n }\n\n // Apply filters using helper function\n countQuery = applyFilters(countQuery, filters)\n\n const { count, error } = await countQuery\n \n if (error) throw error\n\n return res.status(200).json({\n success: true,\n count: count || 0,\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");
99
+ return "\nasync function getCount(req, res) {\n const supabase = getClient()\n\n try {\n const { query, queryColumns, filters } = req.query\n let countQuery = supabase.from('".concat(tableName, "').select('*', { count: 'exact', head: true })\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n // Fallback: Get text-searchable columns from a sample row\n try {\n const { data: sampleData, error: sampleError } = await supabase.from('").concat(tableName, "').select('*').limit(1).single()\n if (sampleError) {\n throw sampleError\n }\n if (sampleData) {\n // Filter out columns that are likely non-text types\n // Note: This is heuristic-based since we don't have schema info\n columns = Object.keys(sampleData).filter(col => {\n const value = sampleData[col]\n const colLower = col.toLowerCase()\n \n // Exclude common timestamp/date column names\n if (colLower.includes('_at') || colLower.includes('date') || colLower === 'timestamp') {\n return false\n }\n \n // Exclude if value is a number, boolean, null, or object (non-string)\n if (value === null || value === undefined) {\n return true // Include null columns, let the query handle it\n }\n \n const type = typeof value\n return type === 'string' // Only include string values\n })\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample row for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n // Mirror the fetch handler: sanitize identifiers, wrap the\n // pattern in double quotes for PostgREST .or() DSL, and escape\n // backslashes / quotes in the user's search term.\n const rawPattern = \"%\" + String(query) + \"%\"\n const escapedForPostgrest = rawPattern\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n const searchPattern = '\"' + escapedForPostgrest + '\"'\n const orConditions = columns\n .map((col) => sanitizeSearchIdentifier(col) + \".ilike.\" + searchPattern)\n .join(\",\")\n countQuery = countQuery.or(orConditions)\n }\n }\n\n // Apply filters using helper function\n countQuery = applyFilters(countQuery, filters)\n\n const { count, error } = await countQuery\n \n if (error) throw error\n\n return res.status(200).json({\n success: true,\n count: count || 0,\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");
40
100
  };
41
101
  exports.generateSupabaseCountFetcher = generateSupabaseCountFetcher;
42
102
  //# sourceMappingURL=supabase.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../../src/fetchers/supabase.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,IAAM,sBAAsB,GAAG,UACpC,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,WAAW,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,EAAE;QACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAA;KAC7D;IAED,IAAI;QACF,IAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;YACpF,OAAO,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAA;SACnF;KACF;IAAC,WAAM;QACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;KAChE;IAED,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;QAClD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,+DAA+D;SACvE,CAAA;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AA5BY,QAAA,sBAAsB,0BA4BlC;AAUM,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAA;IAC9C,IAAM,MAAM,GAAG,cAAc,CAAC,cAAc,IAAI,cAAc,CAAC,YAAY,CAAA;IAE3E,OAAO,iLAQH,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,oBAC3B,IAAA,8BAAsB,EAAC,MAAM,CAAC,8CAMlC,IAAA,iCAAyB,GAAE,uuHAyG3B,IAAA,iCAAyB,GAAE,2QAOK,SAAS,4XAWqC,SAAS,uyGA8FxF,CAAA;AACD,CAAC,CAAA;AAjPY,QAAA,uBAAuB,2BAiPnC;AAED,yCAAyC;AAClC,IAAM,4BAA4B,GAAG,UAAC,OAAY,EAAE,SAAiB;IAC1E,OAAO,wLAM6B,SAAS,kdAYmC,SAAS,4rEA6D1F,CAAA;AACD,CAAC,CAAA;AAjFY,QAAA,4BAA4B,gCAiFxC"}
1
+ {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../../src/fetchers/supabase.ts"],"names":[],"mappings":";;;AAAA,kCAKiB;AAEV,IAAM,sBAAsB,GAAG,UACpC,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,WAAW,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,EAAE;QACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAA;KAC7D;IAED,IAAI;QACF,IAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;YACpF,OAAO,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAA;SACnF;KACF;IAAC,WAAM;QACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;KAChE;IAED,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;QAClD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,+DAA+D;SACvE,CAAA;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AA5BY,QAAA,sBAAsB,0BA4BlC;AAUM,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAA;IAC9C,IAAM,MAAM,GAAG,cAAc,CAAC,cAAc,IAAI,cAAc,CAAC,YAAY,CAAA;IAC3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2DA;IACA,OAAO,iLAQH,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,oBAC3B,IAAA,8BAAsB,EAAC,MAAM,CAAC,8CAMlC,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,uCAA+B,GAAE,uuHAyGjC,IAAA,iCAAyB,GAAE,2QAOK,SAAS,qjBAaqC,SAAS,2+HA0GxF,CAAA;AACD,CAAC,CAAA;AA5TY,QAAA,uBAAuB,2BA4TnC;AAED,yCAAyC;AAClC,IAAM,4BAA4B,GAAG,UAAC,OAAY,EAAE,SAAiB;IAC1E,OAAO,wLAM6B,SAAS,kdAYmC,SAAS,o+EAoE1F,CAAA;AACD,CAAC,CAAA;AAxFY,QAAA,4BAA4B,gCAwFxC"}