@teleporthq/teleport-plugin-next-data-source 0.42.8 → 0.42.10

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 (160) hide show
  1. package/__tests__/csv-header-detection.test.ts +212 -0
  2. package/__tests__/validation.test.ts +33 -2
  3. package/dist/cjs/data-source-fetchers.d.ts +2 -2
  4. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  5. package/dist/cjs/data-source-fetchers.js +30 -7
  6. package/dist/cjs/data-source-fetchers.js.map +1 -1
  7. package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
  8. package/dist/cjs/fetchers/airtable.js +2 -2
  9. package/dist/cjs/fetchers/airtable.js.map +1 -1
  10. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  11. package/dist/cjs/fetchers/clickhouse.js +1 -1
  12. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  13. package/dist/cjs/fetchers/csv-file.d.ts.map +1 -1
  14. package/dist/cjs/fetchers/csv-file.js +23 -3
  15. package/dist/cjs/fetchers/csv-file.js.map +1 -1
  16. package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
  17. package/dist/cjs/fetchers/firestore.js +1 -1
  18. package/dist/cjs/fetchers/firestore.js.map +1 -1
  19. package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -1
  20. package/dist/cjs/fetchers/google-sheets.js +6 -1
  21. package/dist/cjs/fetchers/google-sheets.js.map +1 -1
  22. package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
  23. package/dist/cjs/fetchers/javascript.js +2 -1
  24. package/dist/cjs/fetchers/javascript.js.map +1 -1
  25. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
  26. package/dist/cjs/fetchers/mariadb.js +3 -3
  27. package/dist/cjs/fetchers/mariadb.js.map +1 -1
  28. package/dist/cjs/fetchers/mongodb.d.ts +1 -1
  29. package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
  30. package/dist/cjs/fetchers/mongodb.js +11 -3
  31. package/dist/cjs/fetchers/mongodb.js.map +1 -1
  32. package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
  33. package/dist/cjs/fetchers/mysql.js +2 -2
  34. package/dist/cjs/fetchers/mysql.js.map +1 -1
  35. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  36. package/dist/cjs/fetchers/postgresql.js +3 -3
  37. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  38. package/dist/cjs/fetchers/redis.d.ts.map +1 -1
  39. package/dist/cjs/fetchers/redis.js +1 -1
  40. package/dist/cjs/fetchers/redis.js.map +1 -1
  41. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  42. package/dist/cjs/fetchers/redshift.js +2 -2
  43. package/dist/cjs/fetchers/redshift.js.map +1 -1
  44. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  45. package/dist/cjs/fetchers/rest-api.js +3 -2
  46. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  47. package/dist/cjs/fetchers/static-collection.d.ts.map +1 -1
  48. package/dist/cjs/fetchers/static-collection.js +2 -1
  49. package/dist/cjs/fetchers/static-collection.js.map +1 -1
  50. package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
  51. package/dist/cjs/fetchers/supabase.js +2 -2
  52. package/dist/cjs/fetchers/supabase.js.map +1 -1
  53. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  54. package/dist/cjs/fetchers/turso.js +1 -1
  55. package/dist/cjs/fetchers/turso.js.map +1 -1
  56. package/dist/cjs/fetchers/utils/header-detection.d.ts +2 -0
  57. package/dist/cjs/fetchers/utils/header-detection.d.ts.map +1 -0
  58. package/dist/cjs/fetchers/utils/header-detection.js +8 -0
  59. package/dist/cjs/fetchers/utils/header-detection.js.map +1 -0
  60. package/dist/cjs/index.d.ts.map +1 -1
  61. package/dist/cjs/index.js +168 -4
  62. package/dist/cjs/index.js.map +1 -1
  63. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  64. package/dist/cjs/pagination-plugin.js +320 -65
  65. package/dist/cjs/pagination-plugin.js.map +1 -1
  66. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  67. package/dist/cjs/utils.d.ts +3 -0
  68. package/dist/cjs/utils.d.ts.map +1 -1
  69. package/dist/cjs/utils.js +218 -46
  70. package/dist/cjs/utils.js.map +1 -1
  71. package/dist/esm/data-source-fetchers.d.ts +2 -2
  72. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  73. package/dist/esm/data-source-fetchers.js +29 -6
  74. package/dist/esm/data-source-fetchers.js.map +1 -1
  75. package/dist/esm/fetchers/airtable.d.ts.map +1 -1
  76. package/dist/esm/fetchers/airtable.js +3 -3
  77. package/dist/esm/fetchers/airtable.js.map +1 -1
  78. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  79. package/dist/esm/fetchers/clickhouse.js +2 -2
  80. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  81. package/dist/esm/fetchers/csv-file.d.ts.map +1 -1
  82. package/dist/esm/fetchers/csv-file.js +23 -3
  83. package/dist/esm/fetchers/csv-file.js.map +1 -1
  84. package/dist/esm/fetchers/firestore.d.ts.map +1 -1
  85. package/dist/esm/fetchers/firestore.js +2 -2
  86. package/dist/esm/fetchers/firestore.js.map +1 -1
  87. package/dist/esm/fetchers/google-sheets.d.ts.map +1 -1
  88. package/dist/esm/fetchers/google-sheets.js +6 -1
  89. package/dist/esm/fetchers/google-sheets.js.map +1 -1
  90. package/dist/esm/fetchers/javascript.d.ts.map +1 -1
  91. package/dist/esm/fetchers/javascript.js +2 -1
  92. package/dist/esm/fetchers/javascript.js.map +1 -1
  93. package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
  94. package/dist/esm/fetchers/mariadb.js +4 -4
  95. package/dist/esm/fetchers/mariadb.js.map +1 -1
  96. package/dist/esm/fetchers/mongodb.d.ts +1 -1
  97. package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
  98. package/dist/esm/fetchers/mongodb.js +12 -4
  99. package/dist/esm/fetchers/mongodb.js.map +1 -1
  100. package/dist/esm/fetchers/mysql.d.ts.map +1 -1
  101. package/dist/esm/fetchers/mysql.js +3 -3
  102. package/dist/esm/fetchers/mysql.js.map +1 -1
  103. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  104. package/dist/esm/fetchers/postgresql.js +4 -4
  105. package/dist/esm/fetchers/postgresql.js.map +1 -1
  106. package/dist/esm/fetchers/redis.d.ts.map +1 -1
  107. package/dist/esm/fetchers/redis.js +2 -2
  108. package/dist/esm/fetchers/redis.js.map +1 -1
  109. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  110. package/dist/esm/fetchers/redshift.js +3 -3
  111. package/dist/esm/fetchers/redshift.js.map +1 -1
  112. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  113. package/dist/esm/fetchers/rest-api.js +3 -2
  114. package/dist/esm/fetchers/rest-api.js.map +1 -1
  115. package/dist/esm/fetchers/static-collection.d.ts.map +1 -1
  116. package/dist/esm/fetchers/static-collection.js +2 -1
  117. package/dist/esm/fetchers/static-collection.js.map +1 -1
  118. package/dist/esm/fetchers/supabase.d.ts.map +1 -1
  119. package/dist/esm/fetchers/supabase.js +3 -3
  120. package/dist/esm/fetchers/supabase.js.map +1 -1
  121. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  122. package/dist/esm/fetchers/turso.js +2 -2
  123. package/dist/esm/fetchers/turso.js.map +1 -1
  124. package/dist/esm/fetchers/utils/header-detection.d.ts +2 -0
  125. package/dist/esm/fetchers/utils/header-detection.d.ts.map +1 -0
  126. package/dist/esm/fetchers/utils/header-detection.js +4 -0
  127. package/dist/esm/fetchers/utils/header-detection.js.map +1 -0
  128. package/dist/esm/index.d.ts.map +1 -1
  129. package/dist/esm/index.js +169 -5
  130. package/dist/esm/index.js.map +1 -1
  131. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  132. package/dist/esm/pagination-plugin.js +320 -65
  133. package/dist/esm/pagination-plugin.js.map +1 -1
  134. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  135. package/dist/esm/utils.d.ts +3 -0
  136. package/dist/esm/utils.d.ts.map +1 -1
  137. package/dist/esm/utils.js +214 -45
  138. package/dist/esm/utils.js.map +1 -1
  139. package/package.json +2 -2
  140. package/src/data-source-fetchers.ts +29 -13
  141. package/src/fetchers/airtable.ts +81 -31
  142. package/src/fetchers/clickhouse.ts +88 -19
  143. package/src/fetchers/csv-file.ts +256 -27
  144. package/src/fetchers/firestore.ts +65 -13
  145. package/src/fetchers/google-sheets.ts +243 -26
  146. package/src/fetchers/javascript.ts +106 -23
  147. package/src/fetchers/mariadb.ts +85 -26
  148. package/src/fetchers/mongodb.ts +156 -37
  149. package/src/fetchers/mysql.ts +86 -26
  150. package/src/fetchers/postgresql.ts +89 -27
  151. package/src/fetchers/redis.ts +43 -5
  152. package/src/fetchers/redshift.ts +87 -18
  153. package/src/fetchers/rest-api.ts +105 -24
  154. package/src/fetchers/static-collection.ts +100 -18
  155. package/src/fetchers/supabase.ts +178 -54
  156. package/src/fetchers/turso.ts +87 -18
  157. package/src/fetchers/utils/header-detection.ts +200 -0
  158. package/src/index.ts +248 -2
  159. package/src/pagination-plugin.ts +708 -191
  160. package/src/utils.ts +374 -38
