@intuned/browser-dev 2.2.3-unify-sdks.20
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/.babelrc +21 -0
- package/.eslintignore +10 -0
- package/.eslintrc.js +39 -0
- package/LICENSE +43 -0
- package/dist/ai-extractors/AnthropicClient/index.js +23 -0
- package/dist/ai-extractors/export.d.js +5 -0
- package/dist/ai-extractors/export.d.ts +422 -0
- package/dist/ai-extractors/extractStructuredData.js +79 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/constants.js +7 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/errors.js +42 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/extractStructuredDataUsingClaude.js +149 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/extractStructuredDataUsingGoogle.js +37 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/extractStructuredDataUsingOpenAi.js +144 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/extractStrucutredDataUsingAiInstance.js +123 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/index.js +55 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/isItemTableHeaderOrFooter.js +96 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/screenshotHelpers.js +55 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/types.js +5 -0
- package/dist/ai-extractors/extractionHelpers/extractStructuredDataUsingAi/utils.js +53 -0
- package/dist/ai-extractors/extractionHelpers/types.js +5 -0
- package/dist/ai-extractors/fileExtractors.js +176 -0
- package/dist/ai-extractors/index.js +31 -0
- package/dist/ai-extractors/jsonSchema.d.js +5 -0
- package/dist/ai-extractors/jsonSchema.d.ts +49 -0
- package/dist/ai-extractors/openAiClients/index.js +23 -0
- package/dist/ai-extractors/validators.js +239 -0
- package/dist/browser/ai/export.d.js +3 -0
- package/dist/browser/ai/export.d.ts +587 -0
- package/dist/browser/ai/extractMarkdown.js +15 -0
- package/dist/browser/ai/extractStructuredData.js +231 -0
- package/dist/browser/ai/extractStructuredDataUsingAi.js +140 -0
- package/dist/browser/ai/extractionHelpers/screenshotHelpers.js +55 -0
- package/dist/browser/ai/extractionHelpers/validateSchema.js +148 -0
- package/dist/browser/ai/index.d.ts +587 -0
- package/dist/browser/ai/index.js +19 -0
- package/dist/browser/ai/isPageLoaded.js +67 -0
- package/dist/browser/ai/prompt.js +39 -0
- package/dist/browser/ai/tests/testCheckAllTypesAreStrings.spec.js +143 -0
- package/dist/browser/ai/tests/testExtractStructuredData.spec.js +622 -0
- package/dist/browser/ai/tools/index.js +48 -0
- package/dist/browser/ai/types/errors.js +67 -0
- package/dist/browser/ai/types/models.js +45 -0
- package/dist/browser/ai/types/types.js +48 -0
- package/dist/browser/ai/validators.js +136 -0
- package/dist/common/Logger/index.js +60 -0
- package/dist/common/Logger/types.js +5 -0
- package/dist/common/SdkError.js +50 -0
- package/dist/common/aiModelsValidations.js +50 -0
- package/dist/common/browser_scripts.js +2596 -0
- package/dist/common/ensureBrowserScripts.js +17 -0
- package/dist/common/environmentVariables.js +16 -0
- package/dist/common/eventTracking/getAiTrackingHeaders.js +31 -0
- package/dist/common/eventTracking/getFileTrackingHeaders.js +23 -0
- package/dist/common/extendedTest.js +148 -0
- package/dist/common/extractionHelpers.js +19 -0
- package/dist/common/formatZodError.js +18 -0
- package/dist/common/fuzzySearch/fuzzySearch.test.js +250 -0
- package/dist/common/fuzzySearch/levenshtein-search.js +298 -0
- package/dist/common/fuzzySearch/utils.js +23 -0
- package/dist/common/getModelProvider.js +18 -0
- package/dist/common/getSimplifiedHtml.js +122 -0
- package/dist/common/hashObject.js +32 -0
- package/dist/common/html2markdown/convertElementToMarkdown.js +469 -0
- package/dist/common/html2markdown/index.js +19 -0
- package/dist/common/jwtTokenManager.js +18 -0
- package/dist/common/loadRuntime.js +16 -0
- package/dist/common/locatorHelpers.js +41 -0
- package/dist/common/matching/collectStrings.js +32 -0
- package/dist/common/matching/levenshtein.js +40 -0
- package/dist/common/matching/matching.js +317 -0
- package/dist/common/matching/types.js +1 -0
- package/dist/common/noEmpty.js +9 -0
- package/dist/common/saveSnapshotWithExamples.js +60 -0
- package/dist/common/tests/testEnsureBrowserScript.spec.js +31 -0
- package/dist/common/xpathMapping.js +107 -0
- package/dist/helpers/downloadFile.js +125 -0
- package/dist/helpers/export.d.js +1 -0
- package/dist/helpers/export.d.ts +1294 -0
- package/dist/helpers/extractMarkdown.js +35 -0
- package/dist/helpers/filterEmptyValues.js +54 -0
- package/dist/helpers/gotoUrl.js +93 -0
- package/dist/helpers/index.d.ts +1294 -0
- package/dist/helpers/index.js +115 -0
- package/dist/helpers/processDate.js +25 -0
- package/dist/helpers/resolveUrl.js +63 -0
- package/dist/helpers/sanitizeHtml.js +73 -0
- package/dist/helpers/saveFileToS3.js +46 -0
- package/dist/helpers/scrollToLoadContent.js +50 -0
- package/dist/helpers/tests/extendedTest.js +130 -0
- package/dist/helpers/tests/testDownloadFile.spec.js +197 -0
- package/dist/helpers/tests/testFilterEmptyValues.spec.js +151 -0
- package/dist/helpers/tests/testGoToUrl.spec.js +37 -0
- package/dist/helpers/tests/testIsPageLoaded.spec.js +285 -0
- package/dist/helpers/tests/testProcessDate.spec.js +13 -0
- package/dist/helpers/tests/testResolveUrl.spec.js +341 -0
- package/dist/helpers/tests/testSanitizeHtml.spec.js +330 -0
- package/dist/helpers/tests/testSimplifyHtml.spec.js +251 -0
- package/dist/helpers/tests/testValidateDataUsingSchema.spec.js +380 -0
- package/dist/helpers/tests/testWaitForDomSettled.spec.js +169 -0
- package/dist/helpers/tests/testWaitForNetworkIdle.spec.js +115 -0
- package/dist/helpers/types/Attachment.js +81 -0
- package/dist/helpers/types/CustomTypeRegistry.js +48 -0
- package/dist/helpers/types/RunEnvironment.js +18 -0
- package/dist/helpers/types/ValidationError.js +17 -0
- package/dist/helpers/types/index.js +51 -0
- package/dist/helpers/uploadFileToS3.js +153 -0
- package/dist/helpers/utils/getS3Client.js +21 -0
- package/dist/helpers/utils/index.js +73 -0
- package/dist/helpers/utils/isDownload.js +10 -0
- package/dist/helpers/utils/isGenerateCodeMode.js +9 -0
- package/dist/helpers/utils/isLocator.js +9 -0
- package/dist/helpers/utils/jwtTokenManager.js +18 -0
- package/dist/helpers/validateDataUsingSchema.js +119 -0
- package/dist/helpers/waitForDomSettled.js +182 -0
- package/dist/helpers/waitForNetworkIdle.js +191 -0
- package/dist/index.d.js +82 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +84 -0
- package/dist/intunedServices/ApiGateway/aiApiGateway.js +87 -0
- package/dist/intunedServices/ApiGateway/factory.js +13 -0
- package/dist/intunedServices/ApiGateway/providers/Anthropic.js +26 -0
- package/dist/intunedServices/ApiGateway/providers/Gemini.js +29 -0
- package/dist/intunedServices/ApiGateway/providers/OpenAI.js +29 -0
- package/dist/intunedServices/ApiGateway/tests/testApiGateway.spec.js +221 -0
- package/dist/intunedServices/ApiGateway/types.js +11 -0
- package/dist/intunedServices/cache/cache.js +61 -0
- package/dist/intunedServices/cache/index.js +12 -0
- package/dist/intunedServices/cache/tests/testCache.spec.js +117 -0
- package/dist/optimized-extractors/common/buildExamplesPrompt.js +12 -0
- package/dist/optimized-extractors/common/buildImagesFromPage.js +55 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingClaude.js +149 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingGoogle.js +37 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingOpenAi.js +145 -0
- package/dist/optimized-extractors/common/extractStrucutredDataUsingAiInstance.js +122 -0
- package/dist/optimized-extractors/common/findTableHeaders.js +175 -0
- package/dist/optimized-extractors/common/index.js +55 -0
- package/dist/optimized-extractors/common/isTableHeaderOrFooter.js +97 -0
- package/dist/optimized-extractors/common/matching/matching.js +212 -0
- package/dist/optimized-extractors/common/matching/matching.test.js +655 -0
- package/dist/optimized-extractors/common/matching/types.js +18 -0
- package/dist/optimized-extractors/common/matching/utils.js +184 -0
- package/dist/optimized-extractors/common/utils.js +58 -0
- package/dist/optimized-extractors/export.d.js +5 -0
- package/dist/optimized-extractors/export.d.ts +397 -0
- package/dist/optimized-extractors/extractArray.js +120 -0
- package/dist/optimized-extractors/extractObject.js +104 -0
- package/dist/optimized-extractors/index.d.ts +397 -0
- package/dist/optimized-extractors/index.js +31 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/dynamicListExtractor.spec.js +312 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/findSetOfXpathsToCreateAnArrayExtractor.test.js +22 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/getContainerElement.test.js +21 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/partOfSameArrayXpath.test.js +42 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/verifyThatAllXpathsArePartOfSameArray.test.js +9 -0
- package/dist/optimized-extractors/listExtractionHelpers/dynamicListExtractor.js +152 -0
- package/dist/optimized-extractors/listExtractionHelpers/errors.js +46 -0
- package/dist/optimized-extractors/listExtractionHelpers/getListMatches.js +14 -0
- package/dist/optimized-extractors/listExtractionHelpers/runAiExtraction.js +240 -0
- package/dist/optimized-extractors/listExtractionHelpers/typesAndSchema.js +5 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/extractPropertiesUsingGPTFromArray.js +277 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/extractStructuredListUsingAi.js +44 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getListContainerXpath.js +94 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getRelativeContainerXpathSelector.js +20 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getSimplifiedHtmlPerListItem.js +21 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/tablesUtils.js +48 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/validateOptions.js +52 -0
- package/dist/optimized-extractors/models/anthropicModel.js +23 -0
- package/dist/optimized-extractors/models/openaiModel.js +23 -0
- package/dist/optimized-extractors/objectExtractionHelpers/AIExtractors.js +73 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/checksumUtils.test.js +103 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/testObjectExtractorFromLocator.spec.js +107 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/testObjectExtractorFromPage.spec.js +107 -0
- package/dist/optimized-extractors/objectExtractionHelpers/calculateObjectExampleHash.js +28 -0
- package/dist/optimized-extractors/objectExtractionHelpers/captureSnapshot.js +26 -0
- package/dist/optimized-extractors/objectExtractionHelpers/checksumUtils.js +32 -0
- package/dist/optimized-extractors/objectExtractionHelpers/constants.js +7 -0
- package/dist/optimized-extractors/objectExtractionHelpers/dynamicObjectExtractor.js +106 -0
- package/dist/optimized-extractors/objectExtractionHelpers/errors.js +42 -0
- package/dist/optimized-extractors/objectExtractionHelpers/findDomMatches.js +54 -0
- package/dist/optimized-extractors/objectExtractionHelpers/getSimplifiedHtml.js +122 -0
- package/dist/optimized-extractors/objectExtractionHelpers/typesAndSchemas.js +5 -0
- package/dist/optimized-extractors/objectExtractionHelpers/validateDynamicObjectExtractorOptions.js +52 -0
- package/dist/optimized-extractors/types/aiModelsValidation.js +45 -0
- package/dist/optimized-extractors/types/errors.js +42 -0
- package/dist/optimized-extractors/types/jsonSchema.d.js +5 -0
- package/dist/optimized-extractors/types/jsonSchema.d.ts +50 -0
- package/dist/optimized-extractors/types/types.js +5 -0
- package/dist/optimized-extractors/validators.js +152 -0
- package/dist/vite-env.d.js +1 -0
- package/dist/vite-env.d.ts +9 -0
- package/docs.md +14 -0
- package/how-to-run-tests.md +10 -0
- package/intuned-runtime-setup.md +13 -0
- package/package.json +124 -0
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _extendedTest = require("./extendedTest");
|
|
4
|
+
var _ = require("..");
|
|
5
|
+
var _playwrightCore = require("playwright-core");
|
|
6
|
+
var _waitForDomSettled = require("../waitForDomSettled");
|
|
7
|
+
(0, _extendedTest.describe)("Test waitForDomSettled", () => {
|
|
8
|
+
let browser;
|
|
9
|
+
let page;
|
|
10
|
+
(0, _extendedTest.beforeAll)(async () => {
|
|
11
|
+
browser = await _playwrightCore.chromium.launch({
|
|
12
|
+
headless: false
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
(0, _extendedTest.afterAll)(async () => {
|
|
16
|
+
await browser.close();
|
|
17
|
+
});
|
|
18
|
+
(0, _extendedTest.beforeEach)(async () => {
|
|
19
|
+
page = await browser.newPage();
|
|
20
|
+
});
|
|
21
|
+
(0, _extendedTest.afterEach)(async () => {
|
|
22
|
+
await page.close();
|
|
23
|
+
});
|
|
24
|
+
(0, _extendedTest.test)("should wait for DOM to settle after navigation", async () => {
|
|
25
|
+
await page.goto("data:text/html,<html><body><div id='target'></div></body></html>");
|
|
26
|
+
await page.evaluate(() => {
|
|
27
|
+
const intervalId = setInterval(() => {
|
|
28
|
+
const target = document.getElementById("target");
|
|
29
|
+
const div = document.createElement("div");
|
|
30
|
+
div.textContent = String(Date.now());
|
|
31
|
+
target === null || target === void 0 || target.appendChild(div);
|
|
32
|
+
if (target && target.children.length > 10 && target.firstChild) {
|
|
33
|
+
target.removeChild(target.firstChild);
|
|
34
|
+
}
|
|
35
|
+
}, 100);
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
clearInterval(intervalId);
|
|
38
|
+
}, 5000);
|
|
39
|
+
});
|
|
40
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
41
|
+
source: page,
|
|
42
|
+
settleDuration: 1,
|
|
43
|
+
timeoutS: 10
|
|
44
|
+
});
|
|
45
|
+
(0, _extendedTest.expect)(settled).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
(0, _extendedTest.test)("should wait for specific element to settle while ignoring other mutations", async () => {
|
|
48
|
+
await page.goto(`
|
|
49
|
+
data:text/html,
|
|
50
|
+
<html>
|
|
51
|
+
<body>
|
|
52
|
+
<div id='watched-element'></div>
|
|
53
|
+
<div id='ignored-element'></div>
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
56
|
+
`);
|
|
57
|
+
await page.evaluate(() => {
|
|
58
|
+
const watchedElement = document.getElementById("watched-element");
|
|
59
|
+
const ignoredElement = document.getElementById("ignored-element");
|
|
60
|
+
const ignoredInterval = setInterval(() => {
|
|
61
|
+
const div = document.createElement("div");
|
|
62
|
+
div.textContent = `Ignored: ${Date.now()}`;
|
|
63
|
+
ignoredElement === null || ignoredElement === void 0 || ignoredElement.appendChild(div);
|
|
64
|
+
if (ignoredElement && ignoredElement.children.length > 5) {
|
|
65
|
+
ignoredElement.removeChild(ignoredElement.firstChild);
|
|
66
|
+
}
|
|
67
|
+
}, 50);
|
|
68
|
+
const watchedInterval = setInterval(() => {
|
|
69
|
+
const div = document.createElement("div");
|
|
70
|
+
div.textContent = `Watched: ${Date.now()}`;
|
|
71
|
+
watchedElement === null || watchedElement === void 0 || watchedElement.appendChild(div);
|
|
72
|
+
if (watchedElement && watchedElement.children.length > 3) {
|
|
73
|
+
watchedElement.removeChild(watchedElement.firstChild);
|
|
74
|
+
}
|
|
75
|
+
}, 200);
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
clearInterval(watchedInterval);
|
|
78
|
+
}, 3000);
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
clearInterval(ignoredInterval);
|
|
81
|
+
}, 15000);
|
|
82
|
+
});
|
|
83
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
84
|
+
source: page.locator("#watched-element"),
|
|
85
|
+
settleDuration: 3,
|
|
86
|
+
timeoutS: 10
|
|
87
|
+
});
|
|
88
|
+
(0, _extendedTest.expect)(settled).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
(0, _extendedTest.test)("should handle no mutations gracefully", async () => {
|
|
91
|
+
await page.goto("data:text/html,<html><body><div id='target'></div></body></html>");
|
|
92
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
93
|
+
source: page.locator("#target"),
|
|
94
|
+
settleDuration: 1,
|
|
95
|
+
timeoutS: 10
|
|
96
|
+
});
|
|
97
|
+
(0, _extendedTest.expect)(settled).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
(0, _extendedTest.test)("should wait for loading to be complete", async () => {
|
|
100
|
+
await (0, _.goToUrl)({
|
|
101
|
+
page,
|
|
102
|
+
url: "https://www.galvestoncountytx.gov/county-offices/purchasing/solicitations-bids",
|
|
103
|
+
waitForLoadingStateUsingAi: false
|
|
104
|
+
});
|
|
105
|
+
const settled = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
106
|
+
source: page,
|
|
107
|
+
settleDuration: 1,
|
|
108
|
+
timeoutS: 10
|
|
109
|
+
});
|
|
110
|
+
const loading = await page.getByText("Loading...").isVisible();
|
|
111
|
+
(0, _extendedTest.expect)(loading).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
(0, _extendedTest.test)("should work as a simple decorator", async () => {
|
|
114
|
+
await page.goto("data:text/html,<html><body><div id='target'></div></body></html>");
|
|
115
|
+
const decoratedFunction = (0, _waitForDomSettled.waitForDomSettled)(async page => {
|
|
116
|
+
await page.evaluate(() => {
|
|
117
|
+
const target = document.getElementById("target");
|
|
118
|
+
const div = document.createElement("div");
|
|
119
|
+
div.textContent = "Added content";
|
|
120
|
+
target === null || target === void 0 || target.appendChild(div);
|
|
121
|
+
});
|
|
122
|
+
return "function executed";
|
|
123
|
+
});
|
|
124
|
+
const result = await decoratedFunction(page);
|
|
125
|
+
(0, _extendedTest.expect)(result).toBe("function executed");
|
|
126
|
+
const content = await page.textContent("#target");
|
|
127
|
+
(0, _extendedTest.expect)(content).toContain("Added content");
|
|
128
|
+
});
|
|
129
|
+
(0, _extendedTest.test)("should work as a parameterized decorator", async () => {
|
|
130
|
+
await page.goto("data:text/html,<html><body><div id='target'></div></body></html>");
|
|
131
|
+
const decoratedFunction = (0, _waitForDomSettled.waitForDomSettled)({
|
|
132
|
+
settleDuration: 2,
|
|
133
|
+
timeoutS: 30
|
|
134
|
+
})(async page => {
|
|
135
|
+
await page.evaluate(() => {
|
|
136
|
+
const target = document.getElementById("target");
|
|
137
|
+
const div = document.createElement("div");
|
|
138
|
+
div.textContent = "Parameterized decorator content";
|
|
139
|
+
target === null || target === void 0 || target.appendChild(div);
|
|
140
|
+
});
|
|
141
|
+
return "parameterized function executed";
|
|
142
|
+
});
|
|
143
|
+
const result = await decoratedFunction(page);
|
|
144
|
+
(0, _extendedTest.expect)(result).toBe("parameterized function executed");
|
|
145
|
+
const content = await page.textContent("#target");
|
|
146
|
+
(0, _extendedTest.expect)(content).toContain("Parameterized decorator content");
|
|
147
|
+
});
|
|
148
|
+
(0, _extendedTest.test)("should work with direct function call", async () => {
|
|
149
|
+
await page.goto("data:text/html,<html><body><div id='target'></div></body></html>");
|
|
150
|
+
const testFunction = async () => {
|
|
151
|
+
await page.evaluate(() => {
|
|
152
|
+
const target = document.getElementById("target");
|
|
153
|
+
const div = document.createElement("div");
|
|
154
|
+
div.textContent = "Direct call content";
|
|
155
|
+
target === null || target === void 0 || target.appendChild(div);
|
|
156
|
+
});
|
|
157
|
+
return "direct call executed";
|
|
158
|
+
};
|
|
159
|
+
const result = await (0, _waitForDomSettled.waitForDomSettled)({
|
|
160
|
+
source: page,
|
|
161
|
+
func: testFunction,
|
|
162
|
+
settleDuration: 1,
|
|
163
|
+
timeoutS: 30
|
|
164
|
+
});
|
|
165
|
+
(0, _extendedTest.expect)(result).toBe("direct call executed");
|
|
166
|
+
const content = await page.textContent("#target");
|
|
167
|
+
(0, _extendedTest.expect)(content).toContain("Direct call content");
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _extendedTest = require("./extendedTest");
|
|
4
|
+
var _playwright = require("playwright");
|
|
5
|
+
var _ = require("..");
|
|
6
|
+
(0, _extendedTest.describe)("TestWaitForNetworkIdle", () => {
|
|
7
|
+
let browser;
|
|
8
|
+
let page;
|
|
9
|
+
(0, _extendedTest.beforeEach)(async () => {
|
|
10
|
+
browser = await _playwright.chromium.launch({
|
|
11
|
+
headless: false
|
|
12
|
+
});
|
|
13
|
+
page = await browser.newPage();
|
|
14
|
+
});
|
|
15
|
+
(0, _extendedTest.afterEach)(async () => {
|
|
16
|
+
await browser.close();
|
|
17
|
+
});
|
|
18
|
+
(0, _extendedTest.test)("wait for network idle click element 1", async () => {
|
|
19
|
+
const clickElement = (0, _.waitForNetworkIdle)({
|
|
20
|
+
timeoutInMs: 10000
|
|
21
|
+
})(async (page, selector, timeoutInMs = 10000) => {
|
|
22
|
+
await page.locator(selector).first().click({
|
|
23
|
+
timeout: timeoutInMs
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
await page.goto("https://www.txsmartbuy.gov/esbd?");
|
|
27
|
+
await page.waitForTimeout(10000);
|
|
28
|
+
await clickElement(page, "xpath=(//*[@id='Next'])[1]", 10000);
|
|
29
|
+
const currentPage = await page.locator("[aria-label='Current Page']").first().textContent();
|
|
30
|
+
(0, _extendedTest.expect)(currentPage).toBe("2");
|
|
31
|
+
});
|
|
32
|
+
(0, _extendedTest.test)("wait for network idle click element 2", async () => {
|
|
33
|
+
const clickElement = (0, _.waitForNetworkIdle)({
|
|
34
|
+
timeoutInMs: 10000
|
|
35
|
+
})(async (page, selector, timeoutInMs = 10000) => {
|
|
36
|
+
await page.locator(selector).first().click({
|
|
37
|
+
timeout: timeoutInMs
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
await page.goto("https://www.biddingo.com/soundtransit", {
|
|
41
|
+
timeout: 0
|
|
42
|
+
});
|
|
43
|
+
await page.waitForTimeout(3000);
|
|
44
|
+
await clickElement(page, "[aria-label='Next page']", 10000);
|
|
45
|
+
const currentPage = await page.locator(".mat-paginator-range-label").first().textContent();
|
|
46
|
+
(0, _extendedTest.expect)(currentPage).toContain("11");
|
|
47
|
+
});
|
|
48
|
+
(0, _extendedTest.test)("wait for network idle press key combination", async () => {
|
|
49
|
+
const pressKeyCombination = (0, _.waitForNetworkIdle)({
|
|
50
|
+
timeoutInMs: 10000
|
|
51
|
+
})(async (page, keyCombination, timeoutInMs = 10000) => {
|
|
52
|
+
await page.keyboard.press(keyCombination);
|
|
53
|
+
});
|
|
54
|
+
await page.goto("https://www.txsmartbuy.gov/esbd?&page=3");
|
|
55
|
+
await page.waitForTimeout(10000);
|
|
56
|
+
await page.click("input[name='agencyNumber']");
|
|
57
|
+
await pressKeyCombination(page, "Enter", 10000);
|
|
58
|
+
const currentPage = await page.locator("[aria-label='Current Page']").first().textContent();
|
|
59
|
+
(0, _extendedTest.expect)(currentPage).toBe("1");
|
|
60
|
+
});
|
|
61
|
+
(0, _extendedTest.test)("wait for network idle enter text and click", async () => {
|
|
62
|
+
const enterTextAndClick = (0, _.waitForNetworkIdle)({
|
|
63
|
+
timeoutInMs: 10000
|
|
64
|
+
})(async (page, textSelector, clickSelector, text, timeoutInMs = 10000) => {
|
|
65
|
+
await page.fill(textSelector, text);
|
|
66
|
+
await page.click(clickSelector);
|
|
67
|
+
});
|
|
68
|
+
await page.goto("https://www.txsmartbuy.gov/esbd?&page=3", {
|
|
69
|
+
timeout: 20000
|
|
70
|
+
});
|
|
71
|
+
await page.waitForTimeout(10000);
|
|
72
|
+
await enterTextAndClick(page, "input[name='agencyNumber']", "#content > div > div > form > div.browse-contract-search-actions [type='submit']", "123456", 10000);
|
|
73
|
+
await page.getByText("No results found", {
|
|
74
|
+
exact: false
|
|
75
|
+
}).first().textContent();
|
|
76
|
+
});
|
|
77
|
+
(0, _extendedTest.test)("wait for click element 3", async () => {
|
|
78
|
+
const clickElement = (0, _.waitForNetworkIdle)({
|
|
79
|
+
timeoutInMs: 20000
|
|
80
|
+
})(async (page, selector, timeoutInMs = 10000) => {
|
|
81
|
+
await page.locator(selector).first().click({
|
|
82
|
+
timeout: timeoutInMs
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
await page.goto("https://www.commbuys.com/bso/view/search/external/advancedSearchBid.xhtml");
|
|
86
|
+
await page.waitForTimeout(4000);
|
|
87
|
+
await clickElement(page, "#bidSearchForm\\:btnBidSearch", 10000);
|
|
88
|
+
(0, _extendedTest.expect)(await page.locator("[aria-label='Page 1']").first().isVisible()).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
(0, _extendedTest.test)("simple decorator usage", async () => {
|
|
91
|
+
const decoratedFunction = (0, _.waitForNetworkIdle)(async page => {
|
|
92
|
+
await page.goto("data:text/html,<html><body><h1>Test</h1></body></html>");
|
|
93
|
+
return "navigation complete";
|
|
94
|
+
});
|
|
95
|
+
const result = await decoratedFunction(page);
|
|
96
|
+
(0, _extendedTest.expect)(result).toBe("navigation complete");
|
|
97
|
+
const title = await page.textContent("h1");
|
|
98
|
+
(0, _extendedTest.expect)(title).toBe("Test");
|
|
99
|
+
});
|
|
100
|
+
(0, _extendedTest.test)("direct call with page and function", async () => {
|
|
101
|
+
const testFunction = async () => {
|
|
102
|
+
await page.goto("data:text/html,<html><body><h1>Direct Call</h1></body></html>");
|
|
103
|
+
return "direct call complete";
|
|
104
|
+
};
|
|
105
|
+
const result = await (0, _.waitForNetworkIdle)({
|
|
106
|
+
page: page,
|
|
107
|
+
func: testFunction,
|
|
108
|
+
timeoutInMs: 10000,
|
|
109
|
+
maxInflightRequests: 0
|
|
110
|
+
});
|
|
111
|
+
(0, _extendedTest.expect)(result).toBe("direct call complete");
|
|
112
|
+
const title = await page.textContent("h1");
|
|
113
|
+
(0, _extendedTest.expect)(title).toBe("Direct Call");
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SignedUrlAttachment = exports.Attachment = void 0;
|
|
7
|
+
var _clientS = require("@aws-sdk/client-s3");
|
|
8
|
+
var _s3RequestPresigner = require("@aws-sdk/s3-request-presigner");
|
|
9
|
+
var _utils = require("../utils");
|
|
10
|
+
var _getS3Client = require("../utils/getS3Client");
|
|
11
|
+
class Attachment {
|
|
12
|
+
constructor(fileName, bucket, region, suggestedFileName, endpoint, fileType) {
|
|
13
|
+
this.fileName = fileName;
|
|
14
|
+
this.bucket = bucket;
|
|
15
|
+
this.region = region;
|
|
16
|
+
this.suggestedFileName = suggestedFileName;
|
|
17
|
+
this.endpoint = endpoint;
|
|
18
|
+
this.fileType = fileType;
|
|
19
|
+
}
|
|
20
|
+
toJSON() {
|
|
21
|
+
return this.toDict();
|
|
22
|
+
}
|
|
23
|
+
toDict() {
|
|
24
|
+
return {
|
|
25
|
+
fileName: this.fileName,
|
|
26
|
+
bucket: this.bucket,
|
|
27
|
+
region: this.region,
|
|
28
|
+
suggestedFileName: this.suggestedFileName,
|
|
29
|
+
...(this.endpoint ? {
|
|
30
|
+
endpoint: this.endpoint
|
|
31
|
+
} : {}),
|
|
32
|
+
...(this.fileType ? {
|
|
33
|
+
fileType: this.fileType
|
|
34
|
+
} : {})
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
static fromDict(data) {
|
|
38
|
+
return new Attachment(data.fileName, data.bucket, data.region, data.suggestedFileName, data.endpoint, data.fileType);
|
|
39
|
+
}
|
|
40
|
+
async getSignedUrl(expiration = 3600 * 24 * 5) {
|
|
41
|
+
if ((0, _utils.isGenerateCodeMode)()) {
|
|
42
|
+
return "https://not.real.com";
|
|
43
|
+
}
|
|
44
|
+
const s3Client = (0, _getS3Client.getS3Client)(this.endpoint);
|
|
45
|
+
try {
|
|
46
|
+
const response = await (0, _s3RequestPresigner.getSignedUrl)(s3Client, new _clientS.GetObjectCommand({
|
|
47
|
+
Bucket: this.bucket,
|
|
48
|
+
Key: this.fileName
|
|
49
|
+
}), {
|
|
50
|
+
expiresIn: expiration
|
|
51
|
+
});
|
|
52
|
+
return response;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.log(error);
|
|
55
|
+
throw new Error("Error generating signed URL");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
getS3Key() {
|
|
59
|
+
return `https://${this.bucket}.s3.${this.region}.amazonaws.com/${this.fileName}`;
|
|
60
|
+
}
|
|
61
|
+
getFilePath() {
|
|
62
|
+
return this.fileName;
|
|
63
|
+
}
|
|
64
|
+
getFileType() {
|
|
65
|
+
return this.fileType || "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.Attachment = Attachment;
|
|
69
|
+
class SignedUrlAttachment extends Attachment {
|
|
70
|
+
constructor(fileName, downloadSignedUrl, suggestedFileName) {
|
|
71
|
+
const url = new URL(downloadSignedUrl);
|
|
72
|
+
const bucket = url.hostname.split(".")[0];
|
|
73
|
+
const key = url.pathname.substring(1);
|
|
74
|
+
super(key, bucket, "", suggestedFileName ?? fileName);
|
|
75
|
+
this.downloadSignedUrl = downloadSignedUrl;
|
|
76
|
+
}
|
|
77
|
+
async getSignedUrl() {
|
|
78
|
+
return this.downloadSignedUrl;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.SignedUrlAttachment = SignedUrlAttachment;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.CustomTypeRegistry = exports.AttachmentValidator = void 0;
|
|
7
|
+
class AttachmentValidator {
|
|
8
|
+
validate(data) {
|
|
9
|
+
if (!data || typeof data !== "object") {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const requiredFields = ["fileName", "bucket", "region", "suggestedFileName"];
|
|
13
|
+
return requiredFields.every(field => field in data && typeof data[field] === "string" && data[field].length > 0);
|
|
14
|
+
}
|
|
15
|
+
getName() {
|
|
16
|
+
return "attachment";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.AttachmentValidator = AttachmentValidator;
|
|
20
|
+
class CustomTypeRegistry {
|
|
21
|
+
registry = new Map();
|
|
22
|
+
constructor(registerIntunedTypes = true) {
|
|
23
|
+
if (registerIntunedTypes) {
|
|
24
|
+
this.registerIntunedTypes();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
registerIntunedTypes() {
|
|
28
|
+
this.register(new AttachmentValidator());
|
|
29
|
+
}
|
|
30
|
+
register(validator) {
|
|
31
|
+
const typeName = validator.getName().toLowerCase();
|
|
32
|
+
this.registry.set(typeName, validator);
|
|
33
|
+
}
|
|
34
|
+
get(typeName) {
|
|
35
|
+
return this.registry.get(typeName.toLowerCase());
|
|
36
|
+
}
|
|
37
|
+
isCustomType(typeName) {
|
|
38
|
+
return this.registry.has(typeName.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
validate(typeName, data) {
|
|
41
|
+
const validator = this.get(typeName);
|
|
42
|
+
return validator ? validator.validate(data) : false;
|
|
43
|
+
}
|
|
44
|
+
getAllTypes() {
|
|
45
|
+
return Array.from(this.registry.keys());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.CustomTypeRegistry = CustomTypeRegistry;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.RunType = exports.RunEnvironment = void 0;
|
|
7
|
+
let RunEnvironment = exports.RunEnvironment = function (RunEnvironment) {
|
|
8
|
+
RunEnvironment["IDE"] = "IDE";
|
|
9
|
+
RunEnvironment["DEPLOYED"] = "DEPLOYED";
|
|
10
|
+
return RunEnvironment;
|
|
11
|
+
}({});
|
|
12
|
+
let RunType = exports.RunType = function (RunType) {
|
|
13
|
+
RunType["SYNC"] = "SYNC";
|
|
14
|
+
RunType["ASYNC"] = "ASYNC";
|
|
15
|
+
RunType["JOB"] = "JOB";
|
|
16
|
+
RunType["QUEUE"] = "QUEUE";
|
|
17
|
+
return RunType;
|
|
18
|
+
}({});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ValidationError = void 0;
|
|
7
|
+
class ValidationError extends Error {
|
|
8
|
+
constructor(message, data) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ValidationError";
|
|
11
|
+
this.data = data;
|
|
12
|
+
if (Error.captureStackTrace) {
|
|
13
|
+
Error.captureStackTrace(this, ValidationError);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ValidationError = ValidationError;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "Attachment", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _Attachment.Attachment;
|
|
10
|
+
}
|
|
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
|
+
Object.defineProperty(exports, "RunEnvironment", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _RunEnvironment.RunEnvironment;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "RunType", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _RunEnvironment.RunType;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "ValidationError", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _ValidationError.ValidationError;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
var _ValidationError = require("./ValidationError");
|
|
49
|
+
var _RunEnvironment = require("./RunEnvironment");
|
|
50
|
+
var _Attachment = require("./Attachment");
|
|
51
|
+
var _CustomTypeRegistry = require("./CustomTypeRegistry");
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.uploadFileToS3 = void 0;
|
|
7
|
+
var _fsExtra = require("fs-extra");
|
|
8
|
+
var _clientS = require("@aws-sdk/client-s3");
|
|
9
|
+
var _Attachment = require("../helpers/types/Attachment");
|
|
10
|
+
var _uuid = require("uuid");
|
|
11
|
+
var _utils = require("./utils");
|
|
12
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
13
|
+
var _jwtTokenManager = require("../common/jwtTokenManager");
|
|
14
|
+
var _zod = _interopRequireDefault(require("zod"));
|
|
15
|
+
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
|
+
function sanitizeKey(key) {
|
|
18
|
+
let result = key.replace(/[^a-zA-Z0-9.\-_/]/g, "_");
|
|
19
|
+
result = result.replace(/_{2,}/g, "_");
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
const stringToJSONSchema = _zod.default.string().transform((str, ctx) => {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(str);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
ctx.addIssue({
|
|
27
|
+
code: "custom",
|
|
28
|
+
message: "Invalid JSON"
|
|
29
|
+
});
|
|
30
|
+
return _zod.default.NEVER;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const getUploadSignedUrlResponseSchema = stringToJSONSchema.pipe(_zod.default.object({
|
|
34
|
+
id: _zod.default.string().uuid(),
|
|
35
|
+
writeSignedUrl: _zod.default.string().url(),
|
|
36
|
+
readSignedUrl: _zod.default.string().url()
|
|
37
|
+
}));
|
|
38
|
+
const uploadFileToS3 = async input => {
|
|
39
|
+
var _configs$s3Configs, _configs$s3Configs2, _configs$s3Configs3, _configs$s3Configs4, _configs$s3Configs5;
|
|
40
|
+
const {
|
|
41
|
+
file,
|
|
42
|
+
configs
|
|
43
|
+
} = input;
|
|
44
|
+
const bucketName = (configs === null || configs === void 0 || (_configs$s3Configs = configs.s3Configs) === null || _configs$s3Configs === void 0 ? void 0 : _configs$s3Configs.bucket) ?? process.env.S3_BUCKET ?? process.env.INTUNED_S3_BUCKET ?? undefined;
|
|
45
|
+
const region = (configs === null || configs === void 0 || (_configs$s3Configs2 = configs.s3Configs) === null || _configs$s3Configs2 === void 0 ? void 0 : _configs$s3Configs2.region) ?? process.env.S3_REGION ?? process.env.INTUNED_S3_REGION ?? undefined;
|
|
46
|
+
const endpoint = (configs === null || configs === void 0 || (_configs$s3Configs3 = configs.s3Configs) === null || _configs$s3Configs3 === void 0 ? void 0 : _configs$s3Configs3.endpoint) ?? process.env.S3_ENDPOINT_URL ?? process.env.INTUNED_S3_ENDPOINT_URL;
|
|
47
|
+
const accessKeyId = (configs === null || configs === void 0 || (_configs$s3Configs4 = configs.s3Configs) === null || _configs$s3Configs4 === void 0 ? void 0 : _configs$s3Configs4.accessKeyId) ?? process.env.S3_ACCESS_KEY_ID ?? process.env.INTUNED_S3_ACCESS_KEY_ID;
|
|
48
|
+
const secretAccessKey = (configs === null || configs === void 0 || (_configs$s3Configs5 = configs.s3Configs) === null || _configs$s3Configs5 === void 0 ? void 0 : _configs$s3Configs5.secretAccessKey) ?? process.env.S3_SECRET_ACCESS_KEY ?? process.env.INTUNED_S3_SECRET_ACCESS_KEY;
|
|
49
|
+
const isDownloadedFile = (0, _utils.isDownload)(file);
|
|
50
|
+
if ((0, _utils.isGenerateCodeMode)()) {
|
|
51
|
+
console.log("Uploaded file successfully");
|
|
52
|
+
if (isDownloadedFile) {
|
|
53
|
+
return new _Attachment.Attachment(`${(0, _uuid.v4)()}/${file.suggestedFilename()}`, "testing_bucket", "testing_region", file.suggestedFilename() || "downloaded_file", endpoint);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let suggestedFileName;
|
|
57
|
+
if (isDownloadedFile) {
|
|
58
|
+
suggestedFileName = file.suggestedFilename();
|
|
59
|
+
}
|
|
60
|
+
console.log(`suggested_file_name ${suggestedFileName}`);
|
|
61
|
+
const fileName = (configs === null || configs === void 0 ? void 0 : configs.fileNameOverride) ?? suggestedFileName ?? (0, _uuid.v4)();
|
|
62
|
+
const fileBody = await getFileBody(file);
|
|
63
|
+
if (!region || !bucketName) {
|
|
64
|
+
return await uploadToIntuned({
|
|
65
|
+
name: fileName,
|
|
66
|
+
suggestedName: suggestedFileName || fileName,
|
|
67
|
+
body: fileBody
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (isDownloadedFile && !(0, _utils.isGenerateCodeMode)() && !(await file.path())) {
|
|
71
|
+
throw new Error("File path not found");
|
|
72
|
+
}
|
|
73
|
+
let credentials = undefined;
|
|
74
|
+
if (accessKeyId && secretAccessKey) {
|
|
75
|
+
credentials = {
|
|
76
|
+
accessKeyId,
|
|
77
|
+
secretAccessKey
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const s3Client = new _clientS.S3Client({
|
|
81
|
+
region,
|
|
82
|
+
endpoint,
|
|
83
|
+
credentials
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
const cleanedFileName = sanitizeKey(fileName);
|
|
87
|
+
const key = `${(0, _uuid.v4)()}/${cleanedFileName}`;
|
|
88
|
+
const command = new _clientS.PutObjectCommand({
|
|
89
|
+
Bucket: bucketName,
|
|
90
|
+
Key: key,
|
|
91
|
+
Body: fileBody
|
|
92
|
+
});
|
|
93
|
+
const response = await s3Client.send(command);
|
|
94
|
+
if (response.$metadata.httpStatusCode === 200) {
|
|
95
|
+
return new _Attachment.Attachment(key, bucketName, region, suggestedFileName || fileName, endpoint);
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error("Error uploading file");
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error instanceof Error && error.message.includes("Credentials")) {
|
|
101
|
+
throw new Error("Credentials not available");
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Error uploading file: ${error instanceof Error ? error.message : String(error)}`);
|
|
104
|
+
} finally {
|
|
105
|
+
if (isDownloadedFile) {
|
|
106
|
+
var _file$delete;
|
|
107
|
+
await ((_file$delete = file.delete) === null || _file$delete === void 0 ? void 0 : _file$delete.call(file));
|
|
108
|
+
}
|
|
109
|
+
if (typeof file === "string") {
|
|
110
|
+
try {
|
|
111
|
+
_fs.default.unlinkSync(file);
|
|
112
|
+
} catch (e) {}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.uploadFileToS3 = uploadFileToS3;
|
|
117
|
+
async function getFileBody(file) {
|
|
118
|
+
if ((0, _utils.isDownload)(file)) {
|
|
119
|
+
const filePath = await file.path();
|
|
120
|
+
if (!filePath) {
|
|
121
|
+
throw new Error("Downloaded file path not found");
|
|
122
|
+
}
|
|
123
|
+
return (0, _fsExtra.readFile)(filePath);
|
|
124
|
+
} else if (Buffer.isBuffer(file)) {
|
|
125
|
+
return file;
|
|
126
|
+
} else {
|
|
127
|
+
throw new Error("Invalid file type");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function uploadToIntuned({
|
|
131
|
+
name,
|
|
132
|
+
suggestedName,
|
|
133
|
+
body
|
|
134
|
+
}) {
|
|
135
|
+
const uploadInfoResponse = await (0, _jwtTokenManager.callBackendFunctionWithToken)("files/uploadSignedUrls");
|
|
136
|
+
if (!uploadInfoResponse.ok) {
|
|
137
|
+
throw new Error(`Failed to get upload signed URL: ${uploadInfoResponse.statusText}`);
|
|
138
|
+
}
|
|
139
|
+
const uploadInfoText = await uploadInfoResponse.text();
|
|
140
|
+
const uploadInfo = getUploadSignedUrlResponseSchema.parse(uploadInfoText);
|
|
141
|
+
const uploadResponse = await (0, _nodeFetch.default)(uploadInfo.writeSignedUrl, {
|
|
142
|
+
method: "PUT",
|
|
143
|
+
body: await getFileBody(body),
|
|
144
|
+
headers: {
|
|
145
|
+
"Content-Type": "application/octet-stream"
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
const uploadResponseText = await uploadResponse.text();
|
|
149
|
+
if (!uploadResponse.ok) {
|
|
150
|
+
throw new Error(`Failed to upload file: ${uploadResponse.status} - ${uploadResponseText}`);
|
|
151
|
+
}
|
|
152
|
+
return new _Attachment.SignedUrlAttachment(name, uploadInfo.readSignedUrl, suggestedName);
|
|
153
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getS3Client = getS3Client;
|
|
7
|
+
var _clientS = require("@aws-sdk/client-s3");
|
|
8
|
+
let s3ClientInstance = null;
|
|
9
|
+
function getS3Client(endpoint) {
|
|
10
|
+
if (!s3ClientInstance) {
|
|
11
|
+
s3ClientInstance = new _clientS.S3Client({
|
|
12
|
+
region: process.env.S3_REGION,
|
|
13
|
+
credentials: {
|
|
14
|
+
accessKeyId: process.env.S3_ACCESS_KEY_ID || "",
|
|
15
|
+
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || ""
|
|
16
|
+
},
|
|
17
|
+
endpoint: endpoint || undefined
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return s3ClientInstance;
|
|
21
|
+
}
|