s3db.js 1.0.0
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/.github/workflows/pipeline.yml +16 -0
- package/README.md +742 -0
- package/build/cache/avro.serializer.js +16 -0
- package/build/cache/json.serializer.js +7 -0
- package/build/cache/s3-cache.class.js +157 -0
- package/build/cache/s3-resource-cache.class.js +77 -0
- package/build/cache/serializers.type.js +8 -0
- package/build/errors.js +64 -0
- package/build/index.js +9 -0
- package/build/metadata.interface.js +2 -0
- package/build/plugin.interface.js +2 -0
- package/build/resource.class.js +485 -0
- package/build/resource.interface.js +2 -0
- package/build/s3-client.class.js +274 -0
- package/build/s3db-config.interface.js +2 -0
- package/build/s3db.class.js +185 -0
- package/build/stream/resource-ids-read-stream.class.js +100 -0
- package/build/stream/resource-ids-transformer.class.js +40 -0
- package/build/stream/resource-write-stream.class.js +76 -0
- package/build/validator.js +37 -0
- package/examples/1-bulk-insert.js +64 -0
- package/examples/2-read-stream.js +61 -0
- package/examples/3-read-stream-to-csv.js +57 -0
- package/examples/4-read-stream-to-zip.js +56 -0
- package/examples/5-write-stream.js +98 -0
- package/examples/6-jwt-tokens.js +124 -0
- package/examples/concerns/index.js +64 -0
- package/jest.config.ts +10 -0
- package/package.json +51 -0
- package/src/cache/avro.serializer.ts +12 -0
- package/src/cache/json.serializer.ts +4 -0
- package/src/cache/s3-cache.class.ts +155 -0
- package/src/cache/s3-resource-cache.class.ts +75 -0
- package/src/cache/serializers.type.ts +8 -0
- package/src/errors.ts +96 -0
- package/src/index.ts +4 -0
- package/src/metadata.interface.ts +4 -0
- package/src/plugin.interface.ts +4 -0
- package/src/resource.class.ts +531 -0
- package/src/resource.interface.ts +21 -0
- package/src/s3-client.class.ts +297 -0
- package/src/s3db-config.interface.ts +9 -0
- package/src/s3db.class.ts +215 -0
- package/src/stream/resource-ids-read-stream.class.ts +90 -0
- package/src/stream/resource-ids-transformer.class.ts +38 -0
- package/src/stream/resource-write-stream.class.ts +78 -0
- package/src/validator.ts +39 -0
- package/tests/cache.spec.ts +187 -0
- package/tests/concerns/index.ts +16 -0
- package/tests/config.spec.ts +29 -0
- package/tests/resources.spec.ts +197 -0
- package/tsconfig.json +111 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
35
|
+
var t = {};
|
|
36
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
37
|
+
t[p] = s[p];
|
|
38
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
39
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
40
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
41
|
+
t[p[i]] = s[p[i]];
|
|
42
|
+
}
|
|
43
|
+
return t;
|
|
44
|
+
};
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const nanoid_1 = require("nanoid");
|
|
51
|
+
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
52
|
+
const events_1 = __importDefault(require("events"));
|
|
53
|
+
const flat_1 = require("flat");
|
|
54
|
+
const lodash_1 = require("lodash");
|
|
55
|
+
const promise_pool_1 = require("@supercharge/promise-pool");
|
|
56
|
+
const errors_1 = require("./errors");
|
|
57
|
+
const s3_resource_cache_class_1 = __importDefault(require("./cache/s3-resource-cache.class"));
|
|
58
|
+
const resource_write_stream_class_1 = __importDefault(require("./stream/resource-write-stream.class"));
|
|
59
|
+
const resource_ids_read_stream_class_1 = __importDefault(require("./stream/resource-ids-read-stream.class"));
|
|
60
|
+
const resource_ids_transformer_class_1 = __importDefault(require("./stream/resource-ids-transformer.class"));
|
|
61
|
+
class Resource extends events_1.default {
|
|
62
|
+
/**
|
|
63
|
+
* Constructor
|
|
64
|
+
*/
|
|
65
|
+
constructor(params) {
|
|
66
|
+
super();
|
|
67
|
+
this.s3db = params.s3db;
|
|
68
|
+
this.name = params.name;
|
|
69
|
+
this.schema = params.schema;
|
|
70
|
+
this.options = params.options;
|
|
71
|
+
this.s3Client = params.s3Client;
|
|
72
|
+
this.validator = params.validatorInstance.compile(this.schema);
|
|
73
|
+
const { mapObj, reversedMapObj } = this.getMappersFromSchema(this.schema);
|
|
74
|
+
this.mapObj = mapObj;
|
|
75
|
+
this.reversedMapObj = reversedMapObj;
|
|
76
|
+
this.studyOptions();
|
|
77
|
+
if (this.options.cache === true) {
|
|
78
|
+
this.s3Cache = new s3_resource_cache_class_1.default({
|
|
79
|
+
resource: this,
|
|
80
|
+
compressData: true,
|
|
81
|
+
serializer: "json",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
getMappersFromSchema(schema) {
|
|
86
|
+
let i = 0;
|
|
87
|
+
const mapObj = (0, lodash_1.sortBy)(Object.entries(schema), ["0"]).reduce((acc, [key, value]) => {
|
|
88
|
+
acc[key] = String(i++);
|
|
89
|
+
return acc;
|
|
90
|
+
}, {});
|
|
91
|
+
const reversedMapObj = Object.entries(mapObj).reduce((acc, [key, value]) => {
|
|
92
|
+
acc[String(value)] = key;
|
|
93
|
+
return acc;
|
|
94
|
+
}, {});
|
|
95
|
+
return {
|
|
96
|
+
mapObj,
|
|
97
|
+
reversedMapObj,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export() {
|
|
101
|
+
const data = {
|
|
102
|
+
name: this.name,
|
|
103
|
+
schema: Object.assign({}, this.schema),
|
|
104
|
+
mapper: this.mapObj,
|
|
105
|
+
options: this.options,
|
|
106
|
+
};
|
|
107
|
+
for (const [name, definition] of Object.entries(this.schema)) {
|
|
108
|
+
data.schema[name] = JSON.stringify(definition);
|
|
109
|
+
}
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
studyOptions() {
|
|
113
|
+
if (!this.options.afterUnmap)
|
|
114
|
+
this.options.beforeMap = {};
|
|
115
|
+
if (!this.options.afterUnmap)
|
|
116
|
+
this.options.afterUnmap = {};
|
|
117
|
+
const schema = (0, flat_1.flatten)(this.schema, { safe: true });
|
|
118
|
+
const addRule = (arr, attribute, action) => {
|
|
119
|
+
if (!this.options[arr][attribute])
|
|
120
|
+
this.options[arr][attribute] = [];
|
|
121
|
+
this.options[arr][attribute] = [
|
|
122
|
+
...new Set([...this.options[arr][attribute], action]),
|
|
123
|
+
];
|
|
124
|
+
};
|
|
125
|
+
for (const [name, definition] of Object.entries(schema)) {
|
|
126
|
+
if (definition.includes("secret")) {
|
|
127
|
+
if (this.options.autoDecrypt === true) {
|
|
128
|
+
addRule("afterUnmap", name, "decrypt");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (definition.includes("array")) {
|
|
132
|
+
addRule("beforeMap", name, "fromArray");
|
|
133
|
+
addRule("afterUnmap", name, "toArray");
|
|
134
|
+
}
|
|
135
|
+
if (definition.includes("number")) {
|
|
136
|
+
addRule("beforeMap", name, "toString");
|
|
137
|
+
addRule("afterUnmap", name, "toNumber");
|
|
138
|
+
}
|
|
139
|
+
if (definition.includes("boolean")) {
|
|
140
|
+
addRule("beforeMap", name, "toJson");
|
|
141
|
+
addRule("afterUnmap", name, "fromJson");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
check(data) {
|
|
146
|
+
const result = {
|
|
147
|
+
original: Object.assign({}, data),
|
|
148
|
+
isValid: false,
|
|
149
|
+
errors: [],
|
|
150
|
+
};
|
|
151
|
+
const check = this.validator(data);
|
|
152
|
+
if (check === true) {
|
|
153
|
+
result.isValid = true;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
result.errors = check;
|
|
157
|
+
}
|
|
158
|
+
return Object.assign(Object.assign({}, result), { data });
|
|
159
|
+
}
|
|
160
|
+
validate(data) {
|
|
161
|
+
return this.check((0, flat_1.flatten)(data, { safe: true }));
|
|
162
|
+
}
|
|
163
|
+
map(data) {
|
|
164
|
+
let obj = Object.assign({}, data);
|
|
165
|
+
for (const [attribute, actions] of Object.entries(this.options.beforeMap)) {
|
|
166
|
+
for (const action of actions) {
|
|
167
|
+
if (action === "fromArray") {
|
|
168
|
+
obj[attribute] = (obj[attribute] || []).join("|");
|
|
169
|
+
}
|
|
170
|
+
else if (action === "toString") {
|
|
171
|
+
obj[attribute] = String(obj[attribute]);
|
|
172
|
+
}
|
|
173
|
+
else if (action === "toJson") {
|
|
174
|
+
obj[attribute] = JSON.stringify(obj[attribute]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
obj = Object.entries(obj).reduce((acc, [key, value]) => {
|
|
179
|
+
acc[this.mapObj[key]] = (0, lodash_1.isArray)(value) ? value.join("|") : value;
|
|
180
|
+
return acc;
|
|
181
|
+
}, {});
|
|
182
|
+
return obj;
|
|
183
|
+
}
|
|
184
|
+
unmap(data) {
|
|
185
|
+
const obj = Object.entries(data).reduce((acc, [key, value]) => {
|
|
186
|
+
acc[this.reversedMapObj[key]] = value;
|
|
187
|
+
return acc;
|
|
188
|
+
}, {});
|
|
189
|
+
for (const [attribute, actions] of Object.entries(this.options.afterUnmap)) {
|
|
190
|
+
for (const action of actions) {
|
|
191
|
+
if (action === "decrypt") {
|
|
192
|
+
let content = obj[attribute];
|
|
193
|
+
content = crypto_js_1.default.AES.decrypt(content, this.s3db.passphrase);
|
|
194
|
+
content = content.toString(crypto_js_1.default.enc.Utf8);
|
|
195
|
+
obj[attribute] = content;
|
|
196
|
+
}
|
|
197
|
+
else if (action === "toArray") {
|
|
198
|
+
obj[attribute] = (obj[attribute] || "").split("|");
|
|
199
|
+
}
|
|
200
|
+
else if (action === "toNumber") {
|
|
201
|
+
obj[attribute] = Number(obj[attribute] || "");
|
|
202
|
+
}
|
|
203
|
+
else if (action === "fromJson") {
|
|
204
|
+
obj[attribute] = JSON.parse(obj[attribute]);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return obj;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Inserts a new object into the resource list.
|
|
212
|
+
* @param {Object} param
|
|
213
|
+
* @returns
|
|
214
|
+
*/
|
|
215
|
+
insert(attributes) {
|
|
216
|
+
var _a;
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
let _b = (0, flat_1.flatten)(attributes, {
|
|
219
|
+
safe: true,
|
|
220
|
+
}), { id } = _b, attrs = __rest(_b, ["id"]);
|
|
221
|
+
// validate
|
|
222
|
+
const { isValid, errors, data: validated } = this.check(attrs);
|
|
223
|
+
if (!isValid) {
|
|
224
|
+
return Promise.reject(new errors_1.S3dbInvalidResource({
|
|
225
|
+
bucket: this.s3Client.bucket,
|
|
226
|
+
resourceName: this.name,
|
|
227
|
+
attributes,
|
|
228
|
+
validation: errors,
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
if (!id && id !== 0)
|
|
232
|
+
id = (0, nanoid_1.nanoid)();
|
|
233
|
+
// save
|
|
234
|
+
yield this.s3Client.putObject({
|
|
235
|
+
key: path.join(`resource=${this.name}`, `id=${id}`),
|
|
236
|
+
body: "",
|
|
237
|
+
metadata: this.map(validated),
|
|
238
|
+
});
|
|
239
|
+
const final = Object.assign({ id }, (0, flat_1.unflatten)(validated));
|
|
240
|
+
this.emit("inserted", final);
|
|
241
|
+
this.s3db.emit("inserted", this.name, final);
|
|
242
|
+
if (this.s3Cache) {
|
|
243
|
+
yield ((_a = this.s3Cache) === null || _a === void 0 ? void 0 : _a.purge());
|
|
244
|
+
}
|
|
245
|
+
return final;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get a resource by id
|
|
250
|
+
* @param {Object} param
|
|
251
|
+
* @returns
|
|
252
|
+
*/
|
|
253
|
+
getById(id) {
|
|
254
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
255
|
+
const request = yield this.s3Client.headObject({
|
|
256
|
+
key: path.join(`resource=${this.name}`, `id=${id}`),
|
|
257
|
+
});
|
|
258
|
+
let data = this.unmap(request.Metadata);
|
|
259
|
+
data = (0, flat_1.unflatten)(data);
|
|
260
|
+
data.id = id;
|
|
261
|
+
data._length = request.ContentLength;
|
|
262
|
+
data._createdAt = request.LastModified;
|
|
263
|
+
if (request.Expiration)
|
|
264
|
+
data._expiresAt = request.Expiration;
|
|
265
|
+
this.emit("got", data);
|
|
266
|
+
this.s3db.emit("got", this.name, data);
|
|
267
|
+
return data;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Update a resource by id
|
|
272
|
+
* @param {Object} param
|
|
273
|
+
* @returns
|
|
274
|
+
*/
|
|
275
|
+
updateById(id, attributes) {
|
|
276
|
+
var _a;
|
|
277
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
278
|
+
const obj = yield this.getById(id);
|
|
279
|
+
let attrs1 = (0, flat_1.flatten)(attributes, { safe: true });
|
|
280
|
+
let attrs2 = (0, flat_1.flatten)(obj, { safe: true });
|
|
281
|
+
const attrs = (0, lodash_1.merge)(attrs2, attrs1);
|
|
282
|
+
delete attrs.id;
|
|
283
|
+
const { isValid, errors, data: validated } = this.check(attrs);
|
|
284
|
+
if (!isValid) {
|
|
285
|
+
return Promise.reject(new errors_1.S3dbInvalidResource({
|
|
286
|
+
bucket: this.s3Client.bucket,
|
|
287
|
+
resourceName: this.name,
|
|
288
|
+
attributes,
|
|
289
|
+
validation: errors,
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
|
+
if (!id && id !== 0)
|
|
293
|
+
id = (0, nanoid_1.nanoid)();
|
|
294
|
+
// save
|
|
295
|
+
yield this.s3Client.putObject({
|
|
296
|
+
key: path.join(`resource=${this.name}`, `id=${id}`),
|
|
297
|
+
body: "",
|
|
298
|
+
metadata: this.map(validated),
|
|
299
|
+
});
|
|
300
|
+
const final = Object.assign({ id }, (0, flat_1.unflatten)(validated));
|
|
301
|
+
this.emit("updated", final);
|
|
302
|
+
this.s3db.emit("updated", this.name, final);
|
|
303
|
+
if (this.s3Cache) {
|
|
304
|
+
yield ((_a = this.s3Cache) === null || _a === void 0 ? void 0 : _a.purge());
|
|
305
|
+
}
|
|
306
|
+
return final;
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Delete a resource by id
|
|
311
|
+
* @param {Object} param
|
|
312
|
+
* @returns
|
|
313
|
+
*/
|
|
314
|
+
deleteById(id) {
|
|
315
|
+
var _a;
|
|
316
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
317
|
+
const key = path.join(`resource=${this.name}`, `id=${id}`);
|
|
318
|
+
const response = yield this.s3Client.deleteObject(key);
|
|
319
|
+
this.emit("deleted", id);
|
|
320
|
+
this.s3db.emit("deleted", this.name, id);
|
|
321
|
+
if (this.s3Cache) {
|
|
322
|
+
yield ((_a = this.s3Cache) === null || _a === void 0 ? void 0 : _a.purge());
|
|
323
|
+
}
|
|
324
|
+
return response;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
*
|
|
329
|
+
*/
|
|
330
|
+
bulkInsert(objects) {
|
|
331
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
332
|
+
const { results } = yield promise_pool_1.PromisePool.for(objects)
|
|
333
|
+
.withConcurrency(this.s3db.parallelism)
|
|
334
|
+
.handleError((error, content) => __awaiter(this, void 0, void 0, function* () {
|
|
335
|
+
this.emit("error", error, content);
|
|
336
|
+
this.s3db.emit("error", this.name, error, content);
|
|
337
|
+
}))
|
|
338
|
+
.process((attributes) => __awaiter(this, void 0, void 0, function* () {
|
|
339
|
+
const result = yield this.insert(attributes);
|
|
340
|
+
return result;
|
|
341
|
+
}));
|
|
342
|
+
return results;
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
* @returns number
|
|
348
|
+
*/
|
|
349
|
+
count() {
|
|
350
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
351
|
+
if (this.s3Cache) {
|
|
352
|
+
const cached = yield this.s3Cache.get({ action: "count" });
|
|
353
|
+
if (cached)
|
|
354
|
+
return cached;
|
|
355
|
+
}
|
|
356
|
+
const count = yield this.s3Client.count({
|
|
357
|
+
prefix: `resource=${this.name}`,
|
|
358
|
+
});
|
|
359
|
+
if (this.s3Cache) {
|
|
360
|
+
yield this.s3Cache.put({ action: "count", data: count });
|
|
361
|
+
}
|
|
362
|
+
return count;
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Delete resources by a list of ids
|
|
367
|
+
* @param {Object} param
|
|
368
|
+
* @returns
|
|
369
|
+
*/
|
|
370
|
+
bulkDelete(ids) {
|
|
371
|
+
var _a;
|
|
372
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
373
|
+
let packages = (0, lodash_1.chunk)(ids.map((x) => path.join(`resource=${this.name}`, `id=${x}`)), 1000);
|
|
374
|
+
const { results } = yield promise_pool_1.PromisePool.for(packages)
|
|
375
|
+
.withConcurrency(this.s3db.parallelism)
|
|
376
|
+
.handleError((error, content) => __awaiter(this, void 0, void 0, function* () {
|
|
377
|
+
this.emit("error", error, content);
|
|
378
|
+
this.s3db.emit("error", this.name, error, content);
|
|
379
|
+
}))
|
|
380
|
+
.process((keys) => __awaiter(this, void 0, void 0, function* () {
|
|
381
|
+
const response = yield this.s3Client.deleteObjects(keys);
|
|
382
|
+
keys.forEach((key) => {
|
|
383
|
+
const id = key.split("=").pop();
|
|
384
|
+
this.emit("deleted", id);
|
|
385
|
+
this.s3db.emit("deleted", this.name, id);
|
|
386
|
+
});
|
|
387
|
+
return response;
|
|
388
|
+
}));
|
|
389
|
+
if (this.s3Cache) {
|
|
390
|
+
yield ((_a = this.s3Cache) === null || _a === void 0 ? void 0 : _a.purge());
|
|
391
|
+
}
|
|
392
|
+
return results;
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
getAllIds() {
|
|
396
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
397
|
+
if (this.s3Cache) {
|
|
398
|
+
const cached = yield this.s3Cache.get({ action: "getAllIds" });
|
|
399
|
+
if (cached)
|
|
400
|
+
return cached;
|
|
401
|
+
}
|
|
402
|
+
const keys = yield this.s3Client.getAllKeys({
|
|
403
|
+
prefix: `resource=${this.name}`,
|
|
404
|
+
});
|
|
405
|
+
const ids = keys.map((x) => x.replace(`resource=${this.name}/id=`, ""));
|
|
406
|
+
if (this.s3Cache) {
|
|
407
|
+
yield this.s3Cache.put({ action: "getAllIds", data: ids });
|
|
408
|
+
const x = yield this.s3Cache.get({ action: "getAllIds" });
|
|
409
|
+
}
|
|
410
|
+
return ids;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
deleteAll() {
|
|
414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
415
|
+
const ids = yield this.getAllIds();
|
|
416
|
+
yield this.bulkDelete(ids);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
getByIdList(ids) {
|
|
420
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
421
|
+
if (this.s3Cache) {
|
|
422
|
+
const cached = yield this.s3Cache.get({ action: "getAll" });
|
|
423
|
+
if (cached)
|
|
424
|
+
return cached;
|
|
425
|
+
}
|
|
426
|
+
const { results } = yield promise_pool_1.PromisePool.for(ids)
|
|
427
|
+
.withConcurrency(this.s3Client.parallelism)
|
|
428
|
+
.process((id) => __awaiter(this, void 0, void 0, function* () {
|
|
429
|
+
this.emit("id", id);
|
|
430
|
+
const data = yield this.getById(id);
|
|
431
|
+
this.emit("data", data);
|
|
432
|
+
return data;
|
|
433
|
+
}));
|
|
434
|
+
if (this.s3Cache) {
|
|
435
|
+
yield this.s3Cache.put({ action: "getAll", data: results });
|
|
436
|
+
}
|
|
437
|
+
return results;
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
getAll() {
|
|
441
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
442
|
+
if (this.s3Cache) {
|
|
443
|
+
const cached = yield this.s3Cache.get({ action: "getAll" });
|
|
444
|
+
if (cached)
|
|
445
|
+
return cached;
|
|
446
|
+
}
|
|
447
|
+
let ids = [];
|
|
448
|
+
let gotFromCache = false;
|
|
449
|
+
if (this.s3Cache) {
|
|
450
|
+
const cached = yield this.s3Cache.get({ action: "getAllIds" });
|
|
451
|
+
if (cached) {
|
|
452
|
+
ids = cached;
|
|
453
|
+
gotFromCache = true;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if (!gotFromCache)
|
|
457
|
+
ids = yield this.getAllIds();
|
|
458
|
+
if (ids.length === 0)
|
|
459
|
+
return [];
|
|
460
|
+
const { results } = yield promise_pool_1.PromisePool.for(ids)
|
|
461
|
+
.withConcurrency(this.s3Client.parallelism)
|
|
462
|
+
.process((id) => __awaiter(this, void 0, void 0, function* () {
|
|
463
|
+
this.emit("id", id);
|
|
464
|
+
const data = yield this.getById(id);
|
|
465
|
+
this.emit("data", data);
|
|
466
|
+
return data;
|
|
467
|
+
}));
|
|
468
|
+
if (this.s3Cache && results.length > 0) {
|
|
469
|
+
yield this.s3Cache.put({ action: "getAll", data: results });
|
|
470
|
+
const x = yield this.s3Cache.get({ action: "getAll" });
|
|
471
|
+
}
|
|
472
|
+
return results;
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
readable() {
|
|
476
|
+
const stream = new resource_ids_read_stream_class_1.default({ resource: this });
|
|
477
|
+
const transformer = new resource_ids_transformer_class_1.default({ resource: this });
|
|
478
|
+
return stream.pipe(transformer);
|
|
479
|
+
}
|
|
480
|
+
writable() {
|
|
481
|
+
const stream = new resource_write_stream_class_1.default({ resource: this });
|
|
482
|
+
return stream;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
exports.default = Resource;
|