@@ -1 +1 @@
1
- {"version":3,"file":"data-source-fetchers.js","sourceRoot":"","sources":["../../src/data-source-fetchers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-source-fetchers.js","sourceRoot":"","sources":["../../src/data-source-fetchers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"airtable.d.ts","sourceRoot":"","sources":["../../../src/fetchers/airtable.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAcpC,CAAA;AAQD,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA2HF,CAAA"}
1
+ {"version":3,"file":"airtable.d.ts","sourceRoot":"","sources":["../../../src/fetchers/airtable.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;CAcpC,CAAA;AAQD,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAyKF,CAAA"}
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils';
1
+ import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, } from '../utils';
2
2
  export var validateAirtableConfig = function (config) {
3
3
  if (!config || typeof config !== 'object') {
4
4
  return { isValid: false, error: 'Config must be a valid object' };
@@ -15,8 +15,8 @@ export var generateAirtableFetcher = function (config, tableName) {
15
15
  var airtableConfig = config;
16
16
  var baseId = airtableConfig.baseId;
17
17
  var personalAccessToken = airtableConfig.personalAccessToken;
18
- return "import fetch from 'node-fetch'\n\nexport default async function handler(req, res) {\n try {\n const { query, view, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query\n \n const queryParams = new URLSearchParams()\n \n if (view) {\n queryParams.append('view', view)\n }\n \n if (sortBy) {\n queryParams.append('sort[0][field]', sortBy)\n queryParams.append('sort[0][direction]', sortOrder || 'asc')\n }\n \n const perPageValue = limit || perPage || 100\n queryParams.append('pageSize', Math.min(parseInt(perPageValue), 100).toString())\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n const conditions = Object.entries(parsedFilters).map(([field, value]) => {\n if (Array.isArray(value)) {\n const arrayConditions = value.map((v) => {\n if (typeof v === 'string') {\n return `{${field}}='${v.replace(/'/g, \"\\\\'\")}'`\n } else if (typeof v === 'number') {\n return `{${field}}=${v}`\n } else if (typeof v === 'boolean') {\n return `{${field}}=${v ? 'TRUE()' : 'FALSE()'}`\n }\n return `{${field}}='${String(v)}'`\n })\n return arrayConditions.length > 1\n ? `OR(${arrayConditions.join(',')})`\n : arrayConditions[0]\n } else if (typeof value === 'string') {\n return `{${field}}='${value.replace(/'/g, \"\\\\'\")}'`\n } else if (typeof value === 'number') {\n return `{${field}}=${value}`\n } else if (typeof value === 'boolean') {\n return `{${field}}=${value ? 'TRUE()' : 'FALSE()'}`\n }\n return `{${field}}='${String(value)}'`\n })\n \n const filterFormula = conditions.length > 1 ? `AND(${conditions.join(',')})` : conditions[0]\n if (filterFormula) {\n queryParams.append('filterByFormula', filterFormula)\n }\n }\n \n let url = `https://api.airtable.com/v0/".concat(baseId, "/${encodeURIComponent('").concat(tableName, "')}`\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`\n }\n \n const allRecords = []\n let airtableOffset\n const skipValue = offsetParam !== undefined ? parseInt(offsetParam) : (page ? (parseInt(page) - 1) * parseInt(perPageValue) : 0)\n const totalRecordsNeeded = skipValue + parseInt(perPageValue)\n \n do {\n const fetchUrl = airtableOffset ? `${url}&offset=${airtableOffset}` : url\n const response = await fetch(fetchUrl, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ").concat(replaceSecretReference(personalAccessToken, {
18
+ return "import fetch from 'node-fetch'\n\n".concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\nexport default async function handler(req, res) {\n try {\n const { query, view, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset: offsetParam } = req.query\n \n const queryParams = new URLSearchParams()\n \n if (view) {\n queryParams.append('view', view)\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 parsedSorts.forEach((sort, index) => {\n if (!sort.field) return\n queryParams.append(`sort[${index}][field]`, sort.field)\n queryParams.append(`sort[${index}][direction]`, sort.order?.toLowerCase() === 'desc' ? 'desc' : 'asc')\n })\n }\n } else if (sortBy) {\n queryParams.append('sort[0][field]', sortBy)\n queryParams.append('sort[0][direction]', sortOrder || 'asc')\n }\n \n const perPageValue = limit || perPage || 100\n queryParams.append('pageSize', Math.min(parseInt(perPageValue), 100).toString())\n \n const formatAirtableValue = (value) => {\n if (typeof value === 'string') {\n return `'${value.replace(/'/g, \"\\\\'\")}'`\n } else if (typeof value === 'number') {\n return String(value)\n } else if (typeof value === 'boolean') {\n return value ? 'TRUE()' : 'FALSE()'\n }\n return `'${String(value)}'`\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n const conditions = parsedFilters.map((filter) => {\n if (!filter.source || filter.destination === undefined) return null\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 null\n const arrayConditions = value.map((v) => `{${field}}=${formatAirtableValue(v)}`)\n return arrayConditions.length > 1\n ? `OR(${arrayConditions.join(',')})`\n : arrayConditions[0]\n } else {\n const operatorMap = {\n '=': '=',\n '!=': '!=',\n '>': '>',\n '<': '<',\n '>=': '>=',\n '<=': '<=',\n }\n const airtableOp = operatorMap[operand] || '='\n return `{${field}}${airtableOp}${formatAirtableValue(value)}`\n }\n }).filter(Boolean)\n \n if (conditions.length > 0) {\n const filterFormula = conditions.length > 1 ? `AND(${conditions.join(',')})` : conditions[0]\n queryParams.append('filterByFormula', filterFormula)\n }\n } else {\n const conditions = Object.entries(parsedFilters).map(([field, value]) => {\n if (Array.isArray(value)) {\n const arrayConditions = value.map((v) => `{${field}}=${formatAirtableValue(v)}`)\n return arrayConditions.length > 1\n ? `OR(${arrayConditions.join(',')})`\n : arrayConditions[0]\n } else {\n return `{${field}}=${formatAirtableValue(value)}`\n }\n })\n \n const filterFormula = conditions.length > 1 ? `AND(${conditions.join(',')})` : conditions[0]\n if (filterFormula) {\n queryParams.append('filterByFormula', filterFormula)\n }\n }\n }\n \n let url = `https://api.airtable.com/v0/").concat(baseId, "/${encodeURIComponent('").concat(tableName, "')}`\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`\n }\n \n const allRecords = []\n let airtableOffset\n const skipValue = offsetParam !== undefined ? parseInt(offsetParam) : (page ? (parseInt(page) - 1) * parseInt(perPageValue) : 0)\n const totalRecordsNeeded = skipValue + parseInt(perPageValue)\n \n do {\n const fetchUrl = airtableOffset ? `${url}&offset=${airtableOffset}` : url\n const response = await fetch(fetchUrl, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ").concat(replaceSecretReference(personalAccessToken, {
19
19
  templateLiteral: true,
20
- }), "`,\n 'Content-Type': 'application/json'\n }\n })\n \n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n return res.status(response.status).json({\n success: false,\n error: errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,\n timestamp: Date.now()\n })\n }\n \n const data = await response.json()\n allRecords.push(...data.records)\n airtableOffset = data.offset\n \n if (allRecords.length >= totalRecordsNeeded || !airtableOffset) {\n break\n }\n } while (airtableOffset)\n \n const paginatedRecords = allRecords.slice(skipValue, skipValue + parseInt(perPageValue))\n \n const formattedRecords = paginatedRecords.map((record) => ({\n id: record.id,\n ...record.fields,\n createdTime: record.createdTime\n }))\n \n const safeData = JSON.parse(JSON.stringify(formattedRecords))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Airtable 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");
20
+ }), "`,\n 'Content-Type': 'application/json'\n }\n })\n \n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}))\n return res.status(response.status).json({\n success: false,\n error: errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,\n timestamp: Date.now()\n })\n }\n \n const data = await response.json()\n allRecords.push(...data.records)\n airtableOffset = data.offset\n \n if (allRecords.length >= totalRecordsNeeded || !airtableOffset) {\n break\n }\n } while (airtableOffset)\n \n const paginatedRecords = allRecords.slice(skipValue, skipValue + parseInt(perPageValue))\n \n const formattedRecords = paginatedRecords.map((record) => ({\n id: record.id,\n ...record.fields,\n createdTime: record.createdTime\n }))\n \n const safeData = JSON.parse(JSON.stringify(formattedRecords, 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('Airtable 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");
21
21
  };
22
22
  //# sourceMappingURL=airtable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"airtable.js","sourceRoot":"","sources":["../../../src/fetchers/airtable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,CAAC,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,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACtF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAA;KACjE;IAED,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,OAAO,MAAM,CAAC,mBAAmB,KAAK,QAAQ,EAAE;QACjF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAA;KAC/E;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAQD,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAA;IACpC,IAAM,mBAAmB,GAAG,cAAc,CAAC,mBAAmB,CAAA;IAE9D,OAAO,8/DAqDqC,MAAM,oCAA2B,SAAS,wkBAepD,sBAAsB,CAAC,mBAAmB,EAAE;QACpE,eAAe,EAAE,IAAI;KACtB,CAAC,i1CA+CX,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"airtable.js","sourceRoot":"","sources":["../../../src/fetchers/airtable.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,UAAU,CAAA;AAEjB,MAAM,CAAC,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,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACtF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAA;KACjE;IAED,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,OAAO,MAAM,CAAC,mBAAmB,KAAK,QAAQ,EAAE;QACjF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAA;KAC/E;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAQD,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAA;IACpC,IAAM,mBAAmB,GAAG,cAAc,CAAC,mBAAmB,CAAA;IAE9D,OAAO,4CAEP,yBAAyB,EAAE,iBAE3B,yBAAyB,EAAE,m/GA+FiB,MAAM,oCAA2B,SAAS,wkBAepD,sBAAsB,CAAC,mBAAmB,EAAE;QACpE,eAAe,EAAE,IAAI;KACtB,CAAC,+1CA+CX,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAkBpC,CAAA;AAQD,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAmGF,CAAA"}
