triangle-utils 1.2.12 → 1.3.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/dist/src/Utils.js +24 -0
- package/dist/src/Utils_Bedrock.js +89 -0
- package/dist/src/Utils_Bee.js +101 -0
- package/dist/src/Utils_DynamoDB.js +381 -0
- package/dist/src/Utils_Misc.js +627 -0
- package/dist/src/Utils_S3.js +96 -0
- package/dist/src/Utils_S3Vectors.js +131 -0
- package/dist/src/Utils_Youtube.js +35 -0
- package/{utils → dist/src}/election_ids.js +472 -474
- package/{states.js → dist/src/states.js} +253 -256
- package/dist/src/types/Config.js +1 -0
- package/dist/types/Config.js +1 -0
- package/eslint.config.ts +13 -0
- package/jest.config.js +19 -0
- package/package.json +23 -3
- package/src/Utils.ts +28 -0
- package/{utils/Utils_Bedrock.js → src/Utils_Bedrock.ts} +23 -12
- package/{utils/Utils_Bee.js → src/Utils_Bee.ts} +39 -19
- package/src/Utils_DynamoDB.ts +448 -0
- package/src/Utils_Misc.ts +655 -0
- package/{utils/Utils_S3.js → src/Utils_S3.ts} +34 -14
- package/{utils/Utils_S3Vectors.js → src/Utils_S3Vectors.ts} +43 -29
- package/{utils/Utils_Youtube.js → src/Utils_Youtube.ts} +13 -6
- package/src/types/Config.ts +9 -0
- package/test/Utils.test.ts +85 -0
- package/tsconfig.json +31 -0
- package/Utils.js +0 -33
- package/test.js +0 -62
- package/utils/Utils_CitizenPortal.js +0 -26
- package/utils/Utils_DynamoDB.js +0 -316
- package/utils/Utils_Misc.js +0 -161
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { S3, NoSuchKey, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
2
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
3
|
+
function parse_s3_filename(s3_filename) {
|
|
4
|
+
if (s3_filename.substring(0, 5) !== "s3://") {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
const bucket_filename = s3_filename.substring(5);
|
|
8
|
+
const bucket = bucket_filename.split("/")[0];
|
|
9
|
+
const filename = bucket_filename.split("/").slice(1).join("/");
|
|
10
|
+
return { Bucket: bucket, Key: filename };
|
|
11
|
+
}
|
|
12
|
+
export class Utils_S3 {
|
|
13
|
+
s3;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.s3 = new S3({ region: config.region });
|
|
16
|
+
}
|
|
17
|
+
async file_exists(s3_filename) {
|
|
18
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
19
|
+
if (s3_key === undefined) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const head = await this.s3.headObject(s3_key);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async get_file(s3_filename) {
|
|
31
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
32
|
+
if (s3_key === undefined) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const response = await this.s3.getObject(s3_key);
|
|
37
|
+
const body = response.Body;
|
|
38
|
+
if (body === undefined) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const text = body.transformToString("utf-8");
|
|
42
|
+
return text;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof NoSuchKey) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async create_file(s3_filename, content, options = {}) {
|
|
52
|
+
const content_type = options.content_type !== undefined ? options.content_type : undefined;
|
|
53
|
+
const exists = await this.file_exists(s3_filename);
|
|
54
|
+
if (exists) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
58
|
+
if (s3_key === undefined) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return await this.s3.putObject({
|
|
62
|
+
...s3_key,
|
|
63
|
+
Body: content,
|
|
64
|
+
ContentType: content_type
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async delete_file(s3_filename) {
|
|
68
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
69
|
+
if (s3_key === undefined) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
await this.s3.deleteObject(s3_key);
|
|
73
|
+
}
|
|
74
|
+
async generate_download_url(s3_filename) {
|
|
75
|
+
const exists = await this.file_exists(s3_filename);
|
|
76
|
+
if (!exists) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
80
|
+
if (s3_key === undefined) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const command = new GetObjectCommand(s3_key);
|
|
84
|
+
const url = await getSignedUrl(this.s3, command);
|
|
85
|
+
return url;
|
|
86
|
+
}
|
|
87
|
+
async generate_upload_url(s3_filename) {
|
|
88
|
+
const s3_key = parse_s3_filename(s3_filename);
|
|
89
|
+
if (s3_key === undefined) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const command = new PutObjectCommand(s3_key);
|
|
93
|
+
const url = await getSignedUrl(this.s3, command);
|
|
94
|
+
return url;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { S3Vectors } from "@aws-sdk/client-s3vectors";
|
|
2
|
+
export class Utils_S3Vectors {
|
|
3
|
+
s3vectors;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.s3vectors = new S3Vectors({ region: config.region });
|
|
6
|
+
}
|
|
7
|
+
async scan(vector_bucket, vector_index) {
|
|
8
|
+
const vector_keys = [];
|
|
9
|
+
let next_token = undefined;
|
|
10
|
+
while (true) {
|
|
11
|
+
const request = {
|
|
12
|
+
vectorBucketName: vector_bucket,
|
|
13
|
+
indexName: vector_index,
|
|
14
|
+
maxResults: 1000,
|
|
15
|
+
nextToken: next_token
|
|
16
|
+
};
|
|
17
|
+
const response = await this.s3vectors.listVectors(request);
|
|
18
|
+
if (response === undefined || response.vectors === undefined) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
vector_keys.push(...response.vectors.map(vector => vector.key));
|
|
22
|
+
next_token = response.nextToken;
|
|
23
|
+
if (next_token === undefined) {
|
|
24
|
+
return vector_keys.filter(vector_key => vector_key !== undefined);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async get(vector_bucket, vector_index, vector_key) {
|
|
29
|
+
const response = await this.s3vectors.getVectors({
|
|
30
|
+
vectorBucketName: vector_bucket,
|
|
31
|
+
indexName: vector_index,
|
|
32
|
+
keys: [vector_key],
|
|
33
|
+
returnData: true,
|
|
34
|
+
returnMetadata: true
|
|
35
|
+
});
|
|
36
|
+
const vector = response.vectors?.[0];
|
|
37
|
+
if (vector === undefined || vector.key === undefined || vector.data === undefined || vector.data.float32 === undefined || vector.metadata === undefined) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
key: vector.key,
|
|
42
|
+
data: vector.data.float32,
|
|
43
|
+
metadata: vector.metadata
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async batch_get(vector_bucket, vector_index, vector_keys) {
|
|
47
|
+
const vectors = [];
|
|
48
|
+
for (let i = 0; i < vector_keys.length; i += 100) {
|
|
49
|
+
const new_vectors = await this.s3vectors.getVectors({
|
|
50
|
+
vectorBucketName: vector_bucket,
|
|
51
|
+
indexName: vector_index,
|
|
52
|
+
keys: vector_keys.slice(i, i + 100),
|
|
53
|
+
returnData: true,
|
|
54
|
+
returnMetadata: true
|
|
55
|
+
})
|
|
56
|
+
.then(response => response.vectors);
|
|
57
|
+
if (new_vectors === undefined) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const vectors_by_key = Object.fromEntries(new_vectors
|
|
61
|
+
.map(vector => [
|
|
62
|
+
vector.key,
|
|
63
|
+
vector.key !== undefined && vector.data !== undefined && vector.data.float32 !== undefined && vector.metadata !== undefined ? {
|
|
64
|
+
key: vector.key,
|
|
65
|
+
data: vector.data.float32,
|
|
66
|
+
metadata: vector.metadata
|
|
67
|
+
} : undefined
|
|
68
|
+
]));
|
|
69
|
+
vectors.push(...vector_keys.map(vector_key => vectors_by_key[vector_key]));
|
|
70
|
+
}
|
|
71
|
+
return vectors;
|
|
72
|
+
}
|
|
73
|
+
async create(vector_bucket, vector_index, vector) {
|
|
74
|
+
await this.s3vectors.putVectors({
|
|
75
|
+
vectorBucketName: vector_bucket,
|
|
76
|
+
indexName: vector_index,
|
|
77
|
+
vectors: [{
|
|
78
|
+
key: vector.key,
|
|
79
|
+
data: {
|
|
80
|
+
float32: vector.data
|
|
81
|
+
},
|
|
82
|
+
metadata: vector.metadata
|
|
83
|
+
}]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async batch_create(vector_bucket, vector_index, vectors) {
|
|
87
|
+
for (let i = 0; i < vectors.length; i += 100) {
|
|
88
|
+
await this.s3vectors.putVectors({
|
|
89
|
+
vectorBucketName: vector_bucket,
|
|
90
|
+
indexName: vector_index,
|
|
91
|
+
vectors: vectors.slice(i, i + 100).map(vector => ({
|
|
92
|
+
key: vector.key,
|
|
93
|
+
data: {
|
|
94
|
+
float32: vector.data
|
|
95
|
+
},
|
|
96
|
+
metadata: vector.metadata
|
|
97
|
+
}))
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async delete(vector_bucket, vector_index, vector_key) {
|
|
102
|
+
await this.s3vectors.deleteVectors({
|
|
103
|
+
vectorBucketName: vector_bucket,
|
|
104
|
+
indexName: vector_index,
|
|
105
|
+
keys: [vector_key]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async batch_delete(vector_bucket, vector_index, vector_keys) {
|
|
109
|
+
for (let i = 0; i < vector_keys.length; i += 100) {
|
|
110
|
+
await this.s3vectors.deleteVectors({
|
|
111
|
+
vectorBucketName: vector_bucket,
|
|
112
|
+
indexName: vector_index,
|
|
113
|
+
keys: vector_keys.slice(i, i + 100)
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async query(vector_bucket, vector_index, data, num_vectors, filters = {}) {
|
|
118
|
+
const response = await this.s3vectors.queryVectors({
|
|
119
|
+
vectorBucketName: vector_bucket,
|
|
120
|
+
indexName: vector_index,
|
|
121
|
+
queryVector: {
|
|
122
|
+
float32: data
|
|
123
|
+
},
|
|
124
|
+
topK: num_vectors,
|
|
125
|
+
returnDistance: true,
|
|
126
|
+
returnMetadata: true,
|
|
127
|
+
filter: filters
|
|
128
|
+
});
|
|
129
|
+
return response.vectors;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { youtube_v3 } from "googleapis";
|
|
2
|
+
export class Utils_Youtube {
|
|
3
|
+
config;
|
|
4
|
+
youtube;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
this.youtube = new youtube_v3.Youtube({
|
|
8
|
+
auth: config.youtube_api_key
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
async batch_get_videos(video_ids, attributes = ["snippet", "contentDetails"]) {
|
|
12
|
+
for (let i = 0; i < 3; i++) {
|
|
13
|
+
try {
|
|
14
|
+
const response = await this.youtube.videos.list({
|
|
15
|
+
part: attributes,
|
|
16
|
+
id: video_ids
|
|
17
|
+
});
|
|
18
|
+
if (response.status !== 200) {
|
|
19
|
+
console.log("Status", response.status);
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const items = response.data.items;
|
|
23
|
+
return items;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
console.log(error.stack);
|
|
28
|
+
}
|
|
29
|
+
console.log("Failed to get from Scraping Bee.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
console.log("Failed to get from Scraping Bee, quitting.");
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|