@intuned/browser-dev 0.1.4-dev.1 → 0.1.5-dev.1
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/README.md +0 -1
- package/dist/ai/export.d.ts +1 -1
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/isPageLoaded.js +14 -3
- package/dist/ai/tests/testIsPageLoaded.spec.js +3 -3
- package/dist/helpers/downloadFile.js +37 -0
- package/dist/helpers/export.d.ts +10 -7
- package/dist/helpers/frame_utils/constants.js +8 -0
- package/dist/helpers/frame_utils/findAllIframes.js +79 -0
- package/dist/helpers/frame_utils/getContainerFrame.js +22 -0
- package/dist/helpers/frame_utils/index.js +44 -0
- package/dist/helpers/frame_utils/tests/testFindAllIframes.spec.js +170 -0
- package/dist/helpers/gotoUrl.js +1 -1
- package/dist/helpers/index.d.ts +10 -7
- package/dist/helpers/index.js +0 -19
- package/dist/helpers/tests/testDownloadFile.spec.js +41 -6
- package/dist/helpers/tests/testInjectAttachmentType.spec.js +482 -0
- package/dist/helpers/tests/testValidateDataUsingSchema.spec.js +35 -31
- package/dist/helpers/tests/testWithDomSettledWait.spec.js +119 -0
- package/dist/helpers/types/Attachment.js +11 -6
- package/dist/helpers/types/index.js +1 -20
- package/dist/helpers/uploadFileToS3.js +2 -2
- package/dist/helpers/validateDataUsingSchema.js +30 -71
- package/dist/helpers/waitForDomSettled.js +57 -40
- package/dist/intunedServices/ApiGateway/tests/testApiGateway.spec.js +4 -4
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/testArrayExtractorFromPage.spec.js +271 -2
- package/dist/optimized-extractors/listExtractionHelpers/runAiExtraction.js +55 -8
- package/generated-docs/ai/functions/extractStructuredData.mdx +5 -5
- package/generated-docs/ai/functions/isPageLoaded.mdx +1 -0
- package/generated-docs/helpers/functions/clickButtonAndWait.mdx +63 -0
- package/generated-docs/helpers/functions/clickUntilExhausted.mdx +112 -0
- package/generated-docs/helpers/functions/scrollToLoadContent.mdx +1 -7
- package/generated-docs/helpers/functions/validateDataUsingSchema.mdx +5 -5
- package/how-to-generate-docs.md +1 -0
- package/package.json +2 -2
- package/dist/helpers/types/CustomTypeRegistry.js +0 -48
|
@@ -23,10 +23,10 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
23
23
|
age: 30,
|
|
24
24
|
extra_field: "allowed"
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
27
27
|
data,
|
|
28
28
|
schema
|
|
29
|
-
})).
|
|
29
|
+
})).not.toThrow();
|
|
30
30
|
});
|
|
31
31
|
(0, _extendedTest.test)("should validate data using schema with invalid data (missing required field)", async () => {
|
|
32
32
|
const schema = {
|
|
@@ -44,12 +44,12 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
44
44
|
const invalidData = {
|
|
45
45
|
name: "John Doe"
|
|
46
46
|
};
|
|
47
|
-
|
|
47
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
48
48
|
data: invalidData,
|
|
49
49
|
schema
|
|
50
|
-
})).
|
|
50
|
+
})).toThrow(_types.ValidationError);
|
|
51
51
|
try {
|
|
52
|
-
|
|
52
|
+
(0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
53
53
|
data: invalidData,
|
|
54
54
|
schema
|
|
55
55
|
});
|
|
@@ -84,10 +84,10 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
84
84
|
age: 25,
|
|
85
85
|
other: "value"
|
|
86
86
|
}];
|
|
87
|
-
|
|
87
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
88
88
|
data,
|
|
89
89
|
schema
|
|
90
|
-
})).
|
|
90
|
+
})).not.toThrow();
|
|
91
91
|
});
|
|
92
92
|
(0, _extendedTest.test)("should validate data using schema with list containing invalid object", async () => {
|
|
93
93
|
const schema = {
|
|
@@ -112,12 +112,12 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
112
112
|
name: "Jane Doe",
|
|
113
113
|
age: "25"
|
|
114
114
|
}];
|
|
115
|
-
|
|
115
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
116
116
|
data: invalidData,
|
|
117
117
|
schema
|
|
118
|
-
})).
|
|
118
|
+
})).toThrow(_types.ValidationError);
|
|
119
119
|
try {
|
|
120
|
-
|
|
120
|
+
(0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
121
121
|
data: invalidData,
|
|
122
122
|
schema
|
|
123
123
|
});
|
|
@@ -128,7 +128,7 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
128
128
|
(0, _extendedTest.expect)(error.data).toEqual(invalidData);
|
|
129
129
|
}
|
|
130
130
|
});
|
|
131
|
-
(0, _extendedTest.test)("should validate data using schema with attachment
|
|
131
|
+
(0, _extendedTest.test)("should validate data using schema with attachment type", async () => {
|
|
132
132
|
const schema = {
|
|
133
133
|
type: "object",
|
|
134
134
|
properties: {
|
|
@@ -146,18 +146,19 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
146
146
|
fileName: "documents/report.pdf",
|
|
147
147
|
bucket: "my-bucket",
|
|
148
148
|
region: "us-east-1",
|
|
149
|
+
key: "documents/report.pdf",
|
|
149
150
|
endpoint: null,
|
|
150
151
|
suggestedFileName: "Monthly Report.pdf",
|
|
151
152
|
fileType: "document"
|
|
152
153
|
},
|
|
153
154
|
name: "Test File Upload"
|
|
154
155
|
};
|
|
155
|
-
|
|
156
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
156
157
|
data: validData,
|
|
157
158
|
schema
|
|
158
|
-
})).
|
|
159
|
+
})).not.toThrow();
|
|
159
160
|
});
|
|
160
|
-
(0, _extendedTest.test)("should validate data using schema with invalid attachment
|
|
161
|
+
(0, _extendedTest.test)("should validate data using schema with invalid attachment type", async () => {
|
|
161
162
|
const schema = {
|
|
162
163
|
type: "object",
|
|
163
164
|
properties: {
|
|
@@ -176,19 +177,18 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
176
177
|
},
|
|
177
178
|
name: "Test File Upload"
|
|
178
179
|
};
|
|
179
|
-
|
|
180
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
180
181
|
data: invalidData,
|
|
181
182
|
schema
|
|
182
|
-
})).
|
|
183
|
+
})).toThrow(_types.ValidationError);
|
|
183
184
|
try {
|
|
184
|
-
|
|
185
|
+
(0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
185
186
|
data: invalidData,
|
|
186
187
|
schema
|
|
187
188
|
});
|
|
188
189
|
} catch (error) {
|
|
189
190
|
(0, _extendedTest.expect)(error).toBeInstanceOf(_types.ValidationError);
|
|
190
191
|
(0, _extendedTest.expect)(error.message).toContain("Data validation failed");
|
|
191
|
-
(0, _extendedTest.expect)(error.message).toContain("does not match custom type 'attachment'");
|
|
192
192
|
(0, _extendedTest.expect)(error.data).toEqual(invalidData);
|
|
193
193
|
}
|
|
194
194
|
});
|
|
@@ -213,6 +213,7 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
213
213
|
fileName: "doc1.pdf",
|
|
214
214
|
bucket: "bucket1",
|
|
215
215
|
region: "us-east-1",
|
|
216
|
+
key: "files/doc1.pdf",
|
|
216
217
|
suggestedFileName: "Document 1.pdf"
|
|
217
218
|
},
|
|
218
219
|
description: "First document"
|
|
@@ -221,14 +222,15 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
221
222
|
fileName: "doc2.pdf",
|
|
222
223
|
bucket: "bucket2",
|
|
223
224
|
region: "us-west-2",
|
|
225
|
+
key: "files/doc2.pdf",
|
|
224
226
|
suggestedFileName: "Document 2.pdf"
|
|
225
227
|
},
|
|
226
228
|
description: "Second document"
|
|
227
229
|
}];
|
|
228
|
-
|
|
230
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
229
231
|
data: validData,
|
|
230
232
|
schema
|
|
231
|
-
})).
|
|
233
|
+
})).not.toThrow();
|
|
232
234
|
});
|
|
233
235
|
(0, _extendedTest.test)("should validate data using schema with invalid attachment in array", async () => {
|
|
234
236
|
const schema = {
|
|
@@ -251,6 +253,7 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
251
253
|
fileName: "doc1.pdf",
|
|
252
254
|
bucket: "bucket1",
|
|
253
255
|
region: "us-east-1",
|
|
256
|
+
key: "files/doc1.pdf",
|
|
254
257
|
suggestedFileName: "Document 1.pdf"
|
|
255
258
|
},
|
|
256
259
|
description: "First document"
|
|
@@ -260,23 +263,22 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
260
263
|
},
|
|
261
264
|
description: "Second document"
|
|
262
265
|
}];
|
|
263
|
-
|
|
266
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
264
267
|
data: invalidData,
|
|
265
268
|
schema
|
|
266
|
-
})).
|
|
269
|
+
})).toThrow(_types.ValidationError);
|
|
267
270
|
try {
|
|
268
|
-
|
|
271
|
+
(0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
269
272
|
data: invalidData,
|
|
270
273
|
schema
|
|
271
274
|
});
|
|
272
275
|
} catch (error) {
|
|
273
276
|
(0, _extendedTest.expect)(error).toBeInstanceOf(_types.ValidationError);
|
|
274
277
|
(0, _extendedTest.expect)(error.message).toContain("Data validation failed");
|
|
275
|
-
(0, _extendedTest.expect)(error.message).toContain("does not match custom type 'attachment'");
|
|
276
278
|
(0, _extendedTest.expect)(error.data).toEqual(invalidData);
|
|
277
279
|
}
|
|
278
280
|
});
|
|
279
|
-
(0, _extendedTest.test)("should handle mixed
|
|
281
|
+
(0, _extendedTest.test)("should handle mixed attachment and standard types", async () => {
|
|
280
282
|
const schema = {
|
|
281
283
|
type: "object",
|
|
282
284
|
properties: {
|
|
@@ -300,31 +302,33 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
300
302
|
fileName: "mixed-test.pdf",
|
|
301
303
|
bucket: "test-bucket",
|
|
302
304
|
region: "us-east-1",
|
|
305
|
+
key: "files/mixed-test.pdf",
|
|
303
306
|
suggestedFileName: "Mixed Test.pdf"
|
|
304
307
|
},
|
|
305
308
|
title: "Mixed validation test",
|
|
306
309
|
count: 42,
|
|
307
310
|
active: true
|
|
308
311
|
};
|
|
309
|
-
|
|
312
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
310
313
|
data: validData,
|
|
311
314
|
schema
|
|
312
|
-
})).
|
|
315
|
+
})).not.toThrow();
|
|
313
316
|
const invalidStandardData = {
|
|
314
317
|
attachment: {
|
|
315
318
|
fileName: "mixed-test.pdf",
|
|
316
319
|
bucket: "test-bucket",
|
|
317
320
|
region: "us-east-1",
|
|
321
|
+
key: "files/mixed-test.pdf",
|
|
318
322
|
suggestedFileName: "Mixed Test.pdf"
|
|
319
323
|
},
|
|
320
324
|
title: "Mixed validation test",
|
|
321
325
|
count: "not-a-number",
|
|
322
326
|
active: true
|
|
323
327
|
};
|
|
324
|
-
|
|
328
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
325
329
|
data: invalidStandardData,
|
|
326
330
|
schema
|
|
327
|
-
})).
|
|
331
|
+
})).toThrow(_types.ValidationError);
|
|
328
332
|
const invalidCustomData = {
|
|
329
333
|
attachment: {
|
|
330
334
|
fileName: "mixed-test.pdf"
|
|
@@ -333,10 +337,10 @@ var _extendedTest = require("../../common/extendedTest");
|
|
|
333
337
|
count: 42,
|
|
334
338
|
active: true
|
|
335
339
|
};
|
|
336
|
-
|
|
340
|
+
(0, _extendedTest.expect)(() => (0, _validateDataUsingSchema.validateDataUsingSchema)({
|
|
337
341
|
data: invalidCustomData,
|
|
338
342
|
schema
|
|
339
|
-
})).
|
|
343
|
+
})).toThrow(_types.ValidationError);
|
|
340
344
|
});
|
|
341
345
|
});
|
|
342
346
|
});
|
|
@@ -161,4 +161,123 @@ var _waitForDomSettled = require("../waitForDomSettled");
|
|
|
161
161
|
const content = await page.textContent("#target");
|
|
162
162
|
(0, _extendedTest.expect)(content).toContain("Locator source content");
|
|
163
163
|
});
|
|
164
|
+
(0, _extendedTest.test)("should wait for DOM to settle with iframe dynamic content", async () => {
|
|
165
|
+
await page.goto(`
|
|
166
|
+
data:text/html,
|
|
167
|
+
<html>
|
|
168
|
+
<body>
|
|
169
|
+
<h1>Main Page</h1>
|
|
170
|
+
<iframe id="test-iframe"
|
|
171
|
+
src="data:text/html,<html><body><div id='iframe-content'>Initial content</div></body></html>"
|
|
172
|
+
width="400"
|
|
173
|
+
height="300">
|
|
174
|
+
</iframe>
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
177
|
+
`);
|
|
178
|
+
await page.waitForTimeout(500);
|
|
179
|
+
const iframeElement = await page.locator("#test-iframe").elementHandle();
|
|
180
|
+
const iframeFrame = await (iframeElement === null || iframeElement === void 0 ? void 0 : iframeElement.contentFrame());
|
|
181
|
+
if (!iframeFrame) {
|
|
182
|
+
throw new Error("Could not get iframe frame");
|
|
183
|
+
}
|
|
184
|
+
await iframeFrame.evaluate(() => {
|
|
185
|
+
let counter = 0;
|
|
186
|
+
const intervalId = setInterval(() => {
|
|
187
|
+
counter++;
|
|
188
|
+
const div = document.createElement("div");
|
|
189
|
+
div.textContent = `Dynamic content ${counter}`;
|
|
190
|
+
div.className = "dynamic-item";
|
|
191
|
+
document.body.appendChild(div);
|
|
192
|
+
if (counter >= 3) {
|
|
193
|
+
clearInterval(intervalId);
|
|
194
|
+
}
|
|
195
|
+
}, 200);
|
|
196
|
+
});
|
|
197
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
198
|
+
source: page,
|
|
199
|
+
settleDurationMs: 1000,
|
|
200
|
+
timeoutInMs: 10000
|
|
201
|
+
});
|
|
202
|
+
(0, _extendedTest.expect)(settled).toBe(true);
|
|
203
|
+
const dynamicItems = await iframeFrame.locator(".dynamic-item").count();
|
|
204
|
+
(0, _extendedTest.expect)(dynamicItems).toBe(3);
|
|
205
|
+
for (let i = 0; i < 3; i++) {
|
|
206
|
+
const content = await iframeFrame.locator(".dynamic-item").nth(i).textContent();
|
|
207
|
+
(0, _extendedTest.expect)(content).toBe(`Dynamic content ${i + 1}`);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
(0, _extendedTest.test)("should wait for DOM to settle with nested iframes", async () => {
|
|
211
|
+
await page.goto(`
|
|
212
|
+
data:text/html,
|
|
213
|
+
<html>
|
|
214
|
+
<body>
|
|
215
|
+
<h1>Main Page</h1>
|
|
216
|
+
<div id="main-content">Main content</div>
|
|
217
|
+
<iframe id="outer-iframe"
|
|
218
|
+
src="data:text/html,<html><body><h2>Outer iframe</h2><div id='outer-content'>Outer initial</div><iframe id='inner-iframe' src='data:text/html,<html><body><h3>Inner iframe</h3><div id=inner-content>Inner initial</div></body></html>'></iframe></body></html>"
|
|
219
|
+
width="500"
|
|
220
|
+
height="400">
|
|
221
|
+
</iframe>
|
|
222
|
+
</body>
|
|
223
|
+
</html>
|
|
224
|
+
`);
|
|
225
|
+
await page.waitForTimeout(1000);
|
|
226
|
+
const outerIframeElement = await page.locator("#outer-iframe").elementHandle();
|
|
227
|
+
const outerFrame = await (outerIframeElement === null || outerIframeElement === void 0 ? void 0 : outerIframeElement.contentFrame());
|
|
228
|
+
if (!outerFrame) {
|
|
229
|
+
throw new Error("Could not get outer frame");
|
|
230
|
+
}
|
|
231
|
+
const innerIframeElement = await outerFrame.locator("#inner-iframe").elementHandle();
|
|
232
|
+
const innerFrame = await (innerIframeElement === null || innerIframeElement === void 0 ? void 0 : innerIframeElement.contentFrame());
|
|
233
|
+
if (!innerFrame) {
|
|
234
|
+
throw new Error("Could not get inner frame");
|
|
235
|
+
}
|
|
236
|
+
await outerFrame.evaluate(() => {
|
|
237
|
+
let outerCounter = 0;
|
|
238
|
+
const outerInterval = setInterval(() => {
|
|
239
|
+
outerCounter++;
|
|
240
|
+
const div = document.createElement("div");
|
|
241
|
+
div.textContent = `Outer dynamic ${outerCounter}`;
|
|
242
|
+
div.className = "outer-dynamic";
|
|
243
|
+
const outerContent = document.getElementById("outer-content");
|
|
244
|
+
outerContent === null || outerContent === void 0 || outerContent.appendChild(div);
|
|
245
|
+
if (outerCounter >= 2) {
|
|
246
|
+
clearInterval(outerInterval);
|
|
247
|
+
}
|
|
248
|
+
}, 150);
|
|
249
|
+
});
|
|
250
|
+
await innerFrame.evaluate(() => {
|
|
251
|
+
let innerCounter = 0;
|
|
252
|
+
const innerInterval = setInterval(() => {
|
|
253
|
+
innerCounter++;
|
|
254
|
+
const div = document.createElement("div");
|
|
255
|
+
div.textContent = `Inner dynamic ${innerCounter}`;
|
|
256
|
+
div.className = "inner-dynamic";
|
|
257
|
+
const innerContent = document.getElementById("inner-content");
|
|
258
|
+
innerContent === null || innerContent === void 0 || innerContent.appendChild(div);
|
|
259
|
+
if (innerCounter >= 2) {
|
|
260
|
+
clearInterval(innerInterval);
|
|
261
|
+
}
|
|
262
|
+
}, 200);
|
|
263
|
+
});
|
|
264
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
265
|
+
source: page,
|
|
266
|
+
settleDurationMs: 1000,
|
|
267
|
+
timeoutInMs: 15000
|
|
268
|
+
});
|
|
269
|
+
(0, _extendedTest.expect)(settled).toBe(true);
|
|
270
|
+
const outerDynamicItems = await outerFrame.locator(".outer-dynamic").count();
|
|
271
|
+
(0, _extendedTest.expect)(outerDynamicItems).toBe(2);
|
|
272
|
+
const innerDynamicItems = await innerFrame.locator(".inner-dynamic").count();
|
|
273
|
+
(0, _extendedTest.expect)(innerDynamicItems).toBe(2);
|
|
274
|
+
for (let i = 0; i < 2; i++) {
|
|
275
|
+
const content = await outerFrame.locator(".outer-dynamic").nth(i).textContent();
|
|
276
|
+
(0, _extendedTest.expect)(content).toBe(`Outer dynamic ${i + 1}`);
|
|
277
|
+
}
|
|
278
|
+
for (let i = 0; i < 2; i++) {
|
|
279
|
+
const content = await innerFrame.locator(".inner-dynamic").nth(i).textContent();
|
|
280
|
+
(0, _extendedTest.expect)(content).toBe(`Inner dynamic ${i + 1}`);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
164
283
|
});
|
|
@@ -12,16 +12,18 @@ var _zod = require("zod");
|
|
|
12
12
|
const AttachmentTypeSchema = exports.AttachmentTypeSchema = _zod.z.literal("document");
|
|
13
13
|
const AttachmentSchema = exports.AttachmentSchema = _zod.z.object({
|
|
14
14
|
fileName: _zod.z.string(),
|
|
15
|
+
key: _zod.z.string(),
|
|
15
16
|
bucket: _zod.z.string(),
|
|
16
17
|
region: _zod.z.string(),
|
|
17
18
|
suggestedFileName: _zod.z.string(),
|
|
18
|
-
endpoint: _zod.z.string().optional(),
|
|
19
|
-
fileType: AttachmentTypeSchema.optional()
|
|
19
|
+
endpoint: _zod.z.string().nullable().optional(),
|
|
20
|
+
fileType: AttachmentTypeSchema.optional().nullable()
|
|
20
21
|
});
|
|
21
22
|
class Attachment {
|
|
22
|
-
constructor(fileName, bucket, region, suggestedFileName, endpoint, fileType) {
|
|
23
|
+
constructor(fileName, key, bucket, region, suggestedFileName, endpoint, fileType) {
|
|
23
24
|
const validatedData = AttachmentSchema.parse({
|
|
24
25
|
fileName,
|
|
26
|
+
key,
|
|
25
27
|
bucket,
|
|
26
28
|
region,
|
|
27
29
|
suggestedFileName,
|
|
@@ -29,8 +31,10 @@ class Attachment {
|
|
|
29
31
|
fileType
|
|
30
32
|
});
|
|
31
33
|
this.fileName = validatedData.fileName;
|
|
34
|
+
this.key = validatedData.key;
|
|
32
35
|
this.bucket = validatedData.bucket;
|
|
33
36
|
this.region = validatedData.region;
|
|
37
|
+
this.key = validatedData.key;
|
|
34
38
|
this.suggestedFileName = validatedData.suggestedFileName;
|
|
35
39
|
this.endpoint = validatedData.endpoint;
|
|
36
40
|
this.fileType = validatedData.fileType;
|
|
@@ -41,6 +45,7 @@ class Attachment {
|
|
|
41
45
|
toDict() {
|
|
42
46
|
return {
|
|
43
47
|
fileName: this.fileName,
|
|
48
|
+
key: this.key,
|
|
44
49
|
bucket: this.bucket,
|
|
45
50
|
region: this.region,
|
|
46
51
|
suggestedFileName: this.suggestedFileName,
|
|
@@ -54,13 +59,13 @@ class Attachment {
|
|
|
54
59
|
}
|
|
55
60
|
static fromDict(data) {
|
|
56
61
|
const validatedData = AttachmentSchema.parse(data);
|
|
57
|
-
return new Attachment(validatedData.fileName, validatedData.bucket, validatedData.region, validatedData.suggestedFileName, validatedData.endpoint, validatedData.fileType);
|
|
62
|
+
return new Attachment(validatedData.fileName, validatedData.key, validatedData.bucket, validatedData.region, validatedData.suggestedFileName, validatedData.endpoint, validatedData.fileType);
|
|
58
63
|
}
|
|
59
64
|
async getSignedUrl(expiration = 3600 * 24 * 5) {
|
|
60
65
|
if ((0, _utils.isGenerateCodeMode)()) {
|
|
61
66
|
return "https://not.real.com";
|
|
62
67
|
}
|
|
63
|
-
const s3Client = (0, _getS3Client.getS3Client)(this.endpoint, this.region);
|
|
68
|
+
const s3Client = (0, _getS3Client.getS3Client)(this.endpoint ?? undefined, this.region);
|
|
64
69
|
try {
|
|
65
70
|
const response = await (0, _s3RequestPresigner.getSignedUrl)(s3Client, new _clientS.GetObjectCommand({
|
|
66
71
|
Bucket: this.bucket,
|
|
@@ -94,7 +99,7 @@ class SignedUrlAttachment extends Attachment {
|
|
|
94
99
|
const bucket = url.hostname.split(".")[0];
|
|
95
100
|
const key = url.pathname.substring(1);
|
|
96
101
|
const validatedUrl = _zod.z.string().url().parse(downloadSignedUrl);
|
|
97
|
-
super(key, bucket, "", suggestedFileName ?? fileName);
|
|
102
|
+
super(fileName, key, bucket, "", suggestedFileName ?? fileName);
|
|
98
103
|
this.downloadSignedUrl = validatedUrl;
|
|
99
104
|
}
|
|
100
105
|
async getSignedUrl() {
|
|
@@ -9,24 +9,6 @@ Object.defineProperty(exports, "Attachment", {
|
|
|
9
9
|
return _Attachment.Attachment;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
-
Object.defineProperty(exports, "AttachmentValidator", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _CustomTypeRegistry.AttachmentValidator;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, "CustomTypeRegistry", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
21
|
-
return _CustomTypeRegistry.CustomTypeRegistry;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, "CustomTypeValidator", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
27
|
-
return _CustomTypeRegistry.CustomTypeValidator;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
12
|
Object.defineProperty(exports, "RunEnvironment", {
|
|
31
13
|
enumerable: true,
|
|
32
14
|
get: function () {
|
|
@@ -47,5 +29,4 @@ Object.defineProperty(exports, "ValidationError", {
|
|
|
47
29
|
});
|
|
48
30
|
var _ValidationError = require("./ValidationError");
|
|
49
31
|
var _RunEnvironment = require("./RunEnvironment");
|
|
50
|
-
var _Attachment = require("./Attachment");
|
|
51
|
-
var _CustomTypeRegistry = require("./CustomTypeRegistry");
|
|
32
|
+
var _Attachment = require("./Attachment");
|
|
@@ -51,7 +51,7 @@ const uploadFileToS3 = async input => {
|
|
|
51
51
|
if ((0, _utils.isGenerateCodeMode)()) {
|
|
52
52
|
console.log("Uploaded file successfully");
|
|
53
53
|
if (isDownloadedFile) {
|
|
54
|
-
return new _Attachment.Attachment(`${(0, _uuid.v4)()}/${file.suggestedFilename()}`, "testing_bucket", "testing_region", file.suggestedFilename() || "downloaded_file", endpoint, "document");
|
|
54
|
+
return new _Attachment.Attachment(`${(0, _uuid.v4)()}/${file.suggestedFilename()}`, `${(0, _uuid.v4)()}/${file.suggestedFilename()}`, "testing_bucket", "testing_region", file.suggestedFilename() || "downloaded_file", endpoint, "document");
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
let suggestedFileName;
|
|
@@ -93,7 +93,7 @@ const uploadFileToS3 = async input => {
|
|
|
93
93
|
});
|
|
94
94
|
const response = await s3Client.send(command);
|
|
95
95
|
if (response.$metadata.httpStatusCode === 200) {
|
|
96
|
-
return new _Attachment.Attachment(key, bucketName, region, suggestedFileName || fileName, endpoint);
|
|
96
|
+
return new _Attachment.Attachment(key, key, bucketName, region, suggestedFileName || fileName, endpoint);
|
|
97
97
|
} else {
|
|
98
98
|
throw new Error("Error uploading file");
|
|
99
99
|
}
|
|
@@ -3,99 +3,58 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.injectAttachmentType = injectAttachmentType;
|
|
6
7
|
exports.validateDataUsingSchema = void 0;
|
|
7
8
|
var _ajv = _interopRequireDefault(require("ajv"));
|
|
9
|
+
var _zodToJsonSchema = require("zod-to-json-schema");
|
|
8
10
|
var _types = require("./types");
|
|
11
|
+
var _Attachment = require("./types/Attachment");
|
|
9
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
13
|
const ajv = new _ajv.default({
|
|
11
14
|
strict: false,
|
|
12
15
|
removeAdditional: false
|
|
13
16
|
});
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const processedSchema = {
|
|
28
|
-
...schema
|
|
29
|
-
};
|
|
30
|
-
if (processedSchema.type && typeof processedSchema.type === "string") {
|
|
31
|
-
if (customTypeRegistry.isCustomType(processedSchema.type)) {
|
|
32
|
-
return {
|
|
33
|
-
type: "object",
|
|
34
|
-
additionalProperties: true,
|
|
35
|
-
"x-custom-type": processedSchema.type
|
|
36
|
-
};
|
|
17
|
+
function injectAttachmentType(schema) {
|
|
18
|
+
const schemaCopy = JSON.parse(JSON.stringify(schema));
|
|
19
|
+
const attachmentJsonSchema = (0, _zodToJsonSchema.zodToJsonSchema)(_Attachment.AttachmentSchema, {
|
|
20
|
+
$refStrategy: "none"
|
|
21
|
+
});
|
|
22
|
+
const attachmentDefinition = typeof attachmentJsonSchema === "object" && attachmentJsonSchema !== null ? attachmentJsonSchema : {};
|
|
23
|
+
if (!schemaCopy.$defs) {
|
|
24
|
+
schemaCopy.$defs = {};
|
|
25
|
+
}
|
|
26
|
+
schemaCopy.$defs.attachment = attachmentDefinition;
|
|
27
|
+
function replaceAttachmentType(node) {
|
|
28
|
+
if (typeof node !== "object" || node === null) {
|
|
29
|
+
return node;
|
|
37
30
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (key === "properties" && typeof processedSchema[key] === "object") {
|
|
41
|
-
const newProperties = {};
|
|
42
|
-
for (const propKey in processedSchema[key]) {
|
|
43
|
-
newProperties[propKey] = preprocessSchema(processedSchema[key][propKey]);
|
|
44
|
-
}
|
|
45
|
-
processedSchema[key] = newProperties;
|
|
46
|
-
} else if (key === "items") {
|
|
47
|
-
processedSchema[key] = preprocessSchema(processedSchema[key]);
|
|
48
|
-
} else if (typeof processedSchema[key] === "object") {
|
|
49
|
-
processedSchema[key] = preprocessSchema(processedSchema[key]);
|
|
31
|
+
if (Array.isArray(node)) {
|
|
32
|
+
return node.map(item => replaceAttachmentType(item));
|
|
50
33
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (typeof schema !== "object" || schema === null) {
|
|
57
|
-
return errors;
|
|
58
|
-
}
|
|
59
|
-
if (schema["x-custom-type"]) {
|
|
60
|
-
const customType = schema["x-custom-type"];
|
|
61
|
-
if (!customTypeRegistry.validate(customType, data)) {
|
|
62
|
-
errors.push(`${path} does not match custom type '${customType}'`);
|
|
34
|
+
const result = {};
|
|
35
|
+
if (node.type === "attachment") {
|
|
36
|
+
return {
|
|
37
|
+
$ref: "#/$defs/attachment"
|
|
38
|
+
};
|
|
63
39
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (schema.type === "object" && schema.properties && typeof data === "object" && data !== null && !Array.isArray(data)) {
|
|
67
|
-
for (const [propKey, propSchema] of Object.entries(schema.properties)) {
|
|
68
|
-
if (Object.prototype.hasOwnProperty.call(data, propKey)) {
|
|
69
|
-
const propPath = path === "root" ? propKey : `${path}.${propKey}`;
|
|
70
|
-
errors.push(...validateCustomTypes(data[propKey], propSchema, propPath));
|
|
71
|
-
}
|
|
40
|
+
for (const key in node) {
|
|
41
|
+
result[key] = replaceAttachmentType(node[key]);
|
|
72
42
|
}
|
|
43
|
+
return result;
|
|
73
44
|
}
|
|
74
|
-
|
|
75
|
-
data.forEach((item, index) => {
|
|
76
|
-
const itemPath = `${path}[${index}]`;
|
|
77
|
-
errors.push(...validateCustomTypes(item, schema.items, itemPath));
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
return errors;
|
|
45
|
+
return replaceAttachmentType(schemaCopy);
|
|
81
46
|
}
|
|
82
|
-
const validateDataUsingSchema =
|
|
47
|
+
const validateDataUsingSchema = input => {
|
|
83
48
|
const {
|
|
84
49
|
data,
|
|
85
50
|
schema
|
|
86
51
|
} = input;
|
|
87
|
-
const processedSchema =
|
|
52
|
+
const processedSchema = injectAttachmentType(schema);
|
|
88
53
|
const validate = ajv.compile(processedSchema);
|
|
89
54
|
const valid = validate(data);
|
|
90
|
-
const errors = [];
|
|
91
55
|
if (!valid) {
|
|
92
56
|
var _validate$errors;
|
|
93
|
-
const
|
|
94
|
-
errors.push(...schemaErrors);
|
|
95
|
-
}
|
|
96
|
-
const customTypeErrors = validateCustomTypes(data, processedSchema);
|
|
97
|
-
errors.push(...customTypeErrors);
|
|
98
|
-
if (errors.length > 0) {
|
|
57
|
+
const errors = ((_validate$errors = validate.errors) === null || _validate$errors === void 0 ? void 0 : _validate$errors.map(err => `${err.instancePath || "root"} ${err.message}`)) || [];
|
|
99
58
|
const errorMessage = errors.join(", ") || "Unknown validation error";
|
|
100
59
|
throw new _types.ValidationError(`Data validation failed: ${errorMessage}`, data);
|
|
101
60
|
}
|