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

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 (124) hide show
  1. package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
  2. package/dist/cjs/fetchers/airtable.js +2 -2
  3. package/dist/cjs/fetchers/airtable.js.map +1 -1
  4. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  5. package/dist/cjs/fetchers/clickhouse.js +1 -1
  6. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  7. package/dist/cjs/fetchers/csv-file.d.ts.map +1 -1
  8. package/dist/cjs/fetchers/csv-file.js +2 -1
  9. package/dist/cjs/fetchers/csv-file.js.map +1 -1
  10. package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
  11. package/dist/cjs/fetchers/firestore.js +1 -1
  12. package/dist/cjs/fetchers/firestore.js.map +1 -1
  13. package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -1
  14. package/dist/cjs/fetchers/google-sheets.js +1 -1
  15. package/dist/cjs/fetchers/google-sheets.js.map +1 -1
  16. package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
  17. package/dist/cjs/fetchers/javascript.js +2 -1
  18. package/dist/cjs/fetchers/javascript.js.map +1 -1
  19. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
  20. package/dist/cjs/fetchers/mariadb.js +2 -2
  21. package/dist/cjs/fetchers/mariadb.js.map +1 -1
  22. package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
  23. package/dist/cjs/fetchers/mongodb.js +1 -1
  24. package/dist/cjs/fetchers/mongodb.js.map +1 -1
  25. package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
  26. package/dist/cjs/fetchers/mysql.js +1 -1
  27. package/dist/cjs/fetchers/mysql.js.map +1 -1
  28. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  29. package/dist/cjs/fetchers/postgresql.js +1 -1
  30. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  31. package/dist/cjs/fetchers/redis.d.ts.map +1 -1
  32. package/dist/cjs/fetchers/redis.js +1 -1
  33. package/dist/cjs/fetchers/redis.js.map +1 -1
  34. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  35. package/dist/cjs/fetchers/redshift.js +2 -2
  36. package/dist/cjs/fetchers/redshift.js.map +1 -1
  37. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  38. package/dist/cjs/fetchers/rest-api.js +3 -2
  39. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  40. package/dist/cjs/fetchers/static-collection.d.ts.map +1 -1
  41. package/dist/cjs/fetchers/static-collection.js +2 -1
  42. package/dist/cjs/fetchers/static-collection.js.map +1 -1
  43. package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
  44. package/dist/cjs/fetchers/supabase.js +1 -1
  45. package/dist/cjs/fetchers/supabase.js.map +1 -1
  46. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  47. package/dist/cjs/fetchers/turso.js +1 -1
  48. package/dist/cjs/fetchers/turso.js.map +1 -1
  49. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  50. package/dist/cjs/utils.d.ts +1 -0
  51. package/dist/cjs/utils.d.ts.map +1 -1
  52. package/dist/cjs/utils.js +5 -1
  53. package/dist/cjs/utils.js.map +1 -1
  54. package/dist/esm/fetchers/airtable.d.ts.map +1 -1
  55. package/dist/esm/fetchers/airtable.js +3 -3
  56. package/dist/esm/fetchers/airtable.js.map +1 -1
  57. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  58. package/dist/esm/fetchers/clickhouse.js +2 -2
  59. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  60. package/dist/esm/fetchers/csv-file.d.ts.map +1 -1
  61. package/dist/esm/fetchers/csv-file.js +2 -1
  62. package/dist/esm/fetchers/csv-file.js.map +1 -1
  63. package/dist/esm/fetchers/firestore.d.ts.map +1 -1
  64. package/dist/esm/fetchers/firestore.js +2 -2
  65. package/dist/esm/fetchers/firestore.js.map +1 -1
  66. package/dist/esm/fetchers/google-sheets.d.ts.map +1 -1
  67. package/dist/esm/fetchers/google-sheets.js +1 -1
  68. package/dist/esm/fetchers/google-sheets.js.map +1 -1
  69. package/dist/esm/fetchers/javascript.d.ts.map +1 -1
  70. package/dist/esm/fetchers/javascript.js +2 -1
  71. package/dist/esm/fetchers/javascript.js.map +1 -1
  72. package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
  73. package/dist/esm/fetchers/mariadb.js +3 -3
  74. package/dist/esm/fetchers/mariadb.js.map +1 -1
  75. package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
  76. package/dist/esm/fetchers/mongodb.js +2 -2
  77. package/dist/esm/fetchers/mongodb.js.map +1 -1
  78. package/dist/esm/fetchers/mysql.d.ts.map +1 -1
  79. package/dist/esm/fetchers/mysql.js +2 -2
  80. package/dist/esm/fetchers/mysql.js.map +1 -1
  81. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  82. package/dist/esm/fetchers/postgresql.js +2 -2
  83. package/dist/esm/fetchers/postgresql.js.map +1 -1
  84. package/dist/esm/fetchers/redis.d.ts.map +1 -1
  85. package/dist/esm/fetchers/redis.js +2 -2
  86. package/dist/esm/fetchers/redis.js.map +1 -1
  87. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  88. package/dist/esm/fetchers/redshift.js +3 -3
  89. package/dist/esm/fetchers/redshift.js.map +1 -1
  90. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  91. package/dist/esm/fetchers/rest-api.js +3 -2
  92. package/dist/esm/fetchers/rest-api.js.map +1 -1
  93. package/dist/esm/fetchers/static-collection.d.ts.map +1 -1
  94. package/dist/esm/fetchers/static-collection.js +2 -1
  95. package/dist/esm/fetchers/static-collection.js.map +1 -1
  96. package/dist/esm/fetchers/supabase.d.ts.map +1 -1
  97. package/dist/esm/fetchers/supabase.js +2 -2
  98. package/dist/esm/fetchers/supabase.js.map +1 -1
  99. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  100. package/dist/esm/fetchers/turso.js +2 -2
  101. package/dist/esm/fetchers/turso.js.map +1 -1
  102. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  103. package/dist/esm/utils.d.ts +1 -0
  104. package/dist/esm/utils.d.ts.map +1 -1
  105. package/dist/esm/utils.js +3 -0
  106. package/dist/esm/utils.js.map +1 -1
  107. package/package.json +2 -2
  108. package/src/fetchers/airtable.ts +4 -2
  109. package/src/fetchers/clickhouse.ts +4 -2
  110. package/src/fetchers/csv-file.ts +5 -1
  111. package/src/fetchers/firestore.ts +4 -2
  112. package/src/fetchers/google-sheets.ts +109 -9
  113. package/src/fetchers/javascript.ts +6 -2
  114. package/src/fetchers/mariadb.ts +4 -2
  115. package/src/fetchers/mongodb.ts +4 -2
  116. package/src/fetchers/mysql.ts +4 -2
  117. package/src/fetchers/postgresql.ts +4 -2
  118. package/src/fetchers/redis.ts +4 -2
  119. package/src/fetchers/redshift.ts +4 -2
  120. package/src/fetchers/rest-api.ts +5 -1
  121. package/src/fetchers/static-collection.ts +5 -1
  122. package/src/fetchers/supabase.ts +4 -2
  123. package/src/fetchers/turso.ts +4 -2
  124. package/src/utils.ts +30 -0
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateAirtableConfig = (
4
4
  config: Record<string, unknown>
@@ -34,6 +34,8 @@ export const generateAirtableFetcher = (
34
34
 
35
35
  return `import fetch from 'node-fetch'
36
36
 
37
+ ${generateDateFormatterCode()}
38
+
37
39
  export default async function handler(req, res) {
38
40
  try {
39
41
  const { query, view, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query
@@ -133,7 +135,7 @@ export default async function handler(req, res) {
133
135
  createdTime: record.createdTime
134
136
  }))
135
137
 
136
- const safeData = JSON.parse(JSON.stringify(formattedRecords))
138
+ const safeData = JSON.parse(JSON.stringify(formattedRecords, dateReplacer))
137
139
 
138
140
  return res.status(200).json({
139
141
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateClickHouseConfig = (
4
4
  config: Record<string, unknown>
@@ -53,6 +53,8 @@ const getClient = () => {
53
53
  return client
54
54
  }
55
55
 
56
+ ${generateDateFormatterCode()}
57
+
56
58
  export default async function handler(req, res) {
57
59
  try {
58
60
  const client = getClient()
@@ -113,7 +115,7 @@ export default async function handler(req, res) {
113
115
 
114
116
  const result = await client.query({ query: sql })
115
117
  const resultResponse = await result.json()
116
- const safeData = JSON.parse(JSON.stringify(resultResponse.data))
118
+ const safeData = JSON.parse(JSON.stringify(resultResponse.data, dateReplacer))
117
119
 
118
120
  return res.status(200).json({
119
121
  success: true,
@@ -1,3 +1,5 @@
1
+ import { generateDateFormatterCode } from '../utils'
2
+
1
3
  export const validateCSVConfig = (
2
4
  config: Record<string, unknown>
3
5
  ): { isValid: boolean; error?: string } => {
@@ -34,6 +36,8 @@ export const generateCSVFileFetcher = (config: Record<string, unknown>): string
34
36
  const csvConfig = config as CSVFileConfig
35
37
  return `const data = ${JSON.stringify(csvConfig.parsedData || [])}
36
38
 
39
+ ${generateDateFormatterCode()}
40
+
37
41
  export default async function handler(req, res) {
38
42
  try {
39
43
  const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query
@@ -93,7 +97,7 @@ export default async function handler(req, res) {
93
97
  filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))
94
98
  }
95
99
 
96
- const safeData = JSON.parse(JSON.stringify(filteredData))
100
+ const safeData = JSON.parse(JSON.stringify(filteredData, dateReplacer))
97
101
 
98
102
  return res.status(200).json({
99
103
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateFirestoreConfig = (
4
4
  config: Record<string, unknown>
@@ -67,6 +67,8 @@ const getFirestore = () => {
67
67
  return firestore
68
68
  }
69
69
 
70
+ ${generateDateFormatterCode()}
71
+
70
72
  export default async function handler(req, res) {
71
73
  try {
72
74
  const firestore = getFirestore()
@@ -150,7 +152,7 @@ export default async function handler(req, res) {
150
152
  }
151
153
  }
152
154
 
153
- const safeData = JSON.parse(JSON.stringify(documents))
155
+ const safeData = JSON.parse(JSON.stringify(documents, dateReplacer))
154
156
 
155
157
  return res.status(200).json({
156
158
  success: true,
@@ -59,8 +59,18 @@ export default async function handler(req, res) {
59
59
  })
60
60
  }
61
61
 
62
+ let gid = undefined
63
+ if (sheetUrl) {
64
+ const gidMatch = sheetUrl.match(/[#&]gid=([0-9]+)/)
65
+ gid = gidMatch ? gidMatch[1] : undefined
66
+ }
67
+
62
68
  let url = \`https://docs.google.com/spreadsheets/d/\${sheetId}/gviz/tq?tqx=out:json&range=\${range}\`
63
69
 
70
+ if (gid) {
71
+ url += \`&gid=\${gid}\`
72
+ }
73
+
64
74
  if (maxRows && maxRows > 0) {
65
75
  url += \`&tq=limit \${maxRows}\`
66
76
  }
@@ -96,25 +106,115 @@ export default async function handler(req, res) {
96
106
  })
97
107
  }
98
108
 
109
+ const formatDateValue = (date) => {
110
+ const options = {
111
+ year: 'numeric',
112
+ month: 'short',
113
+ day: 'numeric',
114
+ }
115
+
116
+ const timeOptions = {
117
+ hour: '2-digit',
118
+ minute: '2-digit',
119
+ }
120
+
121
+ const hasTime = date.getHours() !== 0 || date.getMinutes() !== 0 || date.getSeconds() !== 0
122
+
123
+ if (hasTime) {
124
+ return date.toLocaleString('en-US', { ...options, ...timeOptions })
125
+ }
126
+
127
+ return date.toLocaleDateString('en-US', options)
128
+ }
129
+
130
+ const parseGoogleSheetsValue = (value) => {
131
+ if (typeof value === 'string') {
132
+ const dateMatch = value.match(/^Date\\((\\d+),(\\d+),(\\d+)(?:,(\\d+),(\\d+),(\\d+))?\\)$/)
133
+ if (dateMatch) {
134
+ const year = parseInt(dateMatch[1], 10)
135
+ const month = parseInt(dateMatch[2], 10)
136
+ const day = parseInt(dateMatch[3], 10)
137
+ const hour = dateMatch[4] ? parseInt(dateMatch[4], 10) : 0
138
+ const minute = dateMatch[5] ? parseInt(dateMatch[5], 10) : 0
139
+ const second = dateMatch[6] ? parseInt(dateMatch[6], 10) : 0
140
+ const date = new Date(year, month, day, hour, minute, second)
141
+ return formatDateValue(date)
142
+ }
143
+ }
144
+ return value
145
+ }
146
+
99
147
  const table = data.table
100
- const columns = table.cols.map((col, index) => ({
101
- id: col.id || \`col_\${index}\`,
102
- label: col.label || \`Column \${index + 1}\`,
103
- type: col.type || 'string'
104
- }))
148
+ const rawRows = table.rows || []
105
149
 
106
- const rows = table.rows.map((row) => {
150
+ if (rawRows.length === 0) {
151
+ return res.status(200).json({
152
+ success: true,
153
+ data: [],
154
+ timestamp: Date.now()
155
+ })
156
+ }
157
+
158
+ const firstRow = rawRows[0]
159
+ const firstRowValues = firstRow.c.map((cell) => cell?.v ?? cell?.f ?? null)
160
+
161
+ const hasHeaderRow = firstRowValues.every((val) =>
162
+ val !== null && val !== undefined && val !== '' && typeof val === 'string'
163
+ )
164
+
165
+ let columns
166
+ let dataRows
167
+
168
+ if (hasHeaderRow && rawRows.length > 1) {
169
+ columns = firstRowValues.map((headerValue, index) => ({
170
+ id: \`col_\${index}\`,
171
+ label: String(headerValue),
172
+ type: 'string'
173
+ }))
174
+ dataRows = rawRows.slice(1)
175
+ } else {
176
+ columns = table.cols.map((col, index) => ({
177
+ id: col.id || \`col_\${index}\`,
178
+ label: col.label || \`Column \${index + 1}\`,
179
+ type: col.type || 'string'
180
+ }))
181
+ dataRows = rawRows
182
+ }
183
+
184
+ if (maxRows && dataRows.length > maxRows) {
185
+ dataRows = dataRows.slice(0, maxRows)
186
+ }
187
+
188
+ const rows = dataRows.map((row) => {
107
189
  const rowData = {}
108
190
  row.c.forEach((cell, index) => {
109
- const columnId = columns[index].id
110
- rowData[columnId] = cell?.v ?? null
191
+ const columnId = columns[index]?.id || \`col_\${index}\`
192
+ const rawValue = cell?.v ?? cell?.f ?? null
193
+ rowData[columnId] = parseGoogleSheetsValue(rawValue)
111
194
  })
112
195
  return rowData
113
196
  })
114
197
 
198
+ const columnsWithData = columns.filter((col, index) => {
199
+ const hasHeaderData = col.label && col.label !== \`Column \${index + 1}\`
200
+ const hasDataInColumn = rows.some((row) => {
201
+ const value = row[col.id]
202
+ return value !== null && value !== undefined && value !== ''
203
+ })
204
+ return hasHeaderData || hasDataInColumn
205
+ })
206
+
207
+ const filteredRows = rows.map((row) => {
208
+ const filteredRow = {}
209
+ columnsWithData.forEach((col) => {
210
+ filteredRow[col.id] = row[col.id]
211
+ })
212
+ return filteredRow
213
+ })
214
+
115
215
  const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query
116
216
 
117
- let filteredData = [...rows]
217
+ let filteredData = [...filteredRows]
118
218
 
119
219
  if (query) {
120
220
  const searchQuery = query.toLowerCase()
@@ -1,3 +1,5 @@
1
+ import { generateDateFormatterCode } from '../utils'
2
+
1
3
  export const validateJavaScriptConfig = (
2
4
  config: Record<string, unknown>
3
5
  ): { isValid: boolean; error?: string } => {
@@ -35,7 +37,9 @@ interface JavaScriptConfig {
35
37
 
36
38
  export const generateJavaScriptFetcher = (config: Record<string, unknown>): string => {
37
39
  const jsConfig = config as JavaScriptConfig
38
- return `export default async function handler(req, res) {
40
+ return `${generateDateFormatterCode()}
41
+
42
+ export default async function handler(req, res) {
39
43
  try {
40
44
  const { limit, offset, page, perPage, query, queryColumns, sortBy, sortOrder, filters } = req.query
41
45
 
@@ -115,7 +119,7 @@ export const generateJavaScriptFetcher = (config: Record<string, unknown>): stri
115
119
  }
116
120
  }
117
121
 
118
- const safeData = JSON.parse(JSON.stringify(data))
122
+ const safeData = JSON.parse(JSON.stringify(data, dateReplacer))
119
123
 
120
124
  return res.status(200).json({
121
125
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  interface MariaDBConfig {
4
4
  host?: string
@@ -20,6 +20,8 @@ export const generateMariaDBFetcher = (
20
20
 
21
21
  return `import mariadb from 'mariadb'
22
22
 
23
+ ${generateDateFormatterCode()}
24
+
23
25
  export default async function handler(req, res) {
24
26
  let connection = null
25
27
  try {
@@ -126,7 +128,7 @@ export default async function handler(req, res) {
126
128
  const plainRows = rowArray.map((row) =>
127
129
  row && typeof row.toJSON === 'function' ? row.toJSON() : row
128
130
  )
129
- const safeData = JSON.parse(JSON.stringify(plainRows))
131
+ const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))
130
132
 
131
133
  return res.status(200).json({
132
134
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateMongoDBConfig = (
4
4
  config: Record<string, unknown>
@@ -67,6 +67,8 @@ export const generateMongoDBFetcher = (
67
67
 
68
68
  return `import { MongoClient, ObjectId } from 'mongodb'
69
69
 
70
+ ${generateDateFormatterCode()}
71
+
70
72
  export default async function handler(req, res) {
71
73
  let client = null
72
74
  try {
@@ -151,7 +153,7 @@ export default async function handler(req, res) {
151
153
  }
152
154
 
153
155
  const documents = await cursor.toArray()
154
- const safeData = JSON.parse(JSON.stringify(documents))
156
+ const safeData = JSON.parse(JSON.stringify(documents, dateReplacer))
155
157
 
156
158
  return res.status(200).json({
157
159
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  interface MySQLConfig {
4
4
  host?: string
@@ -57,6 +57,8 @@ const getConnection = () => {
57
57
  })
58
58
  }
59
59
 
60
+ ${generateDateFormatterCode()}
61
+
60
62
  export default async function handler(req, res) {
61
63
  const connection = await getConnection()
62
64
 
@@ -135,7 +137,7 @@ export default async function handler(req, res) {
135
137
  const plainRows = rowArray.map((row) =>
136
138
  row && typeof row.toJSON === 'function' ? row.toJSON() : row
137
139
  )
138
- const safeData = JSON.parse(JSON.stringify(plainRows))
140
+ const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))
139
141
 
140
142
  return res.status(200).json({
141
143
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  interface PostgreSQLConfig {
4
4
  host?: string
@@ -43,6 +43,8 @@ const getClient = () => {
43
43
  })
44
44
  }
45
45
 
46
+ ${generateDateFormatterCode()}
47
+
46
48
  export default async function handler(req, res) {
47
49
  const client = getClient()
48
50
 
@@ -136,7 +138,7 @@ export default async function handler(req, res) {
136
138
  const plainRows = rows.map((row) =>
137
139
  row && typeof row.toJSON === 'function' ? row.toJSON() : row
138
140
  )
139
- const safeData = JSON.parse(JSON.stringify(plainRows))
141
+ const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))
140
142
 
141
143
  return res.status(200).json({
142
144
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateRedisConfig = (
4
4
  config: Record<string, unknown>
@@ -63,6 +63,8 @@ export const generateRedisFetcher = (config: Record<string, unknown>): string =>
63
63
 
64
64
  return `import { createClient } from 'redis'
65
65
 
66
+ ${generateDateFormatterCode()}
67
+
66
68
  export default async function handler(req, res) {
67
69
  let client = null
68
70
  try {
@@ -128,7 +130,7 @@ export default async function handler(req, res) {
128
130
  })
129
131
  }
130
132
 
131
- const safeData = JSON.parse(JSON.stringify(results))
133
+ const safeData = JSON.parse(JSON.stringify(results, dateReplacer))
132
134
 
133
135
  return res.status(200).json({
134
136
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  interface RedshiftConfig {
4
4
  host?: string
@@ -49,6 +49,8 @@ const getClient = () => {
49
49
  })
50
50
  }
51
51
 
52
+ ${generateDateFormatterCode()}
53
+
52
54
  export default async function handler(req, res) {
53
55
  const client = getClient()
54
56
 
@@ -137,7 +139,7 @@ export default async function handler(req, res) {
137
139
  const plainRows = rows.map((row) =>
138
140
  row && typeof row.toJSON === 'function' ? row.toJSON() : row
139
141
  )
140
- const safeData = JSON.parse(JSON.stringify(plainRows))
142
+ const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))
141
143
 
142
144
  return res.status(200).json({
143
145
  success: true,
@@ -1,3 +1,5 @@
1
+ import { generateDateFormatterCode } from '../utils'
2
+
1
3
  export const validateRESTAPIConfig = (
2
4
  config: Record<string, unknown>
3
5
  ): { isValid: boolean; error?: string } => {
@@ -75,6 +77,8 @@ export const generateRESTAPIFetcher = (config: Record<string, unknown>): string
75
77
 
76
78
  return `import fetch from 'node-fetch'
77
79
 
80
+ ${generateDateFormatterCode()}
81
+
78
82
  export default async function handler(req, res) {
79
83
  try {
80
84
  const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset } = req.query
@@ -190,7 +194,7 @@ export default async function handler(req, res) {
190
194
  }
191
195
  }
192
196
 
193
- const safeData = JSON.parse(JSON.stringify(data))
197
+ const safeData = JSON.parse(JSON.stringify(data, dateReplacer))
194
198
 
195
199
  return res.status(200).json({
196
200
  success: true,
@@ -1,3 +1,5 @@
1
+ import { generateDateFormatterCode } from '../utils'
2
+
1
3
  export const validateStaticCollectionConfig = (
2
4
  config: Record<string, unknown>
3
5
  ): { isValid: boolean; error?: string } => {
@@ -20,6 +22,8 @@ export const generateStaticCollectionFetcher = (config: Record<string, unknown>)
20
22
  const staticConfig = config as StaticCollectionConfig
21
23
  return `const data = ${JSON.stringify(staticConfig.data || [])}
22
24
 
25
+ ${generateDateFormatterCode()}
26
+
23
27
  export default async function handler(req, res) {
24
28
  try {
25
29
  const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset: offsetParam } = req.query
@@ -79,7 +83,7 @@ export default async function handler(req, res) {
79
83
  filteredData = filteredData.slice(offsetValue, offsetValue + parseInt(limitValue))
80
84
  }
81
85
 
82
- const safeData = JSON.parse(JSON.stringify(filteredData))
86
+ const safeData = JSON.parse(JSON.stringify(filteredData, dateReplacer))
83
87
 
84
88
  return res.status(200).json({
85
89
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateSupabaseConfig = (
4
4
  config: Record<string, unknown>
@@ -61,6 +61,8 @@ const getClient = () => {
61
61
  return client
62
62
  }
63
63
 
64
+ ${generateDateFormatterCode()}
65
+
64
66
  export default async function handler(req, res) {
65
67
  try {
66
68
  const client = getClient()
@@ -159,7 +161,7 @@ export default async function handler(req, res) {
159
161
  })
160
162
  }
161
163
 
162
- const safeData = JSON.parse(JSON.stringify(data))
164
+ const safeData = JSON.parse(JSON.stringify(data, dateReplacer))
163
165
 
164
166
  return res.status(200).json({
165
167
  success: true,
@@ -1,4 +1,4 @@
1
- import { replaceSecretReference } from '../utils'
1
+ import { replaceSecretReference, generateDateFormatterCode } from '../utils'
2
2
 
3
3
  export const validateTursoConfig = (
4
4
  config: Record<string, unknown>
@@ -35,6 +35,8 @@ export const generateTursoFetcher = (
35
35
 
36
36
  return `import { createClient } from '@libsql/client'
37
37
 
38
+ ${generateDateFormatterCode()}
39
+
38
40
  export default async function handler(req, res) {
39
41
  let client = null
40
42
  try {
@@ -137,7 +139,7 @@ export default async function handler(req, res) {
137
139
  }
138
140
  }
139
141
 
140
- const safeData = JSON.parse(JSON.stringify(data))
142
+ const safeData = JSON.parse(JSON.stringify(data, dateReplacer))
141
143
 
142
144
  return res.status(200).json({
143
145
  success: true,
package/src/utils.ts CHANGED
@@ -510,6 +510,36 @@ export const replaceSecretReference = (
510
510
  }
511
511
  }
512
512
 
513
+ export const generateDateFormatterCode = (): string => {
514
+ return `const formatDateValue = (date) => {
515
+ const options = {
516
+ year: 'numeric',
517
+ month: 'short',
518
+ day: 'numeric',
519
+ }
520
+
521
+ const timeOptions = {
522
+ hour: '2-digit',
523
+ minute: '2-digit',
524
+ }
525
+
526
+ const hasTime = date.getHours() !== 0 || date.getMinutes() !== 0 || date.getSeconds() !== 0
527
+
528
+ if (hasTime) {
529
+ return date.toLocaleString('en-US', { ...options, ...timeOptions })
530
+ }
531
+
532
+ return date.toLocaleDateString('en-US', options)
533
+ }
534
+
535
+ const dateReplacer = (key, value) => {
536
+ if (value instanceof Date) {
537
+ return formatDateValue(value)
538
+ }
539
+ return value
540
+ }`
541
+ }
542
+
513
543
  export const sanitizeNumericParam = (value: unknown, defaultValue: number = 0): number => {
514
544
  if (typeof value === 'number' && !isNaN(value) && isFinite(value)) {
515
545
  return Math.max(0, Math.floor(value))