1
+ {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAkBpC,CAAA;AAQD,eAAO,MAAM,yBAAyB,WAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAoKF,CAAA"}
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils';
1
+ import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, } from '../utils';
2
2
  export var validateClickHouseConfig = function (config) {
3
3
  if (!config || typeof config !== 'object') {
4
4
  return { isValid: false, error: 'Config must be a valid object' };
@@ -19,6 +19,6 @@ export var generateClickHouseFetcher = function (config, tableName) {
19
19
  var url = clickConfig.url;
20
20
  var username = clickConfig.username;
21
21
  var password = clickConfig.password;
22
- return "import { createClient } from '@clickhouse/client'\n\nlet client = null\n\nconst getClient = () => {\n if (client) return client\n \n client = createClient({\n url: ".concat(JSON.stringify(url), ",\n username: ").concat(JSON.stringify(username), ",\n password: ").concat(replaceSecretReference(password), "\n })\n \n return client\n}\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset } = req.query\n \n const conditions = []\n \n if (query) {\n if (queryColumns) {\n const columns = typeof queryColumns === 'string' ? JSON.parse(queryColumns) : (Array.isArray(queryColumns) ? queryColumns : [queryColumns])\n const searchConditions = columns.map(\n (col) => `positionCaseInsensitive(toString(${col}), '${query}') > 0`\n )\n conditions.push(`(${searchConditions.join(' OR ')})`)\n } else {\n // Note: Without queryColumns, ClickHouse can't search all columns efficiently\n // Users should provide queryColumns for optimal search performance\n console.warn('Search query provided without queryColumns - search may not work as expected')\n }\n }\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n const formattedValues = value\n .map((v) => (typeof v === 'string' ? `'${v}'` : v))\n .join(', ')\n conditions.push(`${key} IN (${formattedValues})`)\n } else if (typeof value === 'string') {\n conditions.push(`${key} = '${value}'`)\n } else {\n conditions.push(`${key} = ${value}`)\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 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({ query: sql })\n const resultResponse = await result.json()\n const safeData = JSON.parse(JSON.stringify(resultResponse.data))\n\n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('ClickHouse 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");
22
+ return "import { createClient } from '@clickhouse/client'\n\nlet client = null\n\nconst getClient = () => {\n if (client) return client\n \n client = createClient({\n url: ".concat(JSON.stringify(url), ",\n username: ").concat(JSON.stringify(username), ",\n password: ").concat(replaceSecretReference(password), "\n })\n \n return client\n}\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n const conditions = []\n \n if (query) {\n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n const columns = Array.isArray(parsed) ? parsed : [parsed]\n const searchConditions = columns.map(\n (col) => `positionCaseInsensitive(toString(${col}), '${query}') > 0`\n )\n conditions.push(`(${searchConditions.join(' OR ')})`)\n } else {\n // Note: Without queryColumns, ClickHouse can't search all columns efficiently\n // Users should provide queryColumns for optimal search performance\n console.warn('Search query provided without queryColumns - search may not work as expected')\n }\n }\n \n const formatClickHouseValue = (value) => {\n if (value === null || value === undefined) return 'NULL'\n if (typeof value === 'string') return `'${value.replace(/'/g, \"\\\\'\")}'`\n if (typeof value === 'boolean') return value ? '1' : '0'\n return String(value)\n }\n \n // Helper to sanitize identifier (prevent SQL injection in column names)\n const sanitizeIdentifier = (name) => {\n // Only allow alphanumeric and underscore\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 formattedValues = value.map(formatClickHouseValue).join(', ')\n if (operand === '!=') {\n conditions.push(`${field} NOT IN (${formattedValues})`)\n } else {\n conditions.push(`${field} IN (${formattedValues})`)\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} ${formatClickHouseValue(value)}`)\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n const field = sanitizeIdentifier(key)\n if (Array.isArray(value)) {\n const formattedValues = value.map(formatClickHouseValue).join(', ')\n conditions.push(`${field} IN (${formattedValues})`)\n } else {\n conditions.push(`${field} = ${formatClickHouseValue(value)}`)\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({ query: sql })\n const resultResponse = await result.json()\n const safeData = JSON.parse(JSON.stringify(resultResponse.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('ClickHouse 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");
23
23
  };
24
24
  //# sourceMappingURL=clickhouse.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clickhouse.js","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,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,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE;QACjD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAA;KAC/D;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAA;KACpE;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAA;KACpE;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAQD,MAAM,CAAC,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAA0B,CAAA;IAC9C,IAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAA;IAC3B,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,OAAO,oLAQE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,8BACd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,8BACxB,sBAAsB,CAAC,QAAQ,CAAC,siDA2ChB,SAAS,mkCAuCxC,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"clickhouse.js","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,UAAU,CAAA;AAEjB,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,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,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE;QACjD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAA;KAC/D;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAA;KACpE;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAA;KACpE;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAQD,MAAM,CAAC,IAAM,yBAAyB,GAAG,UACvC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAA0B,CAAA;IAC9C,IAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAA;IAC3B,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IACrC,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,OAAO,oLAQE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,8BACd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,8BACxB,sBAAsB,CAAC,QAAQ,CAAC,+CAM9C,yBAAyB,EAAE,iBAE3B,yBAAyB,EAAE,80GAsFG,SAAS,oqDAqDxC,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"csv-file.d.ts","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,WACpB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAuBpC,CAAA;AAOD,eAAO,MAAM,sBAAsB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAgFxE,CAAA;AAGD,eAAO,MAAM,uBAAuB,YAAa,GAAG,KAAG,MA+CtD,CAAA"}
1
+ {"version":3,"file":"csv-file.d.ts","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,iBAAiB,WACpB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA8BpC,CAAA;AAyKD,eAAO,MAAM,sBAAsB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAqIxE,CAAA;AAGD,eAAO,MAAM,uBAAuB,YAAa,GAAG,KAAG,MA+CtD,CAAA"}
@@ -1,11 +1,18 @@
1
+ import { generateDateFormatterCode, generateSortFilterHelperCode, generateSafeJSONParseCode, } from '../utils';
2
+ import { generateHeaderDetectionCode } from './utils/header-detection';
1
3
  export var validateCSVConfig = function (config) {
2
4
  if (!config || typeof config !== 'object') {
3
5
  return { isValid: false, error: 'Config must be a valid object' };
4
6
  }
5
- if (!config.parsedData || !Array.isArray(config.parsedData)) {
7
+ if (!config.fileContent && !config.parsedData) {
8
+ return { isValid: false, error: 'Either fileContent or parsedData must be provided' };
9
+ }
10
+ if (config.fileContent && typeof config.fileContent !== 'string') {
11
+ return { isValid: false, error: 'File content must be a string' };
12
+ }
13
+ if (config.parsedData && !Array.isArray(config.parsedData)) {
6
14
  return { isValid: false, error: 'Parsed data must be an array' };
7
15
  }
8
- // Columns are optional - if not provided, we'll infer them from parsedData
9
16
  if (config.columns !== undefined) {
10
17
  if (!Array.isArray(config.columns)) {
11
18
  return { isValid: false, error: 'Columns definition must be an array' };
@@ -19,9 +26,22 @@ export var validateCSVConfig = function (config) {
19
26
  }
20
27
  return { isValid: true };
21
28
  };
29
+ var generateHandlerBody = function () {
30
+ return "\n try {\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset: offsetParam } = req.query\n \n const labelToIdMap = {}\n columns.forEach((col) => {\n if (col.label && col.id) {\n labelToIdMap[col.label] = col.id\n }\n })\n \n let filteredData = [...data]\n \n if (query) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n const searchColumns = safeJSONParse(queryColumns)\n filteredData = filteredData.filter((item) => {\n return searchColumns.some((col) => {\n const field = labelToIdMap[col] || col\n const value = getNestedValue(item, field)\n return value && String(value).toLowerCase().includes(searchQuery)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n try {\n const stringified = JSON.stringify(item).toLowerCase()\n return stringified.includes(searchQuery)\n } catch {\n return false\n }\n })\n }\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n filteredData = filteredData.filter((item) => {\n return parsedFilters.every((filter) => {\n if (!filter.source || filter.destination === undefined) return true\n \n const field = labelToIdMap[filter.source] || filter.source\n const value = getNestedValue(item, field)\n const target = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(target)) {\n if (operand === '!=') {\n return !target.includes(value)\n }\n return target.includes(value)\n }\n \n return compareValues(value, target, operand)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n const field = labelToIdMap[key] || key\n const itemValue = getNestedValue(item, field)\n if (Array.isArray(value)) {\n return value.includes(itemValue)\n }\n return compareValues(itemValue, value, '=')\n })\n })\n }\n }\n \n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n filteredData.sort((a, b) => {\n for (const sort of parsedSorts) {\n if (!sort.field) continue\n const field = labelToIdMap[sort.field] || sort.field\n const aVal = getNestedValue(a, field)\n const bVal = getNestedValue(b, field)\n const sortOrderValue = sort.order?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n if (comparison !== 0) return comparison * sortOrderValue\n }\n return 0\n })\n }\n } else if (sortBy) {\n const field = labelToIdMap[sortBy] || sortBy\n filteredData.sort((a, b) => {\n const aVal = getNestedValue(a, field)\n const bVal = getNestedValue(b, field)\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n return comparison * sortOrderValue\n })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offsetParam !== undefined ? parseInt(offsetParam) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : 0)\n \n if (limitValue) {\n filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))\n }\n \n const safeData = JSON.parse(JSON.stringify(filteredData, dateReplacer))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('CSV 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";
31
+ };
22
32
  export var generateCSVFileFetcher = function (config) {
23
33
  var csvConfig = config;
24
- return "const data = ".concat(JSON.stringify(csvConfig.parsedData || []), "\n\nexport default async function handler(req, res) {\n try {\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query\n \n let filteredData = [...data]\n \n if (query) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n const columns = JSON.parse(queryColumns)\n filteredData = filteredData.filter((item) => {\n return columns.some((col) => {\n const value = item[col]\n return value && String(value).toLowerCase().includes(searchQuery)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n try {\n const stringified = JSON.stringify(item).toLowerCase()\n return stringified.includes(searchQuery)\n } catch {\n return false\n }\n })\n }\n }\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n filteredData = filteredData.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n if (Array.isArray(value)) {\n return value.includes(item[key])\n }\n return item[key] === value\n })\n })\n }\n \n if (sortBy) {\n filteredData.sort((a, b) => {\n const aVal = a[sortBy]\n const bVal = b[sortBy]\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offsetParam !== undefined ? parseInt(offsetParam) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : 0)\n \n if (limitValue) {\n filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))\n }\n \n const safeData = JSON.parse(JSON.stringify(filteredData))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('CSV 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
+ // Get header detection flags, ensuring boolean false values are preserved
35
+ var autoDetectHeader = csvConfig.autoDetectHeader !== false;
36
+ var firstRowIsHeader = csvConfig.firstRowIsHeader !== false;
37
+ var configColumns = csvConfig.columns || [];
38
+ if (csvConfig.fileContent) {
39
+ var fileContent = csvConfig.fileContent;
40
+ return "const csvContent = ".concat(JSON.stringify(fileContent), "\nconst autoDetectHeader = ").concat(autoDetectHeader, "\nconst firstRowIsHeader = ").concat(firstRowIsHeader, "\nconst configColumns = ").concat(JSON.stringify(configColumns), "\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\n").concat(generateSortFilterHelperCode(), "\n\n").concat(generateHeaderDetectionCode(), "\n\nfunction parseCSVLine(line) {\n const result = []\n let current = ''\n let inQuotes = false\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i]\n const nextChar = line[i + 1]\n\n if (char === '\"') {\n if (inQuotes && nextChar === '\"') {\n current += '\"'\n i++\n } else {\n inQuotes = !inQuotes\n }\n } else if (char === ',' && !inQuotes) {\n result.push(current)\n current = ''\n } else {\n current += char\n }\n }\n\n result.push(current)\n return result\n}\n\nfunction parseCSVContent(content, autoDetect, firstRowHeader, columns) {\n const lines = content.split('\\n').filter((line) => line.trim())\n \n if (lines.length === 0) {\n return { columns: [], rows: [] }\n }\n \n const allRowValues = lines.map((line) => parseCSVLine(line))\n const firstRowValues = allRowValues[0]\n \n if (firstRowValues.length === 0) {\n return { columns: [], rows: [] }\n }\n \n const shouldAutoDetect = autoDetect !== false\n let hasHeaderRow = false\n \n if (shouldAutoDetect) {\n hasHeaderRow = detectHeaderRow(firstRowValues, allRowValues)\n } else {\n hasHeaderRow = firstRowHeader !== false\n }\n \n const useConfigColumns = columns && columns.length > 0\n let parsedColumns\n let dataStartIndex\n \n if (hasHeaderRow && allRowValues.length > 1) {\n parsedColumns = firstRowValues.map((header, index) => {\n const configCol = useConfigColumns ? columns[index] : null\n return {\n id: configCol?.id || `col_${index}`,\n label: String(header || configCol?.label || `Column ${index + 1}`),\n type: configCol?.type || 'string'\n }\n })\n dataStartIndex = 1\n } else {\n parsedColumns = firstRowValues.map((_, index) => {\n const configCol = useConfigColumns ? columns[index] : null\n return {\n id: configCol?.id || `col_${index}`,\n label: configCol?.label || `Column ${index + 1}`,\n type: configCol?.type || 'string'\n }\n })\n dataStartIndex = 0\n }\n \n const rows = []\n for (let i = dataStartIndex; i < allRowValues.length; i++) {\n const values = allRowValues[i]\n const row = {}\n parsedColumns.forEach((col, index) => {\n const value = values[index]?.trim() || null\n row[col.id] = value\n })\n rows.push(row)\n }\n \n return { columns: parsedColumns, rows }\n}\n\nconst { columns, rows: data } = parseCSVContent(csvContent, autoDetectHeader, firstRowIsHeader, configColumns)\n\nexport default async function handler(req, res) {").concat(generateHandlerBody(), "\n}\n");
41
+ }
42
+ else {
43
+ return "const data = ".concat(JSON.stringify(csvConfig.parsedData || []), "\nconst columns = ").concat(JSON.stringify(configColumns), "\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\n").concat(generateSortFilterHelperCode(), "\n\nexport default async function handler(req, res) {").concat(generateHandlerBody(), "\n}\n");
44
+ }
25
45
  };
26
46
  // tslint:disable-next-line:variable-name
27
47
  export var generateCSVCountFetcher = function (_config) {
@@ -1 +1 @@
1
- {"version":3,"file":"csv-file.js","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAC/B,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,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAA;KACjE;IAED,2EAA2E;IAC3E,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE;QAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAA;SACxE;QAED,KAAqB,UAAc,EAAd,KAAA,MAAM,CAAC,OAAO,EAAd,cAAc,EAAd,IAAc,EAAE;YAAhC,IAAM,MAAM,SAAA;YACf,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAE;gBACxF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAA;aACrE;SACF;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAOD,MAAM,CAAC,IAAM,sBAAsB,GAAG,UAAC,MAA+B;IACpE,IAAM,SAAS,GAAG,MAAuB,CAAA;IACzC,OAAO,uBAAgB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC,mzEA6ElE,CAAA;AACD,CAAC,CAAA;AAED,yCAAyC;AACzC,MAAM,CAAC,IAAM,uBAAuB,GAAG,UAAC,OAAY;IAClD,OAAO,knCA6CR,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"csv-file.js","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"firestore.d.ts","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAyBpC,CAAA;AAOD,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAkIF,CAAA"}
1
+ {"version":3,"file":"firestore.d.ts","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAyBpC,CAAA;AAOD,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAkLF,CAAA"}
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils';
1
+ import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, } from '../utils';
2
2
  export var validateFirestoreConfig = function (config) {
3
3
  if (!config || typeof config !== 'object') {
4
4
  return { isValid: false, error: 'Config must be a valid object' };
@@ -25,6 +25,6 @@ export var validateFirestoreConfig = function (config) {
25
25
  export var generateFirestoreFetcher = function (config, tableName) {
26
26
  var firestoreConfig = config;
27
27
  var serviceAccount = firestoreConfig.serviceAccount;
28
- return "import * as admin from 'firebase-admin'\n\nlet firestore = null\n\nconst getFirestore = () => {\n if (firestore) return firestore\n \n const rawServiceAccount = ".concat(replaceSecretReference(serviceAccount), "\n let serviceAccount\n\n try {\n serviceAccount = JSON.parse(rawServiceAccount)\n } catch (error) {\n throw new Error('Invalid Firestore service account JSON: ' + error.message)\n }\n \n if (!admin.apps.length) {\n admin.initializeApp({\n credential: admin.credential.cert(serviceAccount)\n })\n }\n \n firestore = admin.firestore()\n return firestore\n}\n\nexport default async function handler(req, res) {\n try {\n const firestore = getFirestore()\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset } = req.query\n \n let queryRef = firestore.collection('").concat(tableName, "')\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n queryRef = queryRef.where(key, 'in', value)\n } else {\n queryRef = queryRef.where(key, '==', value)\n }\n })\n }\n \n let usePostFiltering = false\n \n if (query) {\n if (queryColumns) {\n const columns = typeof queryColumns === 'string' ? JSON.parse(queryColumns) : (Array.isArray(queryColumns) ? queryColumns : [queryColumns])\n for (const column of columns) {\n queryRef = queryRef\n .where(column, '>=', query)\n .where(column, '<=', query + '\\uf8ff')\n }\n } else {\n // Firestore doesn't support full-text search without queryColumns\n // We'll fetch all data and filter in JavaScript\n usePostFiltering = true\n }\n }\n \n if (sortBy) {\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? 'desc' : 'asc'\n queryRef = queryRef.orderBy(sortBy, sortOrderValue)\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage && parseInt(page) > 1 ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n // Only apply pagination at query level if not post-filtering\n if (!usePostFiltering) {\n if (limitValue) {\n queryRef = queryRef.limit(parseInt(limitValue))\n }\n if (offsetValue !== undefined) {\n queryRef = queryRef.offset(offsetValue)\n }\n }\n \n const snapshot = await queryRef.get()\n let documents = []\n snapshot.forEach((doc) => {\n documents.push({\n id: doc.id,\n ...doc.data()\n })\n })\n \n // Apply post-filtering if needed\n if (usePostFiltering && query) {\n const searchQuery = query.toLowerCase()\n documents = documents.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 // Apply pagination after filtering\n if (limitValue) {\n const start = offsetValue || 0\n documents = documents.slice(start, start + parseInt(limitValue))\n } else if (offsetValue) {\n documents = documents.slice(offsetValue)\n }\n }\n \n const safeData = JSON.parse(JSON.stringify(documents))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Firestore 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");
28
+ return "import * as admin from 'firebase-admin'\n\nlet firestore = null\n\nconst getFirestore = () => {\n if (firestore) return firestore\n \n const rawServiceAccount = ".concat(replaceSecretReference(serviceAccount), "\n let serviceAccount\n\n try {\n serviceAccount = JSON.parse(rawServiceAccount)\n } catch (error) {\n throw new Error('Invalid Firestore service account JSON: ' + error.message)\n }\n \n if (!admin.apps.length) {\n admin.initializeApp({\n credential: admin.credential.cert(serviceAccount)\n })\n }\n \n firestore = admin.firestore()\n return firestore\n}\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\nexport default async function handler(req, res) {\n try {\n const firestore = getFirestore()\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n let queryRef = firestore.collection('").concat(tableName, "')\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 = filter.source\n const value = filter.destination\n const operand = filter.operand || '='\n \n // Map operands to Firestore operators\n const operatorMap = {\n '=': '==',\n '!=': '!=',\n '>': '>',\n '<': '<',\n '>=': '>=',\n '<=': '<=',\n }\n \n if (Array.isArray(value)) {\n if (value.length === 0) return\n if (operand === '!=') {\n queryRef = queryRef.where(field, 'not-in', value)\n } else {\n queryRef = queryRef.where(field, 'in', value)\n }\n } else {\n const firestoreOp = operatorMap[operand] || '=='\n queryRef = queryRef.where(field, firestoreOp, value)\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n queryRef = queryRef.where(key, 'in', value)\n } else {\n queryRef = queryRef.where(key, '==', value)\n }\n })\n }\n }\n \n let usePostFiltering = false\n \n if (query) {\n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n const columns = Array.isArray(parsed) ? parsed : [parsed]\n for (const column of columns) {\n queryRef = queryRef\n .where(column, '>=', query)\n .where(column, '<=', query + '\\uf8ff')\n }\n } else {\n // Firestore doesn't support full-text search without queryColumns\n // We'll fetch all data and filter in JavaScript\n usePostFiltering = true\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 parsedSorts.forEach((sort) => {\n if (!sort.field) return\n const order = sort.order?.toLowerCase() === 'desc' ? 'desc' : 'asc'\n queryRef = queryRef.orderBy(sort.field, order)\n })\n }\n } else if (sortBy) {\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? 'desc' : 'asc'\n queryRef = queryRef.orderBy(sortBy, sortOrderValue)\n }\n \n const limitValue = limit || perPage\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage && parseInt(page) > 1 ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n // Only apply pagination at query level if not post-filtering\n if (!usePostFiltering) {\n if (limitValue) {\n queryRef = queryRef.limit(parseInt(limitValue))\n }\n if (offsetValue !== undefined) {\n queryRef = queryRef.offset(offsetValue)\n }\n }\n \n const snapshot = await queryRef.get()\n let documents = []\n snapshot.forEach((doc) => {\n documents.push({\n id: doc.id,\n ...doc.data()\n })\n })\n \n // Apply post-filtering if needed\n if (usePostFiltering && query) {\n const searchQuery = query.toLowerCase()\n documents = documents.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 // Apply pagination after filtering\n if (limitValue) {\n const start = offsetValue || 0\n documents = documents.slice(start, start + parseInt(limitValue))\n } else if (offsetValue) {\n documents = documents.slice(offsetValue)\n }\n }\n \n const safeData = JSON.parse(JSON.stringify(documents, 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('Firestore 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");
29
29
  };
30
30
  //# sourceMappingURL=firestore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"firestore.js","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,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,cAAc,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE;QACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAA;KAC/E;IAED,IAAM,cAAc,GAAG,MAAM,CAAC,cAAwB,CAAA;IAEtD,iGAAiG;IACjG,sEAAsE;IACtE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE;QACrD,IAAI;YACF,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YACzC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;gBACrE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAA;aACrF;SACF;QAAC,WAAM;YACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAA;SACvE;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAOD,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,eAAe,GAAG,MAAyB,CAAA;IACjD,IAAM,cAAc,GAAG,eAAe,CAAC,cAAc,CAAA;IAErD,OAAO,8KAOqB,sBAAsB,CAAC,cAAc,CAAC,yoBAwBzB,SAAS,o2FA8FnD,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"firestore.js","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,UAAU,CAAA;AAEjB,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,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,cAAc,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE;QACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAA;KAC/E;IAED,IAAM,cAAc,GAAG,MAAM,CAAC,cAAwB,CAAA;IAEtD,iGAAiG;IACjG,sEAAsE;IACtE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE;QACrD,IAAI;YACF,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YACzC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;gBACrE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAA;aACrF;SACF;QAAC,WAAM;YACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAA;SACvE;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAOD,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,eAAe,GAAG,MAAyB,CAAA;IACjD,IAAM,cAAc,GAAG,eAAe,CAAC,cAAc,CAAA;IAErD,OAAO,8KAOqB,sBAAsB,CAAC,cAAc,CAAC,+YAmBlE,yBAAyB,EAAE,iBAE3B,yBAAyB,EAAE,kRAOc,SAAS,uyIA0InD,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"google-sheets.d.ts","sourceRoot":"","sources":["../../../src/fetchers/google-sheets.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,WAC7B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAwBpC,CAAA;AAWD,eAAO,MAAM,2BAA2B,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAuJ7E,CAAA"}
1
+ {"version":3,"file":"google-sheets.d.ts","sourceRoot":"","sources":["../../../src/fetchers/google-sheets.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,0BAA0B,WAC7B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAwBpC,CAAA;AAcD,eAAO,MAAM,2BAA2B,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MA0W7E,CAAA"}
@@ -1,3 +1,5 @@
1
+ import { generateSortFilterHelperCode, generateSafeJSONParseCode } from '../utils';
2
+ import { generateHeaderDetectionCode } from './utils/header-detection';
1
3
  export var validateGoogleSheetsConfig = function (config) {
2
4
  if (!config || typeof config !== 'object') {
3
5
  return { isValid: false, error: 'Config must be a valid object' };
@@ -20,6 +22,9 @@ export var validateGoogleSheetsConfig = function (config) {
20
22
  };
21
23
  export var generateGoogleSheetsFetcher = function (config) {
22
24
  var sheetsConfig = config;
23
- return "import fetch from 'node-fetch'\n\nexport default async function handler(req, res) {\n try {\n const sheetUrl = ".concat(JSON.stringify(sheetsConfig.sheetUrl), "\n let sheetId = ").concat(JSON.stringify(sheetsConfig.sheetId), "\n const range = ").concat(JSON.stringify(sheetsConfig.range || 'A1:Z1000'), "\n const maxRows = ").concat(sheetsConfig.maxRows || 0, "\n \n if (!sheetId && sheetUrl) {\n const match = sheetUrl.match(/\\/d\\/([a-zA-Z0-9-_]+)/)\n sheetId = match ? match[1] : undefined\n }\n \n if (!sheetId) {\n return res.status(400).json({\n success: false,\n error: 'Invalid Google Sheets URL or Sheet ID',\n timestamp: Date.now()\n })\n }\n \n let url = `https://docs.google.com/spreadsheets/d/${sheetId}/gviz/tq?tqx=out:json&range=${range}`\n \n if (maxRows && maxRows > 0) {\n url += `&tq=limit ${maxRows}`\n }\n \n const response = await fetch(url)\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 const text = await response.text()\n const jsonMatch = text.match(/google\\.visualization\\.Query\\.setResponse\\((.*)\\);/)\n \n if (!jsonMatch) {\n return res.status(500).json({\n success: false,\n error: 'Unable to parse Google Sheets response',\n timestamp: Date.now()\n })\n }\n \n const data = JSON.parse(jsonMatch[1])\n \n if (data.status === 'error') {\n return res.status(500).json({\n success: false,\n error: data.errors?.[0]?.detailed_message || 'Failed to fetch Google Sheets data',\n timestamp: Date.now()\n })\n }\n \n const table = data.table\n const columns = table.cols.map((col, index) => ({\n id: col.id || `col_${index}`,\n label: col.label || `Column ${index + 1}`,\n type: col.type || 'string'\n }))\n \n const rows = table.rows.map((row) => {\n const rowData = {}\n row.c.forEach((cell, index) => {\n const columnId = columns[index].id\n rowData[columnId] = cell?.v ?? null\n })\n return rowData\n })\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query\n \n let filteredData = [...rows]\n \n if (query) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n const searchColumns = JSON.parse(queryColumns)\n filteredData = filteredData.filter((item) => {\n return searchColumns.some((col) => {\n const value = item[col]\n return value && String(value).toLowerCase().includes(searchQuery)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n try {\n const stringified = JSON.stringify(item).toLowerCase()\n return stringified.includes(searchQuery)\n } catch {\n return false\n }\n })\n }\n }\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n filteredData = filteredData.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n if (Array.isArray(value)) {\n return value.includes(item[key])\n }\n return item[key] === value\n })\n })\n }\n \n if (sortBy) {\n filteredData.sort((a, b) => {\n const aVal = a[sortBy]\n const bVal = b[sortBy]\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offsetParam !== undefined ? parseInt(offsetParam) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : 0)\n \n if (limitValue) {\n filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))\n }\n \n const safeData = JSON.parse(JSON.stringify(filteredData))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Google Sheets 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");
25
+ var autoDetectHeader = sheetsConfig.autoDetectHeader;
26
+ var firstRowIsHeader = sheetsConfig.firstRowIsHeader;
27
+ var configColumns = sheetsConfig.columns || [];
28
+ return "import fetch from 'node-fetch'\n\n".concat(generateSafeJSONParseCode(), "\n\n").concat(generateSortFilterHelperCode(), "\n\n").concat(generateHeaderDetectionCode(), "\n\nexport default async function handler(req, res) {\n try {\n const sheetUrl = ").concat(JSON.stringify(sheetsConfig.sheetUrl), "\n let sheetId = ").concat(JSON.stringify(sheetsConfig.sheetId), "\n const range = ").concat(JSON.stringify(sheetsConfig.range || 'A1:Z1000'), "\n const maxRows = ").concat(sheetsConfig.maxRows || 0, "\n const autoDetectHeader = ").concat(autoDetectHeader !== undefined ? autoDetectHeader : true, "\n const firstRowIsHeader = ").concat(firstRowIsHeader !== undefined ? firstRowIsHeader : true, "\n \n if (!sheetId && sheetUrl) {\n const match = sheetUrl.match(/\\/d\\/([a-zA-Z0-9-_]+)/)\n sheetId = match ? match[1] : undefined\n }\n \n if (!sheetId) {\n return res.status(400).json({\n success: false,\n error: 'Invalid Google Sheets URL or Sheet ID',\n timestamp: Date.now()\n })\n }\n \n let gid = undefined\n if (sheetUrl) {\n const gidMatch = sheetUrl.match(/[#&]gid=([0-9]+)/)\n gid = gidMatch ? gidMatch[1] : undefined\n }\n \n let url = `https://docs.google.com/spreadsheets/d/${sheetId}/gviz/tq?tqx=out:json&range=${range}`\n \n if (gid) {\n url += `&gid=${gid}`\n }\n \n if (maxRows && maxRows > 0) {\n url += `&tq=limit ${maxRows}`\n }\n \n const response = await fetch(url)\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 const text = await response.text()\n const jsonMatch = text.match(/google\\.visualization\\.Query\\.setResponse\\((.*)\\);/)\n \n if (!jsonMatch) {\n return res.status(500).json({\n success: false,\n error: 'Unable to parse Google Sheets response',\n timestamp: Date.now()\n })\n }\n \n const data = JSON.parse(jsonMatch[1])\n \n if (data.status === 'error') {\n return res.status(500).json({\n success: false,\n error: data.errors?.[0]?.detailed_message || 'Failed to fetch Google Sheets data',\n timestamp: Date.now()\n })\n }\n \n const formatDateValue = (date) => {\n const options = {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }\n \n const timeOptions = {\n hour: '2-digit',\n minute: '2-digit',\n }\n \n const hasTime = date.getHours() !== 0 || date.getMinutes() !== 0 || date.getSeconds() !== 0\n \n if (hasTime) {\n return date.toLocaleString('en-US', { ...options, ...timeOptions })\n }\n \n return date.toLocaleDateString('en-US', options)\n }\n \n const parseGoogleSheetsValue = (value) => {\n if (typeof value === 'string') {\n const dateMatch = value.match(/^Date\\((\\d+),(\\d+),(\\d+)(?:,(\\d+),(\\d+),(\\d+))?\\)$/)\n if (dateMatch) {\n const year = parseInt(dateMatch[1], 10)\n const month = parseInt(dateMatch[2], 10)\n const day = parseInt(dateMatch[3], 10)\n const hour = dateMatch[4] ? parseInt(dateMatch[4], 10) : 0\n const minute = dateMatch[5] ? parseInt(dateMatch[5], 10) : 0\n const second = dateMatch[6] ? parseInt(dateMatch[6], 10) : 0\n const date = new Date(year, month, day, hour, minute, second)\n return formatDateValue(date)\n }\n }\n return value\n }\n \n const table = data.table\n const rawRows = table.rows || []\n \n if (rawRows.length === 0) {\n return res.status(200).json({\n success: true,\n data: [],\n timestamp: Date.now()\n })\n }\n \n const firstRow = rawRows[0]\n const firstRowValues = firstRow.c.map((cell) => cell?.v ?? cell?.f ?? null)\n \n const shouldAutoDetect = autoDetectHeader !== false\n let hasHeaderRow = false\n \n if (shouldAutoDetect) {\n hasHeaderRow = detectHeaderRow(firstRowValues, rawRows)\n } else {\n hasHeaderRow = firstRowIsHeader !== false\n }\n \n const configColumns = ").concat(JSON.stringify(configColumns), "\n const useConfigColumns = configColumns && configColumns.length > 0\n \n let columns\n let dataRows\n \n if (hasHeaderRow && rawRows.length > 1) {\n columns = table.cols.map((col, index) => {\n const configCol = useConfigColumns ? configColumns[index] : null\n return {\n id: configCol?.id || col.id || `col_${index}`,\n label: String(firstRowValues[index] || col.label || configCol?.label || `Column ${index + 1}`),\n type: configCol?.type || col.type || 'string'\n }\n })\n dataRows = rawRows.slice(1)\n } else {\n columns = table.cols.map((col, index) => {\n const configCol = useConfigColumns ? configColumns[index] : null\n return {\n id: configCol?.id || col.id || `col_${index}`,\n label: configCol?.label || col.label || `Column ${index + 1}`,\n type: configCol?.type || col.type || 'string'\n }\n })\n dataRows = rawRows\n }\n \n if (maxRows && dataRows.length > maxRows) {\n dataRows = dataRows.slice(0, maxRows)\n }\n \n const rows = dataRows.map((row) => {\n const rowData = {}\n row.c.forEach((cell, index) => {\n const columnId = columns[index]?.id || `col_${index}`\n const rawValue = cell?.v ?? cell?.f ?? null\n rowData[columnId] = parseGoogleSheetsValue(rawValue)\n })\n return rowData\n })\n \n const columnsWithData = columns.filter((col, index) => {\n const hasHeaderData = col.label && col.label !== `Column ${index + 1}`\n const hasDataInColumn = rows.some((row) => {\n const value = row[col.id]\n return value !== null && value !== undefined && value !== ''\n })\n return hasHeaderData || hasDataInColumn\n })\n \n const filteredRows = rows.map((row) => {\n const filteredRow = {}\n columnsWithData.forEach((col) => {\n filteredRow[col.id] = row[col.id]\n })\n return filteredRow\n })\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset: offsetParam } = req.query\n \n // Create label-to-ID mapping for filters and sorts\n const labelToIdMap = {}\n columnsWithData.forEach((col) => {\n labelToIdMap[col.label] = col.id\n })\n \n let filteredData = [...filteredRows]\n \n if (query) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n const searchColumns = safeJSONParse(queryColumns)\n filteredData = filteredData.filter((item) => {\n return searchColumns.some((col) => {\n // Map label to column ID\n const field = labelToIdMap[col] || col\n const value = getNestedValue(item, field)\n return value && String(value).toLowerCase().includes(searchQuery)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n try {\n const stringified = JSON.stringify(item).toLowerCase()\n return stringified.includes(searchQuery)\n } catch {\n return false\n }\n })\n }\n }\n \n if (filters) {\n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n filteredData = filteredData.filter((item) => {\n return parsedFilters.every((filter) => {\n if (!filter.source || filter.destination === undefined) return true\n \n // Map label to column ID\n const field = labelToIdMap[filter.source] || filter.source\n const value = getNestedValue(item, field)\n const target = filter.destination\n const operand = filter.operand || '='\n \n if (Array.isArray(target)) {\n if (operand === '!=') {\n return !target.includes(value)\n }\n return target.includes(value)\n }\n \n return compareValues(value, target, operand)\n })\n })\n } else {\n filteredData = filteredData.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n // Map label to column ID\n const field = labelToIdMap[key] || key\n const itemValue = getNestedValue(item, field)\n if (Array.isArray(value)) {\n return value.includes(itemValue)\n }\n return compareValues(itemValue, value, '=')\n })\n })\n }\n }\n \n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n filteredData.sort((a, b) => {\n for (const sort of parsedSorts) {\n if (!sort.field) continue\n // Map label to column ID\n const field = labelToIdMap[sort.field] || sort.field\n const aVal = getNestedValue(a, field)\n const bVal = getNestedValue(b, field)\n const sortOrderValue = sort.order?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n if (comparison !== 0) return comparison * sortOrderValue\n }\n return 0\n })\n }\n } else if (sortBy) {\n filteredData.sort((a, b) => {\n // Map label to column ID\n const field = labelToIdMap[sortBy] || sortBy\n const aVal = getNestedValue(a, field)\n const bVal = getNestedValue(b, field)\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n \n let comparison = 0\n if (aVal === null || aVal === undefined) {\n comparison = bVal === null || bVal === undefined ? 0 : -1\n } else if (bVal === null || bVal === undefined) {\n comparison = 1\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal instanceof Date && bVal instanceof Date) {\n comparison = aVal.getTime() - bVal.getTime()\n } else {\n const aStr = String(aVal)\n const bStr = String(bVal)\n if (aStr < bStr) comparison = -1\n else if (aStr > bStr) comparison = 1\n }\n \n return comparison * sortOrderValue\n })\n }\n \n const limitValue = limit || perPage\n const offsetValue = offsetParam !== undefined ? parseInt(offsetParam) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : 0)\n \n if (limitValue) {\n filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))\n }\n \n const safeData = JSON.parse(JSON.stringify(filteredData))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Google Sheets 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");
24
29
  };
25
30
  //# sourceMappingURL=google-sheets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"google-sheets.js","sourceRoot":"","sources":["../../../src/fetchers/google-sheets.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,0BAA0B,GAAG,UACxC,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,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;QACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAA;KACxE;IAED,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE;QACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAA;KAC9D;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;YACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAA;SAC/D;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE;YAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAA;SACrE;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAWD,MAAM,CAAC,IAAM,2BAA2B,GAAG,UAAC,MAA+B;IACzE,IAAM,YAAY,GAAG,MAA4B,CAAA;IACjD,OAAO,6HAIc,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,iCACxC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,iCACpC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,UAAU,CAAC,mCAC9C,YAAY,CAAC,OAAO,IAAI,CAAC,goIA6I9C,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"google-sheets.js","sourceRoot":"","sources":["../../../src/fetchers/google-sheets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAClF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AAEtE,MAAM,CAAC,IAAM,0BAA0B,GAAG,UACxC,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,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;QACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAA;KACxE;IAED,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE;QACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAA;KAC9D;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;YACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAA;SAC/D;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE;YAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAA;SACrE;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAcD,MAAM,CAAC,IAAM,2BAA2B,GAAG,UAAC,MAA+B;IACzE,IAAM,YAAY,GAAG,MAA4B,CAAA;IACjD,IAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAA;IACtD,IAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAA;IACtD,IAAM,aAAa,GAAG,YAAY,CAAC,OAAO,IAAI,EAAE,CAAA;IAEhD,OAAO,4CAEP,yBAAyB,EAAE,iBAE3B,4BAA4B,EAAE,iBAE9B,2BAA2B,EAAE,kGAIR,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,iCACxC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,iCACpC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,UAAU,CAAC,mCAC9C,YAAY,CAAC,OAAO,IAAI,CAAC,4CAChB,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,4CACxD,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,6iHA2H3D,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,gqPAyNxD,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../../src/fetchers/javascript.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA2BpC,CAAA;AAMD,eAAO,MAAM,yBAAyB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAmG3E,CAAA;AAGD,eAAO,MAAM,8BAA8B,YAAa,GAAG,KAAG,MA+C7D,CAAA"}
1
+ {"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../../src/fetchers/javascript.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,wBAAwB,WAC3B,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CA2BpC,CAAA;AAMD,eAAO,MAAM,yBAAyB,WAAY,OAAO,MAAM,EAAE,OAAO,CAAC,KAAG,MAgL3E,CAAA;AAGD,eAAO,MAAM,8BAA8B,YAAa,GAAG,KAAG,MA+C7D,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { generateDateFormatterCode, generateSortFilterHelperCode, generateSafeJSONParseCode, } from '../utils';
1
2
  export var validateJavaScriptConfig = function (config) {
2
3
  if (!config || typeof config !== 'object') {
3
4
  return { isValid: false, error: 'Config must be a valid object' };
@@ -25,7 +26,7 @@ export var validateJavaScriptConfig = function (config) {
25
26
  };
26
27
  export var generateJavaScriptFetcher = function (config) {
27
28
  var jsConfig = config;
28
- return "export default async function handler(req, res) {\n try {\n const { limit, offset, page, perPage, query, queryColumns, sortBy, sortOrder, filters } = req.query\n \n const code = ".concat(JSON.stringify(jsConfig.code), "\n const executeCode = new Function('return ' + code)\n let data = executeCode()\n \n if (Array.isArray(data)) {\n // 1. Apply search filter\n if (query && query.trim()) {\n const searchQuery = query.toLowerCase()\n \n if (queryColumns) {\n try {\n const columns = typeof queryColumns === 'string' ? JSON.parse(queryColumns) : (Array.isArray(queryColumns) ? queryColumns : [queryColumns])\n data = data.filter(item => {\n return columns.some(col => {\n const value = 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 // 2. Apply custom filters\n if (filters) {\n try {\n const parsedFilters = typeof filters === 'string' ? JSON.parse(filters) : filters\n data = data.filter((item) => {\n return Object.entries(parsedFilters).every(([key, value]) => {\n if (Array.isArray(value)) {\n return value.includes(item[key])\n }\n return item[key] === value\n })\n })\n } catch (err) {\n console.error('Error parsing filters:', err)\n }\n }\n \n // 3. Apply sorting\n if (sortBy && sortBy.trim()) {\n data.sort((a, b) => {\n const aVal = a[sortBy]\n const bVal = b[sortBy]\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n if (aVal < bVal) return -sortOrderValue\n if (aVal > bVal) return sortOrderValue\n return 0\n })\n }\n \n // 4. Apply pagination\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))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('JavaScript execution error:', error)\n return res.status(500).json({\n success: false,\n error: error.message || 'Failed to execute code',\n timestamp: Date.now()\n })\n }\n}\n");
29
+ return "".concat(generateSafeJSONParseCode(), "\n\n").concat(generateDateFormatterCode(), "\n\n").concat(generateSortFilterHelperCode(), "\n\nexport default async function handler(req, res) {\n try {\n const { limit, offset, page, perPage, query, queryColumns, sortBy, sortOrder, filters, sorts } = req.query\n \n const code = ").concat(JSON.stringify(jsConfig.code), "\n const executeCode = new Function('return ' + code)\n let data = executeCode()\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('JavaScript execution error:', error)\n return res.status(500).json({\n success: false,\n error: error.message || 'Failed to execute code',\n timestamp: Date.now()\n })\n }\n}\n");
29
30
  };
30
31
  // tslint:disable-next-line:variable-name
31
32
  export var generateJavaScriptCountFetcher = function (_config) {
@@ -1 +1 @@
1
- {"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/fetchers/javascript.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,MAA+B;IAE/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAA;KAClE;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAChF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;KAChE;IAED,IAAM,iBAAiB,GAAG;QACxB,eAAe;QACf,YAAY;QACZ,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,cAAc;KACf,CAAA;IAED,KAAsB,UAAiB,EAAjB,uCAAiB,EAAjB,+BAAiB,EAAjB,IAAiB,EAAE;QAApC,IAAM,OAAO,0BAAA;QAChB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC7B,OAAO,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAA;YAC9F,MAAK;SACN;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAMD,MAAM,CAAC,IAAM,yBAAyB,GAAG,UAAC,MAA+B;IACvE,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,OAAO,sMAIU,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,mjGA4F/C,CAAA;AACD,CAAC,CAAA;AAED,yCAAyC;AACzC,MAAM,CAAC,IAAM,8BAA8B,GAAG,UAAC,OAAY;IACzD,OAAO,gmCA6CR,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/fetchers/javascript.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,UAAU,CAAA;AAEjB,MAAM,CAAC,IAAM,wBAAwB,GAAG,UACtC,MAA+B;IAE/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAA;KAClE;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAChF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;KAChE;IAED,IAAM,iBAAiB,GAAG;QACxB,eAAe;QACf,YAAY;QACZ,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,WAAW;QACX,cAAc;KACf,CAAA;IAED,KAAsB,UAAiB,EAAjB,uCAAiB,EAAjB,+BAAiB,EAAjB,IAAiB,EAAE;QAApC,IAAM,OAAO,0BAAA;QAChB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC7B,OAAO,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAA;YAC9F,MAAK;SACN;KACF;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC,CAAA;AAMD,MAAM,CAAC,IAAM,yBAAyB,GAAG,UAAC,MAA+B;IACvE,IAAM,QAAQ,GAAG,MAA0B,CAAA;IAC3C,OAAO,UAAG,yBAAyB,EAAE,iBAErC,yBAAyB,EAAE,iBAE3B,4BAA4B,EAAE,oNAMb,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,4gMAmK/C,CAAA;AACD,CAAC,CAAA;AAED,yCAAyC;AACzC,MAAM,CAAC,IAAM,8BAA8B,GAAG,UAAC,OAAY;IACzD,OAAO,gmCA6CR,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"mariadb.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mariadb.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAyIF,CAAA;AAED,eAAO,MAAM,2BAA2B,WAC9B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA8GF,CAAA"}
1
+ {"version":3,"file":"mariadb.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mariadb.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAoMF,CAAA;AAED,eAAO,MAAM,2BAA2B,WAC9B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA0GF,CAAA"}
@@ -1,14 +1,14 @@
1
- import { replaceSecretReference } from '../utils';
1
+ import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, } from '../utils';
2
2
  export var generateMariaDBFetcher = function (config, tableName) {
3
3
  var mariaConfig = config;
4
4
  var database = mariaConfig.database;
5
- return "import mariadb from 'mariadb'\n\nexport default async function handler(req, res) {\n let connection = null\n try {\n connection = await mariadb.createConnection({\n host: ".concat(JSON.stringify(mariaConfig.host), ",\n port: ").concat(mariaConfig.port || 3306, ",\n user: ").concat(JSON.stringify(mariaConfig.user), ",\n password: ").concat(replaceSecretReference(mariaConfig.password), ",\n database: ").concat(JSON.stringify(mariaConfig.database), ",\n ssl: ").concat(mariaConfig.ssl || false).concat(mariaConfig.sslConfig
5
+ return "import mariadb from 'mariadb'\n\n".concat(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 = `\\`${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 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(`\\`${key}\\` IN (${placeholders})`)\n } else {\n conditions.push(`\\`${key}\\` = ?`)\n queryParams.push(value)\n }\n })\n }\n}\n\n").concat(generateDateFormatterCode(), "\n\nexport default async function handler(req, res) {\n let connection = null\n try {\n connection = await mariadb.createConnection({\n host: ").concat(JSON.stringify(mariaConfig.host), ",\n port: ").concat(mariaConfig.port || 3306, ",\n user: ").concat(JSON.stringify(mariaConfig.user), ",\n password: ").concat(replaceSecretReference(mariaConfig.password), ",\n database: ").concat(JSON.stringify(mariaConfig.database), ",\n ssl: ").concat(mariaConfig.ssl || false).concat(mariaConfig.sslConfig
6
6
  ? ",\n sslConfig: {\n ".concat(mariaConfig.sslConfig.ca ? "ca: ".concat(replaceSecretReference(mariaConfig.sslConfig.ca), ",") : '', "\n ").concat(mariaConfig.sslConfig.cert
7
7
  ? "cert: ".concat(replaceSecretReference(mariaConfig.sslConfig.cert), ",")
8
8
  : '', "\n ").concat(mariaConfig.sslConfig.key
9
9
  ? "key: ".concat(replaceSecretReference(mariaConfig.sslConfig.key), ",")
10
10
  : '', "\n rejectUnauthorized: ").concat(mariaConfig.sslConfig.rejectUnauthorized !== false, "\n }")
11
- : '', "\n })\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, 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 = JSON.parse(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(\\`${col}\\` AS CHAR) LIKE ?`)\n columns.forEach(() => queryParams.push(`%${query}%`))\n conditions.push(`(${searchConditions.join(' OR ')})`)\n }\n }\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\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(`\\`${key}\\` IN (${placeholders})`)\n } else {\n conditions.push(`\\`${key}\\` = ?`)\n queryParams.push(value)\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 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 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))\n \n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('MariaDB 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 MariaDB connection:', error)\n }\n }\n }\n}\n");
11
+ : '', "\n })\n \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(\\`${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 \\`").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 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('MariaDB 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 MariaDB connection:', error)\n }\n }\n }\n}\n");
12
12
  };
13
13
  export var generateMariaDBCountFetcher = function (config, tableName) {
14
14
  var mariaConfig = config;
@@ -19,6 +19,6 @@ export var generateMariaDBCountFetcher = function (config, tableName) {
19
19
  : '', "\n ").concat(mariaConfig.sslConfig.key
20
20
  ? "key: ".concat(replaceSecretReference(mariaConfig.sslConfig.key), ",")
21
21
  : '', "\n rejectUnauthorized: ").concat(mariaConfig.sslConfig.rejectUnauthorized !== false, "\n }")
22
- : '', "\n })\n \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 columns = typeof queryColumns === 'string' ? JSON.parse(queryColumns) : (Array.isArray(queryColumns) ? queryColumns : [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(${col} AS CHAR) LIKE ?`).join(' OR ')\n conditions.push(`(${searchConditions})`)\n columns.forEach(() => queryParams.push(`%${query}%`))\n }\n }\n\n if (filters) {\n const parsedFilters = JSON.parse(filters)\n for (const filter of parsedFilters) {\n conditions.push(`${filter.column} ${filter.operator} ?`)\n queryParams.push(filter.value)\n }\n }\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 MariaDB connection:', error)\n }\n }\n }\n}\n");
22
+ : '', "\n })\n \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.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(${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 MariaDB connection:', error)\n }\n }\n }\n}\n");
23
23
  };
24
24
  //# sourceMappingURL=mariadb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mariadb.js","sourceRoot":"","sources":["../../../src/fetchers/mariadb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAajD,MAAM,CAAC,IAAM,sBAAsB,GAAG,UACpC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAuB,CAAA;IAC3C,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,OAAO,+LAMK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,4BAChC,WAAW,CAAC,IAAI,IAAI,IAAI,4BACxB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,gCAC5B,sBAAsB,CAAC,WAAW,CAAC,QAAQ,CAAC,gCAC5C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,2BACzC,WAAW,CAAC,GAAG,IAAI,KAAK,SACjC,WAAW,CAAC,SAAS;QACnB,CAAC,CAAC,yCAGE,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,uBAG1F,WAAW,CAAC,SAAS,CAAC,IAAI;YACxB,CAAC,CAAC,gBAAS,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG;YAChE,CAAC,CAAC,EAAE,uBAGN,WAAW,CAAC,SAAS,CAAC,GAAG;YACvB,CAAC,CAAC,eAAQ,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG;YAC9D,CAAC,CAAC,EAAE,2CAEc,WAAW,CAAC,SAAS,CAAC,kBAAkB,KAAK,KAAK,cACxE;QACF,CAAC,CAAC,EAAE,yqBAsBK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,kkCA8BjC,SAAS,o4CAkD5C,CAAA;AACD,CAAC,CAAA;AAED,MAAM,CAAC,IAAM,2BAA2B,GAAG,UACzC,MAA+B,EAC/B,SAAiB;IAEjB,IAAM,WAAW,GAAG,MAAuB,CAAA;IAC3C,IAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAA;IAErC,OAAO,oJAMK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,4BAChC,WAAW,CAAC,IAAI,IAAI,IAAI,4BACxB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,gCAC5B,sBAAsB,CAAC,WAAW,CAAC,QAAQ,CAAC,gCAC5C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,2BACzC,WAAW,CAAC,GAAG,IAAI,KAAK,SACjC,WAAW,CAAC,SAAS;QACnB,CAAC,CAAC,yCAGE,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,uBAG1F,WAAW,CAAC,SAAS,CAAC,IAAI;YACxB,CAAC,CAAC,gBAAS,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG;YAChE,CAAC,CAAC,EAAE,uBAGN,WAAW,CAAC,SAAS,CAAC,GAAG;YACvB,CAAC,CAAC,eAAQ,sBAAsB,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG;YAC9D,CAAC,CAAC,EAAE,2CAEc,WAAW,CAAC,SAAS,CAAC,kBAAkB,KAAK,KAAK,cACxE;QACF,CAAC,CAAC,EAAE,itBAqBK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,+1BAwBhB,SAAS,ouBA8B7D,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"mariadb.js","sourceRoot":"","sources":["../../../src/fetchers/mariadb.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,5 @@ export declare const validateMongoDBConfig: (config: Record<string, unknown>) =>
3
3
  error?: string;
4
4
  };
5
5
  export declare const generateMongoDBFetcher: (config: Record<string, unknown>, tableName: string) => string;
6
- export declare const generateMongoDBCountFetcher: (_config: any, tableName: string) => string;
6
+ export declare const generateMongoDBCountFetcher: (config: any, tableName: string) => string;
7
7
  //# sourceMappingURL=mongodb.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mongodb.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mongodb.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,WACxB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAoCpC,CAAA;AAWD,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA4HF,CAAA;AAGD,eAAO,MAAM,2BAA2B,YAAa,GAAG,aAAa,MAAM,KAAG,MA6D7E,CAAA"}
1
+ {"version":3,"file":"mongodb.d.ts","sourceRoot":"","sources":["../../../src/fetchers/mongodb.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,qBAAqB,WACxB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAoCpC,CAAA;AAWD,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MAuNF,CAAA;AAGD,eAAO,MAAM,2BAA2B,WAAY,GAAG,aAAa,MAAM,KAAG,MAqF5E,CAAA"}
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils';
1
+ import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, } from '../utils';
2
2
  export var validateMongoDBConfig = function (config) {
3
3
  if (!config || typeof config !== 'object') {
4
4
  return { isValid: false, error: 'Config must be a valid object' };
@@ -37,10 +37,18 @@ export var generateMongoDBFetcher = function (config, tableName) {
37
37
  if (!connectionString) {
38
38
  connectionString = "mongodb://".concat(hasUsername ? "".concat(mongoConfig.username, ":").concat(mongoConfig.password, "@") : '').concat(mongoConfig.host, ":").concat(mongoConfig.port || 27017, "/").concat(database);
39
39
  }
40
- return "import { MongoClient, ObjectId } from 'mongodb'\n\nexport default async function handler(req, res) {\n let client = null\n try {\n const url = ".concat(replaceSecretReference(connectionString), "\n client = new MongoClient(url, {\n connectTimeoutMS: 30000,\n serverSelectionTimeoutMS: 30000\n })\n \n await client.connect()\n const db = client.db(").concat(JSON.stringify(database), ")\n const collection = db.collection('").concat(tableName, "')\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset } = req.query\n \n const filter = {}\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n columns = JSON.parse(queryColumns)\n } else {\n // Fallback: Get all field names from a sample document\n try {\n const sampleDoc = await db.collection(").concat(JSON.stringify(tableName), ").findOne({})\n if (sampleDoc) {\n columns = Object.keys(sampleDoc).filter(key => key !== '_id')\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample document 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 orConditions = columns.map((col) => ({\n [col]: { $regex: query, $options: 'i' }\n }))\n filter.$or = orConditions\n }\n }\n \n if (filters) {\n const parsedFilters = JSON.parse(filters)\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (key === '_id') {\n if (Array.isArray(value)) {\n filter[key] = {\n $in: value.map((id) => (typeof id === 'string' ? new ObjectId(id) : id))\n }\n } else if (typeof value === 'string') {\n filter[key] = new ObjectId(value)\n } else {\n filter[key] = value\n }\n } else if (Array.isArray(value)) {\n filter[key] = { $in: value }\n } else {\n filter[key] = value\n }\n })\n }\n \n let cursor = collection.find(filter)\n \n if (sortBy) {\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n cursor = cursor.sort({ [sortBy]: sortOrderValue })\n }\n \n const limitValue = limit || perPage\n const skipValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (skipValue !== undefined) {\n cursor = cursor.skip(skipValue)\n }\n \n if (limitValue) {\n cursor = cursor.limit(parseInt(limitValue))\n }\n \n const documents = await cursor.toArray()\n const safeData = JSON.parse(JSON.stringify(documents))\n\n return res.status(200).json({\n success: true,\n data: safeData,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('MongoDB 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.close()\n } catch (error) {\n console.error('Error closing MongoDB client:', error)\n }\n }\n }\n}\n");
40
+ return "import { MongoClient, ObjectId } from 'mongodb'\n\n".concat(generateSafeJSONParseCode(), "\n\n// Helper function to process filters\nconst processFilters = (filters, filter) => {\n if (!filters) return\n \n const parsedFilters = safeJSONParse(filters)\n \n if (Array.isArray(parsedFilters)) {\n parsedFilters.forEach((filterItem) => {\n if (!filterItem.source || filterItem.destination === undefined) return\n \n const field = filterItem.source\n const value = filterItem.destination\n const operand = filterItem.operand || '='\n \n // Handle _id specially\n const processValue = (v) => {\n if (field === '_id' && typeof v === 'string') {\n try {\n return new ObjectId(v)\n } catch (e) {\n return v\n }\n }\n return v\n }\n \n if (Array.isArray(value)) {\n const processedValues = value.map(processValue)\n if (operand === '!=') {\n filter[field] = { $nin: processedValues }\n } else {\n filter[field] = { $in: processedValues }\n }\n } else {\n const processedValue = processValue(value)\n \n // Handle null values\n if (processedValue === null) {\n if (operand === '=') {\n filter[field] = null\n } else if (operand === '!=') {\n filter[field] = { $ne: null }\n }\n } else {\n // Map operand to MongoDB operators\n switch (operand) {\n case '=':\n filter[field] = processedValue\n break\n case '!=':\n filter[field] = { $ne: processedValue }\n break\n case '>':\n filter[field] = { $gt: processedValue }\n break\n case '>=':\n filter[field] = { $gte: processedValue }\n break\n case '<':\n filter[field] = { $lt: processedValue }\n break\n case '<=':\n filter[field] = { $lte: processedValue }\n break\n default:\n filter[field] = processedValue\n }\n }\n }\n })\n } else {\n Object.entries(parsedFilters).forEach(([key, value]) => {\n if (key === '_id') {\n if (Array.isArray(value)) {\n filter[key] = {\n $in: value.map((id) => (typeof id === 'string' ? new ObjectId(id) : id))\n }\n } else if (typeof value === 'string') {\n filter[key] = new ObjectId(value)\n } else {\n filter[key] = value\n }\n } else if (Array.isArray(value)) {\n filter[key] = { $in: value }\n } else {\n filter[key] = value\n }\n })\n }\n}\n\n").concat(generateDateFormatterCode(), "\n\nexport default async function handler(req, res) {\n let client = null\n try {\n const url = ").concat(replaceSecretReference(connectionString), "\n client = new MongoClient(url, {\n connectTimeoutMS: 30000,\n serverSelectionTimeoutMS: 30000\n })\n \n await client.connect()\n const db = client.db(").concat(JSON.stringify(database), ")\n const collection = db.collection('").concat(tableName, "')\n \n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n \n const filter = {}\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 field names from a sample document\n try {\n const sampleDoc = await db.collection(").concat(JSON.stringify(tableName), ").findOne({})\n if (sampleDoc) {\n columns = Object.keys(sampleDoc).filter(key => key !== '_id')\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample document 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 orConditions = columns.map((col) => ({\n [col]: { $regex: query, $options: 'i' }\n }))\n filter.$or = orConditions\n }\n }\n \n // Apply filters using helper function\n processFilters(filters, filter)\n \n let cursor = collection.find(filter)\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 sortObject = {}\n parsedSorts.forEach((sort) => {\n if (sort.field) {\n sortObject[sort.field] = sort.order?.toLowerCase() === 'desc' ? -1 : 1\n }\n })\n if (Object.keys(sortObject).length > 0) {\n cursor = cursor.sort(sortObject)\n }\n }\n } else if (sortBy) {\n const sortOrderValue = sortOrder?.toLowerCase() === 'desc' ? -1 : 1\n cursor = cursor.sort({ [sortBy]: sortOrderValue })\n }\n \n const limitValue = limit || perPage\n const skipValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n \n if (skipValue !== undefined) {\n cursor = cursor.skip(skipValue)\n }\n \n if (limitValue) {\n cursor = cursor.limit(parseInt(limitValue))\n }\n \n const documents = await cursor.toArray()\n const safeData = JSON.parse(JSON.stringify(documents, 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('MongoDB 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.close()\n } catch (error) {\n console.error('Error closing MongoDB client:', error)\n }\n }\n }\n}\n");
41
41
  };
42
42
  // tslint:disable-next-line:variable-name
43
- export var generateMongoDBCountFetcher = function (_config, tableName) {
44
- return "\nasync function getCount(req, res) {\n const client = getClient()\n const db = client.db()\n\n try {\n const { query, queryColumns, filters } = req.query\n const collection = db.collection('".concat(tableName, "')\n const filter = {}\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n // Use specified columns\n columns = typeof queryColumns === 'string' ? JSON.parse(queryColumns) : (Array.isArray(queryColumns) ? queryColumns : [queryColumns])\n } else {\n // Fallback: Get all field names from a sample document\n try {\n const sampleDoc = await collection.findOne({})\n if (sampleDoc) {\n columns = Object.keys(sampleDoc).filter(key => key !== '_id')\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample document for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n filter.$or = columns.map(col => ({\n [col]: { $regex: query, $options: 'i' }\n }))\n }\n }\n\n if (filters) {\n const parsedFilters = JSON.parse(filters)\n for (const f of parsedFilters) {\n filter[f.column] = f.value\n }\n }\n\n const count = await collection.countDocuments(filter)\n\n return res.status(200).json({\n success: true,\n count: count,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Error getting count:', error)\n return res.status(500).json({\n success: false,\n error: error.message || 'Failed to get count',\n timestamp: Date.now()\n })\n }\n}\n");
43
+ export var generateMongoDBCountFetcher = function (config, tableName) {
44
+ var mongoConfig = config;
45
+ var hasUsername = mongoConfig === null || mongoConfig === void 0 ? void 0 : mongoConfig.username;
46
+ var database = mongoConfig === null || mongoConfig === void 0 ? void 0 : mongoConfig.database;
47
+ // Build connection string from parts if not provided
48
+ var connectionString = mongoConfig.connectionString;
49
+ if (!connectionString) {
50
+ connectionString = "mongodb://".concat(hasUsername ? "".concat(mongoConfig.username, ":").concat(mongoConfig.password, "@") : '').concat(mongoConfig.host, ":").concat(mongoConfig.port || 27017, "/").concat(database);
51
+ }
52
+ return "\nasync function getCount(req, res) {\n let client = null\n try {\n const url = ".concat(replaceSecretReference(connectionString), "\n client = new MongoClient(url, {\n connectTimeoutMS: 30000,\n serverSelectionTimeoutMS: 30000\n })\n \n await client.connect()\n const db = client.db(").concat(JSON.stringify(database), ")\n const collection = db.collection('").concat(tableName, "')\n \n const { query, queryColumns, filters } = req.query\n const filter = {}\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 field names from a sample document\n try {\n const sampleDoc = await collection.findOne({})\n if (sampleDoc) {\n columns = Object.keys(sampleDoc).filter(key => key !== '_id')\n }\n } catch (schemaError) {\n console.warn('Failed to fetch sample document for column names:', schemaError.message)\n // Continue without search if we can't get columns\n }\n }\n \n if (columns.length > 0) {\n filter.$or = columns.map(col => ({\n [col]: { $regex: query, $options: 'i' }\n }))\n }\n }\n\n // Apply filters using helper function\n processFilters(filters, filter)\n\n const count = await collection.countDocuments(filter)\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.close()\n } catch (error) {\n console.error('Error closing MongoDB client:', error)\n }\n }\n }\n}\n");
45
53
  };
46
54
  //# sourceMappingURL=mongodb.js.map