ag-common 0.0.892 → 0.0.894
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/dist/api/helpers/acm.js +7 -17
- package/dist/api/helpers/api.js +28 -23
- package/dist/api/helpers/apigw.js +54 -71
- package/dist/api/helpers/cosmos/delete.js +81 -94
- package/dist/api/helpers/cosmos/get.js +170 -195
- package/dist/api/helpers/cosmos/index.js +23 -53
- package/dist/api/helpers/cosmos/write.js +88 -92
- package/dist/api/helpers/dynamo/delete.js +22 -52
- package/dist/api/helpers/dynamo/get.js +145 -135
- package/dist/api/helpers/dynamo/set.js +22 -29
- package/dist/api/helpers/enforceDynamoProvisionCap.js +5 -5
- package/dist/api/helpers/google/apikey.js +1 -2
- package/dist/api/helpers/google/gemini.js +26 -37
- package/dist/api/helpers/retryOnError.js +15 -26
- package/dist/api/helpers/s3.js +102 -121
- package/dist/api/helpers/ses.js +19 -26
- package/dist/api/helpers/sqs.js +5 -15
- package/dist/api/helpers/ssmInfra/dynamo.js +9 -5
- package/dist/api/helpers/sts.js +26 -37
- package/dist/api/helpers/validations.js +7 -17
- package/dist/api/helpers/zod.js +1 -2
- package/dist/common/helpers/async.js +27 -42
- package/dist/common/helpers/csv.js +1 -4
- package/dist/common/helpers/date.js +2 -2
- package/dist/common/helpers/fetch.js +42 -55
- package/dist/common/helpers/generator.js +11 -22
- package/dist/common/helpers/i18n.js +3 -5
- package/dist/common/helpers/log.js +4 -4
- package/dist/common/helpers/math.js +1 -2
- package/dist/common/helpers/node-cache.js +10 -2
- package/dist/common/helpers/random.js +2 -2
- package/dist/common/helpers/secondsInNearest.js +1 -2
- package/dist/common/helpers/stream.js +24 -35
- package/dist/common/helpers/string/redact.js +1 -2
- package/dist/common/helpers/withRetry.js +5 -14
- package/dist/common/helpers/xml.js +9 -22
- package/dist/node/helpers/fetch.js +22 -33
- package/dist/ui/components/DarkMode/Base.js +10 -5
- package/dist/ui/components/Markdown/index.js +4 -5
- package/dist/ui/components/shadcn/accordion.js +13 -36
- package/dist/ui/components/shadcn/alert.d.ts +1 -1
- package/dist/ui/components/shadcn/alert.js +3 -23
- package/dist/ui/components/shadcn/avatar.js +4 -24
- package/dist/ui/components/shadcn/button.d.ts +1 -1
- package/dist/ui/components/shadcn/button.js +2 -14
- package/dist/ui/components/shadcn/card.js +6 -35
- package/dist/ui/components/shadcn/checkbox.js +4 -18
- package/dist/ui/components/shadcn/dialog.js +17 -46
- package/dist/ui/components/shadcn/dropdown-list.js +2 -2
- package/dist/ui/components/shadcn/dropdown-menu.js +22 -58
- package/dist/ui/components/shadcn/input-selector.js +4 -5
- package/dist/ui/components/shadcn/input.js +2 -14
- package/dist/ui/components/shadcn/label.d.ts +1 -1
- package/dist/ui/components/shadcn/label.js +2 -16
- package/dist/ui/components/shadcn/popover.js +3 -17
- package/dist/ui/components/shadcn/radio-group.js +4 -17
- package/dist/ui/components/shadcn/scroll-area.js +9 -26
- package/dist/ui/components/shadcn/select.js +23 -55
- package/dist/ui/components/shadcn/sheet.d.ts +1 -1
- package/dist/ui/components/shadcn/sheet.js +13 -42
- package/dist/ui/components/shadcn/switch.js +3 -17
- package/dist/ui/components/shadcn/textarea.js +2 -14
- package/dist/ui/components/shadcn/toast.js +6 -4
- package/dist/ui/helpers/cookie/get.js +5 -1
- package/dist/ui/helpers/cookie/raw.js +1 -2
- package/dist/ui/helpers/cookie/set.js +2 -2
- package/dist/ui/helpers/cookie/use.js +19 -9
- package/dist/ui/helpers/date.js +3 -4
- package/dist/ui/helpers/debounce.js +1 -1
- package/dist/ui/helpers/extractAttributes.js +1 -2
- package/dist/ui/helpers/openDialog.js +1 -2
- package/dist/ui/helpers/routes.js +6 -4
- package/dist/ui/helpers/serviceWorker.js +7 -18
- package/dist/ui/helpers/useContextMenu.js +2 -3
- package/dist/ui/helpers/useElementAttribute.js +1 -1
- package/dist/ui/helpers/useGranularHook.js +2 -2
- package/dist/ui/helpers/useInterval.js +5 -7
- package/dist/ui/helpers/useLocalStorage.js +1 -1
- package/dist/ui/helpers/useOnClickOutside.js +2 -3
- package/dist/ui/helpers/useOnScroll.js +6 -8
- package/dist/ui/helpers/useOverloadPageSearch.js +1 -1
- package/dist/ui/helpers/useQueryString.js +2 -2
- package/dist/ui/helpers/useResize.js +1 -1
- package/dist/ui/helpers/useTimeout.js +1 -1
- package/dist/ui/helpers/useTooltip.js +8 -5
- package/dist/ui/icons/Checkmark.js +2 -5
- package/dist/ui/icons/Circle.js +2 -5
- package/dist/ui/icons/Magnify.js +2 -5
- package/dist/ui/icons/Sun.js +8 -11
- package/dist/ui/icons/Warning.js +7 -10
- package/dist/ui/styles/common.js +8 -20
- package/package.json +66 -65
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.resolveGroundedUrl = exports.geminiPromptDirect = exports.geminiPromptImage = void 0;
|
|
13
4
|
const genai_1 = require("@google/genai");
|
|
@@ -59,28 +50,27 @@ const sortModelsByPreference = (models, prefer) => {
|
|
|
59
50
|
return modelArray;
|
|
60
51
|
};
|
|
61
52
|
const normalizeModelName = (name) => name.replace(/^models\//, '');
|
|
62
|
-
const getAvailableGeminiModels = () =>
|
|
63
|
-
var _a, _b;
|
|
53
|
+
const getAvailableGeminiModels = async () => {
|
|
64
54
|
const cachedModels = geminiModelsCache.get(geminiModelsCacheKey);
|
|
65
55
|
if (cachedModels && cachedModels.length > 0) {
|
|
66
56
|
return cachedModels;
|
|
67
57
|
}
|
|
68
58
|
const keyServiceCombinations = (0, apikey_1.getAvailableCombinations)('gemini');
|
|
69
|
-
const key =
|
|
59
|
+
const key = keyServiceCombinations[0]?.key;
|
|
70
60
|
if (!key) {
|
|
71
61
|
(0, log_1.warn)('No GOOGLE_API_KEY available. Falling back to default Gemini models.');
|
|
72
62
|
return [...FALLBACK_GEMINI_MODELS];
|
|
73
63
|
}
|
|
74
64
|
try {
|
|
75
|
-
const response =
|
|
65
|
+
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(key)}`);
|
|
76
66
|
if (!response.ok) {
|
|
77
67
|
throw new Error(`model list fetch failed with status ${response.status}`);
|
|
78
68
|
}
|
|
79
|
-
const payload = (
|
|
69
|
+
const payload = (await response.json());
|
|
80
70
|
const discoveredModels = [
|
|
81
|
-
...new Set((
|
|
82
|
-
.filter((m) =>
|
|
83
|
-
.map((m) =>
|
|
71
|
+
...new Set((payload.models ?? [])
|
|
72
|
+
.filter((m) => (m.supportedGenerationMethods ?? []).includes('generateContent'))
|
|
73
|
+
.map((m) => normalizeModelName(m.name ?? ''))
|
|
84
74
|
.filter((name) => name.startsWith('gemini') && !name.includes('embedding'))),
|
|
85
75
|
];
|
|
86
76
|
if (discoveredModels.length === 0) {
|
|
@@ -94,16 +84,16 @@ const getAvailableGeminiModels = () => __awaiter(void 0, void 0, void 0, functio
|
|
|
94
84
|
(0, log_1.warn)(`Failed to load Gemini models from API. Falling back to defaults. ${String(e)}`);
|
|
95
85
|
return [...FALLBACK_GEMINI_MODELS];
|
|
96
86
|
}
|
|
97
|
-
}
|
|
87
|
+
};
|
|
98
88
|
// Helper to get available key+model combinations
|
|
99
|
-
const getAvailableGeminiCombinations = (prefer) =>
|
|
89
|
+
const getAvailableGeminiCombinations = async (prefer) => {
|
|
100
90
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
101
91
|
if (!genAIs || genAIs.length === 0) {
|
|
102
92
|
const keyServiceCombinations = (0, apikey_1.getAvailableCombinations)('gemini');
|
|
103
93
|
const keys = keyServiceCombinations.map((combo) => combo.key);
|
|
104
94
|
genAIs = keys.map((k) => [k, new genai_1.GoogleGenAI({ apiKey: k })]);
|
|
105
95
|
}
|
|
106
|
-
const availableModels =
|
|
96
|
+
const availableModels = await getAvailableGeminiModels();
|
|
107
97
|
const sortedModels = sortModelsByPreference(availableModels, prefer);
|
|
108
98
|
const combinations = [];
|
|
109
99
|
for (const [key, ai] of genAIs) {
|
|
@@ -116,35 +106,34 @@ const getAvailableGeminiCombinations = (prefer) => __awaiter(void 0, void 0, voi
|
|
|
116
106
|
}
|
|
117
107
|
}
|
|
118
108
|
return combinations;
|
|
119
|
-
}
|
|
120
|
-
const geminiPromptImage =
|
|
109
|
+
};
|
|
110
|
+
const geminiPromptImage = async ({ prompt, urls, ident, prefer, }) => {
|
|
121
111
|
let images = [];
|
|
122
112
|
if (urls && urls.length > 0) {
|
|
123
|
-
images =
|
|
113
|
+
images = await (0, async_1.asyncMap)(urls, (i) => (0, fetch_1.fetchToMemory)(i));
|
|
124
114
|
}
|
|
125
115
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
126
116
|
if (images.find((a) => !a)) {
|
|
127
117
|
throw new Error('image not downloaded correctly');
|
|
128
118
|
}
|
|
129
|
-
const r =
|
|
119
|
+
const r = await (0, exports.geminiPromptDirect)({
|
|
130
120
|
prompt,
|
|
131
121
|
images: images.filter(array_1.notEmpty),
|
|
132
122
|
ident,
|
|
133
123
|
prefer,
|
|
134
124
|
});
|
|
135
125
|
return r;
|
|
136
|
-
}
|
|
126
|
+
};
|
|
137
127
|
exports.geminiPromptImage = geminiPromptImage;
|
|
138
|
-
const geminiPromptDirect =
|
|
128
|
+
const geminiPromptDirect = async ({ prompt, images = [], ident, prefer, groundedSearch = false, }) => {
|
|
139
129
|
const parts = images.map((i) => ({
|
|
140
130
|
inlineData: {
|
|
141
131
|
data: Buffer.from(i.arraybuffer).toString('base64'),
|
|
142
132
|
mimeType: i.type,
|
|
143
133
|
},
|
|
144
134
|
}));
|
|
145
|
-
return (0, retryOnError_1.retryOnError)(`geminiPromptDirect:${ident
|
|
146
|
-
|
|
147
|
-
const combinations = yield getAvailableGeminiCombinations(prefer);
|
|
135
|
+
return (0, retryOnError_1.retryOnError)(`geminiPromptDirect:${ident ?? 'unknown'}`, async () => {
|
|
136
|
+
const combinations = await getAvailableGeminiCombinations(prefer);
|
|
148
137
|
if (combinations.length === 0) {
|
|
149
138
|
throw new Error('No available API key and model combinations');
|
|
150
139
|
}
|
|
@@ -161,8 +150,8 @@ const geminiPromptDirect = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
161
150
|
}
|
|
162
151
|
(0, log_1.info)('gem query on:' + selectedModel, requestConfig);
|
|
163
152
|
try {
|
|
164
|
-
const response =
|
|
165
|
-
const rawtext = (
|
|
153
|
+
const response = await ai.models.generateContent(requestConfig);
|
|
154
|
+
const rawtext = (response.text ?? '')
|
|
166
155
|
.replace(/```(json)?/gi, '')
|
|
167
156
|
.replace(/:[ ]+undefined/gim, ': null');
|
|
168
157
|
(0, log_1.info)('gem response');
|
|
@@ -179,10 +168,10 @@ const geminiPromptDirect = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
179
168
|
}
|
|
180
169
|
throw e;
|
|
181
170
|
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
171
|
+
}, 1, 5000);
|
|
172
|
+
};
|
|
184
173
|
exports.geminiPromptDirect = geminiPromptDirect;
|
|
185
|
-
const resolveGroundedUrl = (url) =>
|
|
174
|
+
const resolveGroundedUrl = async (url) => {
|
|
186
175
|
if (!url.includes('vertexaisearch.cloud.google.com')) {
|
|
187
176
|
(0, log_1.debug)('not a grounded url', url);
|
|
188
177
|
return url;
|
|
@@ -190,7 +179,7 @@ const resolveGroundedUrl = (url) => __awaiter(void 0, void 0, void 0, function*
|
|
|
190
179
|
try {
|
|
191
180
|
(0, log_1.debug)('resolving grounded url', url);
|
|
192
181
|
// Fetch the grounded URL with redirect following disabled
|
|
193
|
-
const response =
|
|
182
|
+
const response = await fetch(url, {
|
|
194
183
|
method: 'HEAD',
|
|
195
184
|
redirect: 'manual',
|
|
196
185
|
});
|
|
@@ -203,7 +192,7 @@ const resolveGroundedUrl = (url) => __awaiter(void 0, void 0, void 0, function*
|
|
|
203
192
|
}
|
|
204
193
|
}
|
|
205
194
|
// If no redirect, try a GET request to follow any JavaScript redirects
|
|
206
|
-
const fullResponse =
|
|
195
|
+
const fullResponse = await fetch(url, {
|
|
207
196
|
redirect: 'follow',
|
|
208
197
|
});
|
|
209
198
|
const finalUrl = fullResponse.url;
|
|
@@ -215,5 +204,5 @@ const resolveGroundedUrl = (url) => __awaiter(void 0, void 0, void 0, function*
|
|
|
215
204
|
// Return original URL if resolution fails
|
|
216
205
|
return url;
|
|
217
206
|
}
|
|
218
|
-
}
|
|
207
|
+
};
|
|
219
208
|
exports.resolveGroundedUrl = resolveGroundedUrl;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.sleep = exports.isRetryableApiError = exports.isOverloadedApiKeyError = exports.retryableErrorMessages = exports.overloadedMessages = void 0;
|
|
13
4
|
exports.retryOnError = retryOnError;
|
|
@@ -34,24 +25,22 @@ const isOverloadedApiKeyError = (error) => errorContainsAnyMessage(error, export
|
|
|
34
25
|
exports.isOverloadedApiKeyError = isOverloadedApiKeyError;
|
|
35
26
|
const isRetryableApiError = (error) => errorContainsAnyMessage(error, exports.retryableErrorMessages);
|
|
36
27
|
exports.isRetryableApiError = isRetryableApiError;
|
|
37
|
-
function retryOnError(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return retryOnError(debugIdent, fn, retries - 1, errorDelay, errorCheck);
|
|
51
|
-
}
|
|
52
|
-
throw error;
|
|
28
|
+
async function retryOnError(
|
|
29
|
+
/** so we can log retries with useful info */
|
|
30
|
+
debugIdent, fn, retries = 1, errorDelay = 2000, errorCheck = exports.isRetryableApiError) {
|
|
31
|
+
try {
|
|
32
|
+
return await fn();
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const e = error;
|
|
36
|
+
const em = e.message;
|
|
37
|
+
if (retries > 0 && errorCheck(e)) {
|
|
38
|
+
(0, log_1.info)(`Operation ${debugIdent} failed. Retrying after ${errorDelay}ms...`, em);
|
|
39
|
+
await (0, exports.sleep)(errorDelay);
|
|
40
|
+
return retryOnError(debugIdent, fn, retries - 1, errorDelay, errorCheck);
|
|
53
41
|
}
|
|
54
|
-
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
55
44
|
}
|
|
56
45
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
57
46
|
exports.sleep = sleep;
|
package/dist/api/helpers/s3.js
CHANGED
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
12
|
-
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
13
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
14
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
15
|
-
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
16
|
-
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
17
|
-
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
18
|
-
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
19
|
-
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
20
|
-
function fulfill(value) { resume("next", value); }
|
|
21
|
-
function reject(value) { resume("throw", value); }
|
|
22
|
-
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
23
|
-
};
|
|
24
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
3
|
exports.copyFile = exports.deleteFiles = exports.deleteFile = exports.putS3Object = exports.getS3Object = exports.setS3 = exports.createStorageClient = void 0;
|
|
26
4
|
exports.getS3Objects = getS3Objects;
|
|
@@ -50,7 +28,6 @@ const getCacheKey = (config) => {
|
|
|
50
28
|
});
|
|
51
29
|
};
|
|
52
30
|
const createStorageClient = (config) => {
|
|
53
|
-
var _a;
|
|
54
31
|
const cacheKey = getCacheKey(config);
|
|
55
32
|
const cachedClient = clientCache.get(cacheKey);
|
|
56
33
|
if (cachedClient) {
|
|
@@ -62,14 +39,19 @@ const createStorageClient = (config) => {
|
|
|
62
39
|
if (!accountId) {
|
|
63
40
|
throw new Error('Account ID is required for R2. Set CLOUDFLARE_ACCOUNT_ID env var or provide accountId in config');
|
|
64
41
|
}
|
|
65
|
-
client = new client_s3_1.S3Client(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
42
|
+
client = new client_s3_1.S3Client({
|
|
43
|
+
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
|
44
|
+
forcePathStyle: true,
|
|
45
|
+
...(config.accessKeyId && config.secretAccessKey
|
|
46
|
+
? {
|
|
47
|
+
credentials: {
|
|
48
|
+
accessKeyId: config.accessKeyId,
|
|
49
|
+
secretAccessKey: config.secretAccessKey,
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
: {}),
|
|
53
|
+
region: config.region ?? 'auto',
|
|
54
|
+
});
|
|
73
55
|
}
|
|
74
56
|
else {
|
|
75
57
|
client = new client_s3_1.S3Client({
|
|
@@ -89,9 +71,9 @@ exports.setS3 = setS3;
|
|
|
89
71
|
provider: 's3',
|
|
90
72
|
region: 'ap-southeast-2',
|
|
91
73
|
});
|
|
92
|
-
const getS3Object =
|
|
74
|
+
const getS3Object = async ({ fileurl: { Bucket, Key }, }) => {
|
|
93
75
|
try {
|
|
94
|
-
const r =
|
|
76
|
+
const r = await s3.send(new client_s3_1.GetObjectCommand({ Bucket, Key }));
|
|
95
77
|
if (!r.Body) {
|
|
96
78
|
throw new Error('no body returned');
|
|
97
79
|
}
|
|
@@ -105,32 +87,30 @@ const getS3Object = (_a) => __awaiter(void 0, [_a], void 0, function* ({ fileurl
|
|
|
105
87
|
catch (e) {
|
|
106
88
|
return { error: e.toString() };
|
|
107
89
|
}
|
|
108
|
-
}
|
|
90
|
+
};
|
|
109
91
|
exports.getS3Object = getS3Object;
|
|
110
92
|
/** function generator to get s3 files */
|
|
111
|
-
function getS3Objects(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
yield yield __await({ error: g.error });
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
yield yield __await({ data: g.data });
|
|
127
|
-
}
|
|
93
|
+
async function* getS3Objects({ bucket, keys, }) {
|
|
94
|
+
let toProcess = keys.map((Key) => ({
|
|
95
|
+
Bucket: bucket,
|
|
96
|
+
Key,
|
|
97
|
+
}));
|
|
98
|
+
while (toProcess.length > 0) {
|
|
99
|
+
const { part, rest } = (0, array_1.take)(toProcess, 1);
|
|
100
|
+
toProcess = rest;
|
|
101
|
+
const fileurl = part[0];
|
|
102
|
+
const g = await (0, exports.getS3Object)({ fileurl });
|
|
103
|
+
if ('error' in g) {
|
|
104
|
+
yield { error: g.error };
|
|
128
105
|
}
|
|
129
|
-
|
|
106
|
+
else {
|
|
107
|
+
yield { data: g.data };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
130
110
|
}
|
|
131
|
-
const putS3Object =
|
|
111
|
+
const putS3Object = async ({ Body, Bucket, Key, ContentType, CacheControl = 'public, max-age=300', }) => {
|
|
132
112
|
try {
|
|
133
|
-
const r =
|
|
113
|
+
const r = await s3.send(new client_s3_1.PutObjectCommand({ Body, Bucket, Key, ContentType, CacheControl }));
|
|
134
114
|
const code = r.$metadata.httpStatusCode;
|
|
135
115
|
if (code !== 200) {
|
|
136
116
|
return {
|
|
@@ -142,31 +122,30 @@ const putS3Object = (_a) => __awaiter(void 0, [_a], void 0, function* ({ Body, B
|
|
|
142
122
|
catch (e) {
|
|
143
123
|
return { error: e.toString() };
|
|
144
124
|
}
|
|
145
|
-
}
|
|
125
|
+
};
|
|
146
126
|
exports.putS3Object = putS3Object;
|
|
147
|
-
const deleteFile =
|
|
127
|
+
const deleteFile = async ({ Bucket, Key, }) => {
|
|
148
128
|
try {
|
|
149
|
-
|
|
129
|
+
await s3.send(new client_s3_1.DeleteObjectCommand({ Bucket, Key }));
|
|
150
130
|
return {};
|
|
151
131
|
}
|
|
152
132
|
catch (e) {
|
|
153
133
|
return { error: e.toString() };
|
|
154
134
|
}
|
|
155
|
-
}
|
|
135
|
+
};
|
|
156
136
|
exports.deleteFile = deleteFile;
|
|
157
|
-
const deleteFiles =
|
|
158
|
-
var _b;
|
|
137
|
+
const deleteFiles = async ({ Bucket, Keys, }) => {
|
|
159
138
|
try {
|
|
160
139
|
let toDelete = Keys.map((Key) => ({ Key }));
|
|
161
140
|
let deleted = 0;
|
|
162
141
|
while (toDelete.length > 0) {
|
|
163
142
|
const { part, rest } = (0, array_1.take)(toDelete, 900);
|
|
164
143
|
toDelete = rest;
|
|
165
|
-
const res =
|
|
144
|
+
const res = await s3.send(new client_s3_1.DeleteObjectsCommand({
|
|
166
145
|
Bucket,
|
|
167
146
|
Delete: { Objects: part },
|
|
168
147
|
}));
|
|
169
|
-
if (!
|
|
148
|
+
if (!res.Deleted?.length) {
|
|
170
149
|
throw new Error('no deleted files');
|
|
171
150
|
}
|
|
172
151
|
deleted += res.Deleted.length;
|
|
@@ -177,12 +156,12 @@ const deleteFiles = (_a) => __awaiter(void 0, [_a], void 0, function* ({ Bucket,
|
|
|
177
156
|
catch (e) {
|
|
178
157
|
return { error: e.toString() };
|
|
179
158
|
}
|
|
180
|
-
}
|
|
159
|
+
};
|
|
181
160
|
exports.deleteFiles = deleteFiles;
|
|
182
|
-
const copyFile =
|
|
161
|
+
const copyFile = async ({ Bucket, fromKey, toKey, deleteSource = false, }) => {
|
|
183
162
|
try {
|
|
184
163
|
(0, log_1.debug)(`copying s3 file from ${Bucket}- ${fromKey} to ${toKey}`);
|
|
185
|
-
|
|
164
|
+
await s3.send(new client_s3_1.CopyObjectCommand({
|
|
186
165
|
//incl bucket
|
|
187
166
|
CopySource: Bucket + '/' + fromKey,
|
|
188
167
|
//dest
|
|
@@ -190,7 +169,7 @@ const copyFile = (_a) => __awaiter(void 0, [_a], void 0, function* ({ Bucket, fr
|
|
|
190
169
|
Key: toKey,
|
|
191
170
|
}));
|
|
192
171
|
if (deleteSource) {
|
|
193
|
-
const df =
|
|
172
|
+
const df = await (0, exports.deleteFile)({ Bucket, Key: fromKey });
|
|
194
173
|
if (df.error) {
|
|
195
174
|
return { error: df.error };
|
|
196
175
|
}
|
|
@@ -200,31 +179,28 @@ const copyFile = (_a) => __awaiter(void 0, [_a], void 0, function* ({ Bucket, fr
|
|
|
200
179
|
catch (e) {
|
|
201
180
|
return { error: e.toString() };
|
|
202
181
|
}
|
|
203
|
-
}
|
|
182
|
+
};
|
|
204
183
|
exports.copyFile = copyFile;
|
|
205
|
-
function listFiles(bucketName, opt) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
response
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return { error: err.toString() };
|
|
226
|
-
}
|
|
227
|
-
});
|
|
184
|
+
async function listFiles(bucketName, opt) {
|
|
185
|
+
try {
|
|
186
|
+
const ret = [];
|
|
187
|
+
let response;
|
|
188
|
+
do {
|
|
189
|
+
response = await s3.send(new client_s3_1.ListObjectsV2Command({
|
|
190
|
+
Bucket: bucketName,
|
|
191
|
+
ContinuationToken: response?.NextContinuationToken,
|
|
192
|
+
Prefix: opt?.prefix,
|
|
193
|
+
}));
|
|
194
|
+
response.Contents?.filter((r) => r.Key).map((c) => {
|
|
195
|
+
ret.push(c.Key);
|
|
196
|
+
});
|
|
197
|
+
} while (response.IsTruncated);
|
|
198
|
+
return { data: (0, array_1.distinct)(ret.filter((r) => r)) };
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
(0, log_1.error)('Error', err);
|
|
202
|
+
return { error: err.toString() };
|
|
203
|
+
}
|
|
228
204
|
}
|
|
229
205
|
/**
|
|
230
206
|
* allow uploading of file directly to s3
|
|
@@ -239,25 +215,23 @@ function listFiles(bucketName, opt) {
|
|
|
239
215
|
formData.append('file', file);
|
|
240
216
|
fetch.POST(url,formData)
|
|
241
217
|
*/
|
|
242
|
-
function getPresignedPostURL(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
});
|
|
218
|
+
async function getPresignedPostURL({ bucket, key, maxMb = 5, }) {
|
|
219
|
+
try {
|
|
220
|
+
const ps = await (0, s3_presigned_post_1.createPresignedPost)(s3, {
|
|
221
|
+
Bucket: bucket,
|
|
222
|
+
Key: key,
|
|
223
|
+
Expires: 600,
|
|
224
|
+
Conditions: [
|
|
225
|
+
['content-length-range', 0, maxMb * 1049000], // content length restrictions: 0-5MB
|
|
226
|
+
['starts-with', '$Content-Type', 'image/'],
|
|
227
|
+
],
|
|
228
|
+
});
|
|
229
|
+
const fields = (0, object_1.copy)(ps.fields);
|
|
230
|
+
return { data: { fields, url: ps.url } };
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
return { error: e.toString() };
|
|
234
|
+
}
|
|
261
235
|
}
|
|
262
236
|
/**
|
|
263
237
|
* Generate a presigned PUT URL for direct browser upload.
|
|
@@ -267,17 +241,24 @@ function getPresignedPostURL(_a) {
|
|
|
267
241
|
* If contentLength is provided, the upload MUST match that exact size
|
|
268
242
|
* or the request will be rejected (signature mismatch).
|
|
269
243
|
*/
|
|
270
|
-
function getPresignedPutUrl(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
244
|
+
async function getPresignedPutUrl({ bucket, key, contentType, contentLength, expiresIn = 600, }) {
|
|
245
|
+
try {
|
|
246
|
+
const command = new client_s3_1.PutObjectCommand({
|
|
247
|
+
Bucket: bucket,
|
|
248
|
+
Key: key,
|
|
249
|
+
ContentType: contentType,
|
|
250
|
+
...(contentLength !== undefined && { ContentLength: contentLength }),
|
|
251
|
+
});
|
|
252
|
+
const url = await (0, s3_request_presigner_1.getSignedUrl)(s3, command, {
|
|
253
|
+
expiresIn,
|
|
254
|
+
// Sign the Content-Length header so it's enforced
|
|
255
|
+
...(contentLength !== undefined && {
|
|
275
256
|
signableHeaders: new Set(['content-length']),
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
}
|
|
257
|
+
}),
|
|
258
|
+
});
|
|
259
|
+
return { data: url };
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
return { error: e.toString() };
|
|
263
|
+
}
|
|
283
264
|
}
|
package/dist/api/helpers/ses.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.sendEmails = exports.sendEmail = exports.ses = exports.setSes = void 0;
|
|
13
4
|
const client_ses_1 = require("@aws-sdk/client-ses");
|
|
@@ -19,33 +10,35 @@ const setSes = (region) => {
|
|
|
19
10
|
};
|
|
20
11
|
exports.setSes = setSes;
|
|
21
12
|
exports.ses = (0, exports.setSes)('ap-southeast-2');
|
|
22
|
-
const sendEmail =
|
|
23
|
-
var _b;
|
|
13
|
+
const sendEmail = async ({ to, message, subject, sourceArn, from, }) => {
|
|
24
14
|
try {
|
|
25
|
-
const sourceArnRegion =
|
|
15
|
+
const sourceArnRegion = sourceArn.match(':ses:(.*?):')?.[1];
|
|
26
16
|
if (sourceArn !== exports.ses.config.region && sourceArnRegion) {
|
|
27
17
|
(0, log_1.warn)('ses arn not equal to config region changing to:' + sourceArnRegion);
|
|
28
18
|
(0, exports.setSes)(sourceArnRegion);
|
|
29
19
|
}
|
|
30
20
|
const ishtml = message.startsWith('<!DOCTYPE HTML') || message.startsWith('<html');
|
|
31
21
|
(0, log_1.warn)('sending email. html=' + ishtml);
|
|
32
|
-
|
|
22
|
+
await exports.ses.send(new client_ses_1.SendEmailCommand({
|
|
33
23
|
Destination: {
|
|
34
24
|
CcAddresses: [],
|
|
35
25
|
ToAddresses: [to],
|
|
36
26
|
},
|
|
37
27
|
Message: {
|
|
38
|
-
Body:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
Body: {
|
|
29
|
+
...(ishtml && {
|
|
30
|
+
Html: {
|
|
31
|
+
Data: message,
|
|
32
|
+
Charset: 'UTF-8',
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
...(!ishtml && {
|
|
36
|
+
Text: {
|
|
37
|
+
Data: message,
|
|
38
|
+
Charset: 'UTF-8',
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
49
42
|
Subject: {
|
|
50
43
|
Charset: 'UTF-8',
|
|
51
44
|
Data: subject,
|
|
@@ -61,7 +54,7 @@ const sendEmail = (_a) => __awaiter(void 0, [_a], void 0, function* ({ to, messa
|
|
|
61
54
|
(0, log_1.warn)('ses send error:' + JSON.stringify(e));
|
|
62
55
|
return { error: e.toString() };
|
|
63
56
|
}
|
|
64
|
-
}
|
|
57
|
+
};
|
|
65
58
|
exports.sendEmail = sendEmail;
|
|
66
|
-
const sendEmails = (emails) =>
|
|
59
|
+
const sendEmails = async (emails) => Promise.all(emails.map(exports.sendEmail));
|
|
67
60
|
exports.sendEmails = sendEmails;
|
package/dist/api/helpers/sqs.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.sendMessages = exports.sqs = exports.setSqs = void 0;
|
|
13
4
|
const client_sqs_1 = require("@aws-sdk/client-sqs");
|
|
@@ -18,18 +9,17 @@ const setSqs = (region) => {
|
|
|
18
9
|
};
|
|
19
10
|
exports.setSqs = setSqs;
|
|
20
11
|
exports.sqs = (0, exports.setSqs)('ap-southeast-2');
|
|
21
|
-
const sendMessages = (items, queueUrl) =>
|
|
22
|
-
|
|
23
|
-
const p = yield exports.sqs.send(new client_sqs_1.SendMessageBatchCommand({
|
|
12
|
+
const sendMessages = async (items, queueUrl) => {
|
|
13
|
+
const p = await exports.sqs.send(new client_sqs_1.SendMessageBatchCommand({
|
|
24
14
|
QueueUrl: queueUrl,
|
|
25
15
|
Entries: items.map((i) => ({
|
|
26
16
|
MessageBody: JSON.stringify(i),
|
|
27
17
|
Id: (0, hashCode_1.hashCode)(JSON.stringify(i)),
|
|
28
18
|
})),
|
|
29
19
|
}));
|
|
30
|
-
if ((
|
|
31
|
-
return { error: `failed: ${JSON.stringify(
|
|
20
|
+
if ((p.Failed ?? []).length > 0) {
|
|
21
|
+
return { error: `failed: ${JSON.stringify(p.Failed ?? [], null, 2)}` };
|
|
32
22
|
}
|
|
33
23
|
return {};
|
|
34
|
-
}
|
|
24
|
+
};
|
|
35
25
|
exports.sendMessages = sendMessages;
|