@teleporthq/teleport-plugin-next-data-source 0.42.9 → 0.42.11
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.
- package/__tests__/csv-header-detection.test.ts +212 -0
- package/__tests__/validation.test.ts +33 -2
- package/dist/cjs/data-source-fetchers.d.ts +2 -2
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +30 -7
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
- package/dist/cjs/fetchers/airtable.js +1 -1
- package/dist/cjs/fetchers/airtable.js.map +1 -1
- package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/cjs/fetchers/clickhouse.js +1 -1
- package/dist/cjs/fetchers/clickhouse.js.map +1 -1
- package/dist/cjs/fetchers/csv-file.d.ts.map +1 -1
- package/dist/cjs/fetchers/csv-file.js +22 -3
- package/dist/cjs/fetchers/csv-file.js.map +1 -1
- package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
- package/dist/cjs/fetchers/firestore.js +1 -1
- package/dist/cjs/fetchers/firestore.js.map +1 -1
- package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -1
- package/dist/cjs/fetchers/google-sheets.js +6 -1
- package/dist/cjs/fetchers/google-sheets.js.map +1 -1
- package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
- package/dist/cjs/fetchers/javascript.js +1 -1
- package/dist/cjs/fetchers/javascript.js.map +1 -1
- package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mariadb.js +3 -3
- package/dist/cjs/fetchers/mariadb.js.map +1 -1
- package/dist/cjs/fetchers/mongodb.d.ts +1 -1
- package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mongodb.js +11 -3
- package/dist/cjs/fetchers/mongodb.js.map +1 -1
- package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
- package/dist/cjs/fetchers/mysql.js +2 -2
- package/dist/cjs/fetchers/mysql.js.map +1 -1
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +3 -3
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/redis.d.ts.map +1 -1
- package/dist/cjs/fetchers/redis.js +1 -1
- package/dist/cjs/fetchers/redis.js.map +1 -1
- package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
- package/dist/cjs/fetchers/redshift.js +2 -2
- package/dist/cjs/fetchers/redshift.js.map +1 -1
- package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
- package/dist/cjs/fetchers/rest-api.js +2 -2
- package/dist/cjs/fetchers/rest-api.js.map +1 -1
- package/dist/cjs/fetchers/static-collection.d.ts.map +1 -1
- package/dist/cjs/fetchers/static-collection.js +1 -1
- package/dist/cjs/fetchers/static-collection.js.map +1 -1
- package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
- package/dist/cjs/fetchers/supabase.js +2 -2
- package/dist/cjs/fetchers/supabase.js.map +1 -1
- package/dist/cjs/fetchers/turso.d.ts.map +1 -1
- package/dist/cjs/fetchers/turso.js +1 -1
- package/dist/cjs/fetchers/turso.js.map +1 -1
- package/dist/cjs/fetchers/utils/header-detection.d.ts +2 -0
- package/dist/cjs/fetchers/utils/header-detection.d.ts.map +1 -0
- package/dist/cjs/fetchers/utils/header-detection.js +8 -0
- package/dist/cjs/fetchers/utils/header-detection.js.map +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +168 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +320 -65
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +2 -0
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +214 -46
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/data-source-fetchers.d.ts +2 -2
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +29 -6
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/airtable.d.ts.map +1 -1
- package/dist/esm/fetchers/airtable.js +2 -2
- package/dist/esm/fetchers/airtable.js.map +1 -1
- package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/esm/fetchers/clickhouse.js +2 -2
- package/dist/esm/fetchers/clickhouse.js.map +1 -1
- package/dist/esm/fetchers/csv-file.d.ts.map +1 -1
- package/dist/esm/fetchers/csv-file.js +23 -4
- package/dist/esm/fetchers/csv-file.js.map +1 -1
- package/dist/esm/fetchers/firestore.d.ts.map +1 -1
- package/dist/esm/fetchers/firestore.js +2 -2
- package/dist/esm/fetchers/firestore.js.map +1 -1
- package/dist/esm/fetchers/google-sheets.d.ts.map +1 -1
- package/dist/esm/fetchers/google-sheets.js +6 -1
- package/dist/esm/fetchers/google-sheets.js.map +1 -1
- package/dist/esm/fetchers/javascript.d.ts.map +1 -1
- package/dist/esm/fetchers/javascript.js +2 -2
- package/dist/esm/fetchers/javascript.js.map +1 -1
- package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
- package/dist/esm/fetchers/mariadb.js +4 -4
- package/dist/esm/fetchers/mariadb.js.map +1 -1
- package/dist/esm/fetchers/mongodb.d.ts +1 -1
- package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
- package/dist/esm/fetchers/mongodb.js +12 -4
- package/dist/esm/fetchers/mongodb.js.map +1 -1
- package/dist/esm/fetchers/mysql.d.ts.map +1 -1
- package/dist/esm/fetchers/mysql.js +3 -3
- package/dist/esm/fetchers/mysql.js.map +1 -1
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +4 -4
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/redis.d.ts.map +1 -1
- package/dist/esm/fetchers/redis.js +2 -2
- package/dist/esm/fetchers/redis.js.map +1 -1
- package/dist/esm/fetchers/redshift.d.ts.map +1 -1
- package/dist/esm/fetchers/redshift.js +3 -3
- package/dist/esm/fetchers/redshift.js.map +1 -1
- package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
- package/dist/esm/fetchers/rest-api.js +3 -3
- package/dist/esm/fetchers/rest-api.js.map +1 -1
- package/dist/esm/fetchers/static-collection.d.ts.map +1 -1
- package/dist/esm/fetchers/static-collection.js +2 -2
- package/dist/esm/fetchers/static-collection.js.map +1 -1
- package/dist/esm/fetchers/supabase.d.ts.map +1 -1
- package/dist/esm/fetchers/supabase.js +3 -3
- package/dist/esm/fetchers/supabase.js.map +1 -1
- package/dist/esm/fetchers/turso.d.ts.map +1 -1
- package/dist/esm/fetchers/turso.js +2 -2
- package/dist/esm/fetchers/turso.js.map +1 -1
- package/dist/esm/fetchers/utils/header-detection.d.ts +2 -0
- package/dist/esm/fetchers/utils/header-detection.d.ts.map +1 -0
- package/dist/esm/fetchers/utils/header-detection.js +4 -0
- package/dist/esm/fetchers/utils/header-detection.js.map +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +169 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +320 -65
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +2 -0
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +211 -45
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/data-source-fetchers.ts +29 -13
- package/src/fetchers/airtable.ts +78 -30
- package/src/fetchers/clickhouse.ts +85 -18
- package/src/fetchers/csv-file.ts +254 -29
- package/src/fetchers/firestore.ts +62 -12
- package/src/fetchers/google-sheets.ts +147 -30
- package/src/fetchers/javascript.ts +102 -23
- package/src/fetchers/mariadb.ts +82 -25
- package/src/fetchers/mongodb.ts +153 -36
- package/src/fetchers/mysql.ts +83 -25
- package/src/fetchers/postgresql.ts +86 -26
- package/src/fetchers/redis.ts +40 -4
- package/src/fetchers/redshift.ts +84 -17
- package/src/fetchers/rest-api.ts +101 -24
- package/src/fetchers/static-collection.ts +96 -18
- package/src/fetchers/supabase.ts +175 -53
- package/src/fetchers/turso.ts +84 -17
- package/src/fetchers/utils/header-detection.ts +200 -0
- package/src/index.ts +248 -2
- package/src/pagination-plugin.ts +708 -191
- package/src/utils.ts +344 -38
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { generateCSVFileFetcher, validateCSVConfig } from '../src/fetchers/csv-file'
|
|
2
|
+
|
|
3
|
+
describe('CSV Header Detection', () => {
|
|
4
|
+
describe('validateCSVConfig with new properties', () => {
|
|
5
|
+
it('validates fileContent with autoDetectHeader', () => {
|
|
6
|
+
const result = validateCSVConfig({
|
|
7
|
+
fileContent: 'name,age\nJohn,30\nJane,25',
|
|
8
|
+
autoDetectHeader: true,
|
|
9
|
+
})
|
|
10
|
+
expect(result.isValid).toBe(true)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('validates fileContent with firstRowIsHeader', () => {
|
|
14
|
+
const result = validateCSVConfig({
|
|
15
|
+
fileContent: 'name,age\nJohn,30',
|
|
16
|
+
firstRowIsHeader: false,
|
|
17
|
+
})
|
|
18
|
+
expect(result.isValid).toBe(true)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('accepts both autoDetectHeader and firstRowIsHeader', () => {
|
|
22
|
+
const result = validateCSVConfig({
|
|
23
|
+
fileContent: 'name,age\nJohn,30',
|
|
24
|
+
autoDetectHeader: false,
|
|
25
|
+
firstRowIsHeader: true,
|
|
26
|
+
})
|
|
27
|
+
expect(result.isValid).toBe(true)
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe('generateCSVFileFetcher with fileContent', () => {
|
|
32
|
+
it('generates fetcher with header detection code when fileContent is provided', () => {
|
|
33
|
+
const config = {
|
|
34
|
+
fileContent: 'name,age\nJohn,30\nJane,25',
|
|
35
|
+
autoDetectHeader: true,
|
|
36
|
+
firstRowIsHeader: true,
|
|
37
|
+
}
|
|
38
|
+
const code = generateCSVFileFetcher(config)
|
|
39
|
+
|
|
40
|
+
expect(code).toContain('parseCSVLine')
|
|
41
|
+
expect(code).toContain('detectHeaderRow')
|
|
42
|
+
expect(code).toContain('parseCSVContent')
|
|
43
|
+
expect(code).toContain('const autoDetectHeader = true')
|
|
44
|
+
expect(code).toContain('const firstRowIsHeader = true')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('generates fetcher with autoDetectHeader defaulting to true', () => {
|
|
48
|
+
const config = {
|
|
49
|
+
fileContent: 'name,age\nJohn,30',
|
|
50
|
+
}
|
|
51
|
+
const code = generateCSVFileFetcher(config)
|
|
52
|
+
|
|
53
|
+
expect(code).toContain('const autoDetectHeader = true')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('generates fetcher with firstRowIsHeader defaulting to true', () => {
|
|
57
|
+
const config = {
|
|
58
|
+
fileContent: 'name,age\nJohn,30',
|
|
59
|
+
}
|
|
60
|
+
const code = generateCSVFileFetcher(config)
|
|
61
|
+
|
|
62
|
+
expect(code).toContain('const firstRowIsHeader = true')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('respects autoDetectHeader: false', () => {
|
|
66
|
+
const config = {
|
|
67
|
+
fileContent: 'name,age\nJohn,30',
|
|
68
|
+
autoDetectHeader: false,
|
|
69
|
+
}
|
|
70
|
+
const code = generateCSVFileFetcher(config)
|
|
71
|
+
|
|
72
|
+
expect(code).toContain('const autoDetectHeader = false')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('respects firstRowIsHeader: false', () => {
|
|
76
|
+
const config = {
|
|
77
|
+
fileContent: 'name,age\nJohn,30',
|
|
78
|
+
firstRowIsHeader: false,
|
|
79
|
+
}
|
|
80
|
+
const code = generateCSVFileFetcher(config)
|
|
81
|
+
|
|
82
|
+
expect(code).toContain('const firstRowIsHeader = false')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('includes column configuration when provided', () => {
|
|
86
|
+
const config = {
|
|
87
|
+
fileContent: 'name,age\nJohn,30',
|
|
88
|
+
columns: [
|
|
89
|
+
{ id: 'col_0', label: 'Full Name', type: 'string' },
|
|
90
|
+
{ id: 'col_1', label: 'Age', type: 'number' },
|
|
91
|
+
],
|
|
92
|
+
}
|
|
93
|
+
const code = generateCSVFileFetcher(config)
|
|
94
|
+
|
|
95
|
+
expect(code).toContain('const configColumns = ')
|
|
96
|
+
expect(code).toContain('Full Name')
|
|
97
|
+
expect(code).toContain('Age')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('includes all necessary helper functions', () => {
|
|
101
|
+
const config = {
|
|
102
|
+
fileContent: 'name,age\nJohn,30',
|
|
103
|
+
}
|
|
104
|
+
const code = generateCSVFileFetcher(config)
|
|
105
|
+
|
|
106
|
+
expect(code).toContain('safeJSONParse')
|
|
107
|
+
expect(code).toContain('formatDateValue')
|
|
108
|
+
expect(code).toContain('getNestedValue')
|
|
109
|
+
expect(code).toContain('compareValues')
|
|
110
|
+
expect(code).toContain('COMMON_HEADER_PATTERNS')
|
|
111
|
+
expect(code).toContain('DATA_PATTERNS')
|
|
112
|
+
expect(code).toContain('looksLikeDataValue')
|
|
113
|
+
expect(code).toContain('looksLikeHeaderValue')
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe('generateCSVFileFetcher backward compatibility', () => {
|
|
118
|
+
it('generates simple fetcher when only parsedData is provided', () => {
|
|
119
|
+
const config = {
|
|
120
|
+
parsedData: [
|
|
121
|
+
{ col_0: 'John', col_1: 30 },
|
|
122
|
+
{ col_0: 'Jane', col_1: 25 },
|
|
123
|
+
],
|
|
124
|
+
columns: [
|
|
125
|
+
{ id: 'col_0', label: 'Name' },
|
|
126
|
+
{ id: 'col_1', label: 'Age' },
|
|
127
|
+
],
|
|
128
|
+
}
|
|
129
|
+
const code = generateCSVFileFetcher(config)
|
|
130
|
+
|
|
131
|
+
expect(code).toContain('const data = ')
|
|
132
|
+
expect(code).toContain('const columns = ')
|
|
133
|
+
expect(code).not.toContain('parseCSVLine')
|
|
134
|
+
expect(code).not.toContain('detectHeaderRow')
|
|
135
|
+
expect(code).not.toContain('parseCSVContent')
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('maintains backward compatibility with existing parsedData format', () => {
|
|
139
|
+
const config = {
|
|
140
|
+
parsedData: [{ name: 'John' }],
|
|
141
|
+
}
|
|
142
|
+
const code = generateCSVFileFetcher(config)
|
|
143
|
+
|
|
144
|
+
expect(code).toContain('export default async function handler')
|
|
145
|
+
expect(code).toContain('const data = ')
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
describe('generated code structure', () => {
|
|
150
|
+
it('exports handler function in both cases', () => {
|
|
151
|
+
const configWithFileContent = {
|
|
152
|
+
fileContent: 'name\nJohn',
|
|
153
|
+
}
|
|
154
|
+
const configWithParsedData = {
|
|
155
|
+
parsedData: [{ col_0: 'John' }],
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const codeWithFileContent = generateCSVFileFetcher(configWithFileContent)
|
|
159
|
+
const codeWithParsedData = generateCSVFileFetcher(configWithParsedData)
|
|
160
|
+
|
|
161
|
+
expect(codeWithFileContent).toContain('export default async function handler')
|
|
162
|
+
expect(codeWithParsedData).toContain('export default async function handler')
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('includes sorting and filtering logic', () => {
|
|
166
|
+
const config = {
|
|
167
|
+
fileContent: 'name\nJohn',
|
|
168
|
+
}
|
|
169
|
+
const code = generateCSVFileFetcher(config)
|
|
170
|
+
|
|
171
|
+
expect(code).toContain('if (query)')
|
|
172
|
+
expect(code).toContain('if (filters)')
|
|
173
|
+
expect(code).toContain('if (sorts)')
|
|
174
|
+
expect(code).toContain('if (sortBy)')
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('includes pagination logic', () => {
|
|
178
|
+
const config = {
|
|
179
|
+
fileContent: 'name\nJohn',
|
|
180
|
+
}
|
|
181
|
+
const code = generateCSVFileFetcher(config)
|
|
182
|
+
|
|
183
|
+
expect(code).toContain('limit')
|
|
184
|
+
expect(code).toContain('offset')
|
|
185
|
+
expect(code).toContain('page')
|
|
186
|
+
expect(code).toContain('perPage')
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
describe('header detection with names-only CSV', () => {
|
|
191
|
+
it('does not treat first name as header when all rows are names', () => {
|
|
192
|
+
const config = {
|
|
193
|
+
fileContent: 'Paul\nNelu\nPop paul\nPop roxi\nGalea',
|
|
194
|
+
autoDetectHeader: true,
|
|
195
|
+
}
|
|
196
|
+
const code = generateCSVFileFetcher(config)
|
|
197
|
+
|
|
198
|
+
expect(code).toContain('parseCSVContent')
|
|
199
|
+
expect(code).toContain('const autoDetectHeader = true')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('includes all names as data when CSV has only names', () => {
|
|
203
|
+
const config = {
|
|
204
|
+
fileContent: 'John\nJane\nBob\nAlice',
|
|
205
|
+
autoDetectHeader: true,
|
|
206
|
+
}
|
|
207
|
+
const code = generateCSVFileFetcher(config)
|
|
208
|
+
|
|
209
|
+
expect(code).toContain('detectHeaderRow')
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
})
|
|
@@ -279,10 +279,10 @@ describe('validateCSVConfig', () => {
|
|
|
279
279
|
expect(result.isValid).toBe(true)
|
|
280
280
|
})
|
|
281
281
|
|
|
282
|
-
it('rejects missing parsedData', () => {
|
|
282
|
+
it('rejects missing parsedData and fileContent', () => {
|
|
283
283
|
const result = validateCSVConfig({})
|
|
284
284
|
expect(result.isValid).toBe(false)
|
|
285
|
-
expect(result.error).toContain('
|
|
285
|
+
expect(result.error).toContain('Either fileContent or parsedData')
|
|
286
286
|
})
|
|
287
287
|
|
|
288
288
|
it('rejects invalid data type', () => {
|
|
@@ -311,6 +311,37 @@ describe('validateCSVConfig', () => {
|
|
|
311
311
|
expect(result.isValid).toBe(false)
|
|
312
312
|
expect(result.error).toContain('column must have a valid id')
|
|
313
313
|
})
|
|
314
|
+
|
|
315
|
+
it('accepts fileContent instead of parsedData', () => {
|
|
316
|
+
const result = validateCSVConfig({
|
|
317
|
+
fileContent: 'name,age\nJohn,30',
|
|
318
|
+
})
|
|
319
|
+
expect(result.isValid).toBe(true)
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
it('rejects invalid fileContent type', () => {
|
|
323
|
+
const result = validateCSVConfig({
|
|
324
|
+
fileContent: 123,
|
|
325
|
+
})
|
|
326
|
+
expect(result.isValid).toBe(false)
|
|
327
|
+
expect(result.error).toContain('File content must be a string')
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
it('accepts both fileContent and autoDetectHeader', () => {
|
|
331
|
+
const result = validateCSVConfig({
|
|
332
|
+
fileContent: 'name,age\nJohn,30',
|
|
333
|
+
autoDetectHeader: true,
|
|
334
|
+
})
|
|
335
|
+
expect(result.isValid).toBe(true)
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('accepts both fileContent and firstRowIsHeader', () => {
|
|
339
|
+
const result = validateCSVConfig({
|
|
340
|
+
fileContent: 'name,age\nJohn,30',
|
|
341
|
+
firstRowIsHeader: true,
|
|
342
|
+
})
|
|
343
|
+
expect(result.isValid).toBe(true)
|
|
344
|
+
})
|
|
314
345
|
})
|
|
315
346
|
|
|
316
347
|
describe('edge cases for all validators', () => {
|
|
@@ -4,11 +4,11 @@ interface DataSourceFetcherDependencies {
|
|
|
4
4
|
isDefaultImport?: boolean;
|
|
5
5
|
}
|
|
6
6
|
export declare const getDataSourceDependencies: (type: DataSourceType) => DataSourceFetcherDependencies;
|
|
7
|
-
export declare
|
|
7
|
+
export declare function generateDataSourceFetcher(dataSource: UIDLDataSource, tableName: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Generates a fetcher with both a core fetchData function (for server-side use in getStaticProps)
|
|
10
10
|
* and an API handler (for client-side use)
|
|
11
11
|
*/
|
|
12
|
-
export declare
|
|
12
|
+
export declare function generateDataSourceFetcherWithCore(dataSource: UIDLDataSource, tableName: string, isApiRoute?: boolean): string;
|
|
13
13
|
export {};
|
|
14
14
|
//# sourceMappingURL=data-source-fetchers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-source-fetchers.d.ts","sourceRoot":"","sources":["../../src/data-source-fetchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAkC3E,UAAU,6BAA6B;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,eAAO,MAAM,yBAAyB,SAAU,cAAc,KAAG,6BAuBhE,CAAA;AAED,
|
|
1
|
+
{"version":3,"file":"data-source-fetchers.d.ts","sourceRoot":"","sources":["../../src/data-source-fetchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAkC3E,UAAU,6BAA6B;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,eAAO,MAAM,yBAAyB,SAAU,cAAc,KAAG,6BAuBhE,CAAA;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA2J/F;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,OAAe,GAC1B,MAAM,CAmGR"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
3
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
4
|
+
if (ar || !(i in from)) {
|
|
5
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
6
|
+
ar[i] = from[i];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.generateDataSourceFetcherWithCore = exports.generateDataSourceFetcher = exports.getDataSourceDependencies = void 0;
|
|
4
13
|
var fetchers_1 = require("./fetchers");
|
|
@@ -28,7 +37,7 @@ var getDataSourceDependencies = function (type) {
|
|
|
28
37
|
return dependencyMap[type];
|
|
29
38
|
};
|
|
30
39
|
exports.getDataSourceDependencies = getDataSourceDependencies;
|
|
31
|
-
|
|
40
|
+
function generateDataSourceFetcher(dataSource, tableName) {
|
|
32
41
|
if (!dataSource || typeof dataSource !== 'object') {
|
|
33
42
|
throw new Error('Invalid data source: data source must be a valid object');
|
|
34
43
|
}
|
|
@@ -164,22 +173,36 @@ var generateDataSourceFetcher = function (dataSource, tableName) {
|
|
|
164
173
|
var errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
165
174
|
throw new Error("Failed to generate fetcher for ".concat(type, ": ").concat(errorMessage));
|
|
166
175
|
}
|
|
167
|
-
}
|
|
176
|
+
}
|
|
168
177
|
exports.generateDataSourceFetcher = generateDataSourceFetcher;
|
|
169
178
|
/**
|
|
170
179
|
* Generates a fetcher with both a core fetchData function (for server-side use in getStaticProps)
|
|
171
180
|
* and an API handler (for client-side use)
|
|
172
181
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
182
|
+
function generateDataSourceFetcherWithCore(dataSource, tableName, isApiRoute) {
|
|
183
|
+
if (isApiRoute === void 0) { isApiRoute = false; }
|
|
184
|
+
var apiHandler = generateDataSourceFetcher(dataSource, tableName);
|
|
175
185
|
// Extract the handler function body from the API route
|
|
176
186
|
// The API route is structured as: export default async function handler(req, res) { ... }
|
|
177
187
|
// We need to create a fetchData function that can be called directly
|
|
178
188
|
// Remove "export default" from the handler and make it a regular function
|
|
179
189
|
var handlerCode = apiHandler.replace('export default async function handler', 'async function handler');
|
|
180
|
-
//
|
|
190
|
+
// Extract imports from handlerCode (they should be at the top)
|
|
191
|
+
var importRegex = /^import\s+.*?$/gm;
|
|
192
|
+
var imports = handlerCode.match(importRegex) || [];
|
|
193
|
+
var handlerWithoutImports = handlerCode.replace(importRegex, '').trim();
|
|
194
|
+
// Generate count fetcher code and extract its imports
|
|
181
195
|
var countFetcherCode = (0, count_fetchers_1.generateCountFetcher)(dataSource, tableName);
|
|
182
|
-
|
|
183
|
-
|
|
196
|
+
var countImports = countFetcherCode.match(importRegex) || [];
|
|
197
|
+
var countFetcherWithoutImports = countFetcherCode.replace(importRegex, '').trim();
|
|
198
|
+
// Combine and deduplicate imports
|
|
199
|
+
var allImports = Array.from(new Set(__spreadArray(__spreadArray([], imports, true), countImports, true)));
|
|
200
|
+
// For API routes, export just the handler function
|
|
201
|
+
// For utils files, export the full object with all functions
|
|
202
|
+
var exports = isApiRoute
|
|
203
|
+
? 'export default handler'
|
|
204
|
+
: "export { fetchData, fetchCount, handler, getCount }\nexport default { fetchData, fetchCount, handler, getCount }";
|
|
205
|
+
return "".concat(allImports.join('\n'), "\n\nasync function fetchData(params = {}) {\n const req = {\n query: params,\n method: 'GET',\n }\n \n let result = null\n let statusCode = 200\n \n const res = {\n status: (code) => {\n statusCode = code\n return res\n },\n json: (data) => {\n result = data\n return res\n },\n }\n \n await handler(req, res)\n \n if (statusCode !== 200 || !result || !result.success) {\n throw new Error(result?.error || 'Failed to fetch data')\n }\n \n return result.data\n}\n\nasync function fetchCount(params = {}) {\n const req = {\n query: params,\n method: 'GET',\n }\n \n let result = null\n let statusCode = 200\n \n const res = {\n status: (code) => {\n statusCode = code\n return res\n },\n json: (data) => {\n result = data\n return res\n },\n }\n \n await getCount(req, res)\n \n if (statusCode !== 200 || !result || !result.success) {\n throw new Error(result?.error || 'Failed to get count')\n }\n \n return result.count\n}\n\n").concat(countFetcherWithoutImports, "\n\n").concat(handlerWithoutImports, "\n\n").concat(exports, "\n");
|
|
206
|
+
}
|
|
184
207
|
exports.generateDataSourceFetcherWithCore = generateDataSourceFetcherWithCore;
|
|
185
208
|
//# sourceMappingURL=data-source-fetchers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-source-fetchers.js","sourceRoot":"","sources":["../../src/data-source-fetchers.ts"],"names":[],"mappings":"
|
|
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":"
|
|
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"}
|
|
@@ -19,7 +19,7 @@ var generateAirtableFetcher = function (config, tableName) {
|
|
|
19
19
|
var airtableConfig = config;
|
|
20
20
|
var baseId = airtableConfig.baseId;
|
|
21
21
|
var personalAccessToken = airtableConfig.personalAccessToken;
|
|
22
|
-
return "import fetch from 'node-fetch'\n\n".concat((0, utils_1.generateDateFormatterCode)(), "\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
|
|
22
|
+
return "import fetch from 'node-fetch'\n\n".concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.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((0, utils_1.replaceSecretReference)(personalAccessToken, {
|
|
23
23
|
templateLiteral: true,
|
|
24
24
|
}), "`,\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");
|
|
25
25
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"airtable.js","sourceRoot":"","sources":["../../../src/fetchers/airtable.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"airtable.js","sourceRoot":"","sources":["../../../src/fetchers/airtable.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,IAAM,sBAAsB,GAAG,UACpC,MAA+B;IAE/B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAA;KAClE;IAED,IAAI,CAAC,MAAM,CAAC,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;AAhBY,QAAA,sBAAsB,0BAgBlC;AAQM,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,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,m/GA+FiB,MAAM,oCAA2B,SAAS,wkBAepD,IAAA,8BAAsB,EAAC,mBAAmB,EAAE;QACpE,eAAe,EAAE,IAAI;KACtB,CAAC,+1CA+CX,CAAA;AACD,CAAC,CAAA;AA5KY,QAAA,uBAAuB,2BA4KnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -23,7 +23,7 @@ var generateClickHouseFetcher = function (config, tableName) {
|
|
|
23
23
|
var url = clickConfig.url;
|
|
24
24
|
var username = clickConfig.username;
|
|
25
25
|
var password = clickConfig.password;
|
|
26
|
-
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((0, utils_1.replaceSecretReference)(password), "\n })\n \n return client\n}\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, offset } = req.query\n \n const conditions = []\n \n if (query) {\n if (queryColumns) {\n const
|
|
26
|
+
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((0, utils_1.replaceSecretReference)(password), "\n })\n \n return client\n}\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\nexport default async function handler(req, res) {\n try {\n const client = getClient()\n const { query, queryColumns, 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");
|
|
27
27
|
};
|
|
28
28
|
exports.generateClickHouseFetcher = generateClickHouseFetcher;
|
|
29
29
|
//# sourceMappingURL=clickhouse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickhouse.js","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"clickhouse.js","sourceRoot":"","sources":["../../../src/fetchers/clickhouse.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,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;AApBY,QAAA,wBAAwB,4BAoBpC;AAQM,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,IAAA,8BAAsB,EAAC,QAAQ,CAAC,+CAM9C,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,80GAsFG,SAAS,oqDAqDxC,CAAA;AACD,CAAC,CAAA;AAvKY,QAAA,yBAAyB,6BAuKrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv-file.d.ts","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -2,14 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateCSVCountFetcher = exports.generateCSVFileFetcher = exports.validateCSVConfig = void 0;
|
|
4
4
|
var utils_1 = require("../utils");
|
|
5
|
+
var header_detection_1 = require("./utils/header-detection");
|
|
5
6
|
var validateCSVConfig = function (config) {
|
|
6
7
|
if (!config || typeof config !== 'object') {
|
|
7
8
|
return { isValid: false, error: 'Config must be a valid object' };
|
|
8
9
|
}
|
|
9
|
-
if (!config.
|
|
10
|
+
if (!config.fileContent && !config.parsedData) {
|
|
11
|
+
return { isValid: false, error: 'Either fileContent or parsedData must be provided' };
|
|
12
|
+
}
|
|
13
|
+
if (config.fileContent && typeof config.fileContent !== 'string') {
|
|
14
|
+
return { isValid: false, error: 'File content must be a string' };
|
|
15
|
+
}
|
|
16
|
+
if (config.parsedData && !Array.isArray(config.parsedData)) {
|
|
10
17
|
return { isValid: false, error: 'Parsed data must be an array' };
|
|
11
18
|
}
|
|
12
|
-
// Columns are optional - if not provided, we'll infer them from parsedData
|
|
13
19
|
if (config.columns !== undefined) {
|
|
14
20
|
if (!Array.isArray(config.columns)) {
|
|
15
21
|
return { isValid: false, error: 'Columns definition must be an array' };
|
|
@@ -24,9 +30,22 @@ var validateCSVConfig = function (config) {
|
|
|
24
30
|
return { isValid: true };
|
|
25
31
|
};
|
|
26
32
|
exports.validateCSVConfig = validateCSVConfig;
|
|
33
|
+
var generateHandlerBody = function () {
|
|
34
|
+
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";
|
|
35
|
+
};
|
|
27
36
|
var generateCSVFileFetcher = function (config) {
|
|
28
37
|
var csvConfig = config;
|
|
29
|
-
|
|
38
|
+
// Get header detection flags, ensuring boolean false values are preserved
|
|
39
|
+
var autoDetectHeader = csvConfig.autoDetectHeader !== false;
|
|
40
|
+
var firstRowIsHeader = csvConfig.firstRowIsHeader !== false;
|
|
41
|
+
var configColumns = csvConfig.columns || [];
|
|
42
|
+
if (csvConfig.fileContent) {
|
|
43
|
+
var fileContent = csvConfig.fileContent;
|
|
44
|
+
return "const csvContent = ".concat(JSON.stringify(fileContent), "\nconst autoDetectHeader = ").concat(autoDetectHeader, "\nconst firstRowIsHeader = ").concat(firstRowIsHeader, "\nconst configColumns = ").concat(JSON.stringify(configColumns), "\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\n").concat((0, utils_1.generateSortFilterHelperCode)(), "\n\n").concat((0, header_detection_1.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");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return "const data = ".concat(JSON.stringify(csvConfig.parsedData || []), "\nconst columns = ").concat(JSON.stringify(configColumns), "\n\n").concat((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.generateDateFormatterCode)(), "\n\n").concat((0, utils_1.generateSortFilterHelperCode)(), "\n\nexport default async function handler(req, res) {").concat(generateHandlerBody(), "\n}\n");
|
|
48
|
+
}
|
|
30
49
|
};
|
|
31
50
|
exports.generateCSVFileFetcher = generateCSVFileFetcher;
|
|
32
51
|
// tslint:disable-next-line:variable-name
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv-file.js","sourceRoot":"","sources":["../../../src/fetchers/csv-file.ts"],"names":[],"mappings":";;;AAAA,
|
|
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":"
|
|
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"}
|
|
@@ -29,7 +29,7 @@ exports.validateFirestoreConfig = validateFirestoreConfig;
|
|
|
29
29
|
var generateFirestoreFetcher = function (config, tableName) {
|
|
30
30
|
var firestoreConfig = config;
|
|
31
31
|
var serviceAccount = firestoreConfig.serviceAccount;
|
|
32
|
-
return "import * as admin from 'firebase-admin'\n\nlet firestore = null\n\nconst getFirestore = () => {\n if (firestore) return firestore\n \n const rawServiceAccount = ".concat((0, utils_1.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((0, utils_1.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, offset } = req.query\n \n let queryRef = firestore.collection('").concat(tableName, "')\n \n if (filters) {\n const parsedFilters =
|
|
32
|
+
return "import * as admin from 'firebase-admin'\n\nlet firestore = null\n\nconst getFirestore = () => {\n if (firestore) return firestore\n \n const rawServiceAccount = ".concat((0, utils_1.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((0, utils_1.generateSafeJSONParseCode)(), "\n\n").concat((0, utils_1.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");
|
|
33
33
|
};
|
|
34
34
|
exports.generateFirestoreFetcher = generateFirestoreFetcher;
|
|
35
35
|
//# sourceMappingURL=firestore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestore.js","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"firestore.js","sourceRoot":"","sources":["../../../src/fetchers/firestore.ts"],"names":[],"mappings":";;;AAAA,kCAIiB;AAEV,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;AA3BY,QAAA,uBAAuB,2BA2BnC;AAOM,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,IAAA,8BAAsB,EAAC,cAAc,CAAC,+YAmBlE,IAAA,iCAAyB,GAAE,iBAE3B,IAAA,iCAAyB,GAAE,kRAOc,SAAS,uyIA0InD,CAAA;AACD,CAAC,CAAA;AArLY,QAAA,wBAAwB,4BAqLpC"}
|