s3db.js 1.0.6 → 2.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.
Files changed (48) hide show
  1. package/README.md +385 -186
  2. package/build/cache/s3-cache.class.js +7 -5
  3. package/build/cache/s3-resource-cache.class.js +6 -8
  4. package/build/cache/serializers.type.js +1 -0
  5. package/build/index.js +23 -6
  6. package/build/plugins/costs.plugin.js +65 -0
  7. package/build/plugins/index.js +8 -0
  8. package/build/{plugin.interface.js → plugins/plugin.interface.js} +0 -0
  9. package/build/s3-client.class.js +52 -21
  10. package/build/{resource.interface.js → s3-database-config.interface.js} +0 -0
  11. package/build/{s3db.class.js → s3-database.class.js} +20 -15
  12. package/build/{resource.class.js → s3-resource.class.js} +73 -77
  13. package/build/{s3db-config.interface.js → s3-resource.interface.js} +0 -0
  14. package/build/stream/index.js +19 -0
  15. package/build/stream/resource-ids-read-stream.class.js +3 -1
  16. package/build/stream/resource-ids-transformer.class.js +3 -1
  17. package/build/stream/resource-write-stream.class.js +4 -2
  18. package/package.json +16 -9
  19. package/.github/workflows/pipeline.yml +0 -16
  20. package/examples/1-bulk-insert.js +0 -64
  21. package/examples/2-read-stream.js +0 -61
  22. package/examples/3-read-stream-to-csv.js +0 -57
  23. package/examples/4-read-stream-to-zip.js +0 -56
  24. package/examples/5-write-stream.js +0 -98
  25. package/examples/6-jwt-tokens.js +0 -124
  26. package/examples/concerns/index.js +0 -64
  27. package/src/cache/avro.serializer.ts +0 -12
  28. package/src/cache/json.serializer.ts +0 -4
  29. package/src/cache/s3-cache.class.ts +0 -155
  30. package/src/cache/s3-resource-cache.class.ts +0 -75
  31. package/src/cache/serializers.type.ts +0 -8
  32. package/src/errors.ts +0 -96
  33. package/src/index.ts +0 -4
  34. package/src/metadata.interface.ts +0 -4
  35. package/src/plugin.interface.ts +0 -4
  36. package/src/resource.class.ts +0 -529
  37. package/src/resource.interface.ts +0 -21
  38. package/src/s3-client.class.ts +0 -297
  39. package/src/s3db-config.interface.ts +0 -9
  40. package/src/s3db.class.ts +0 -215
  41. package/src/stream/resource-ids-read-stream.class.ts +0 -90
  42. package/src/stream/resource-ids-transformer.class.ts +0 -38
  43. package/src/stream/resource-write-stream.class.ts +0 -78
  44. package/src/validator.ts +0 -39
  45. package/tests/cache.spec.ts +0 -187
  46. package/tests/concerns/index.ts +0 -16
  47. package/tests/config.spec.ts +0 -29
  48. package/tests/resources.spec.ts +0 -197
package/README.md CHANGED
@@ -1,34 +1,49 @@
1
1
  # s3db.js
2
2
 
3
+ [![license: unlicense](https://img.shields.io/badge/license-Unlicense-blue.svg)](http://unlicense.org/) [![npm version](https://img.shields.io/npm/v/s3db.js.svg?style=flat)](https://www.npmjs.com/package/s3db.js) [![Maintainability](https://api.codeclimate.com/v1/badges/26e3dc46c42367d44f18/maintainability)](https://codeclimate.com/github/forattini-dev/s3db.js/maintainability) [![Coverage Status](https://coveralls.io/repos/github/forattini-dev/s3db.js/badge.svg?branch=main)](https://coveralls.io/github/forattini-dev/s3db.js?branch=main)
4
+
3
5
  Another way to create a cheap document-base database with an easy ORM to handle your dataset!
4
6
 
7
+ <table width="100%">
8
+ <tr>
9
+ <td>
10
+
5
11
  1. <a href="#motivation">Motivation</a>
6
- 1. <a href="#install">Install</a>
7
12
  1. <a href="#usage">Usage</a>
13
+ 1. <a href="#install">Install</a>
8
14
  1. <a href="#quick-setup">Quick Setup</a>
9
15
  1. <a href="#insights">Insights</a>
10
16
  1. <a href="#database">Database</a>
11
17
  1. <a href="#create-a-resource">Create a resource</a>
12
18
  1. <a href="#resource-methods">Resource methods</a>
13
- 1. <a href="#insert">Insert</a>
14
- 1. <a href="#bulk-insert">Bulk insert</a>
15
- 1. <a href="#get">Get</a>
16
- 1. <a href="#update">Update</a>
17
- 1. <a href="#delete">Delete</a>
19
+ 1. <a href="#insert-one">Insert one</a>
20
+ 1. <a href="#get-one">Get one</a>
21
+ 1. <a href="#update-one">Update one</a>
22
+ 1. <a href="#delete-one">Delete one</a>
18
23
  1. <a href="#count">Count</a>
19
- 1. <a href="#bulk-delete">Bulk delete</a>
20
- 1. <a href="#get-all-ids">Get all ids</a>
21
- 1. <a href="#delete-all">Delete all</a>
24
+ 1. <a href="#insert-many">Insert many</a>
25
+ 1. <a href="#get-many">Get many</a>
22
26
  1. <a href="#get-all">Get all</a>
27
+ 1. <a href="#delete-many">Delete many</a>
28
+ 1. <a href="#delete-all">Delete all</a>
29
+ 1. <a href="#list-ids">List ids</a>
23
30
  1. <a href="#resource-streams">Resource streams</a>
24
31
  1. <a href="#readable-stream">Readable stream</a>
25
32
  1. <a href="#writable-stream">Writable stream</a>
26
- 1. <a href="#events">Events</a>
27
33
  1. <a href="#s3-client">S3 Client</a>
34
+ 1. <a href="#events">Events</a>
35
+ 1. <a href="#plugins">Plugins</a>
28
36
  1. <a href="#examples">Examples</a>
29
37
  1. <a href="#cost-simulation">Cost Simulation</a>
30
38
  1. <a href="#big-example">Big Example</a>
31
39
  1. <a href="#small-example">Small example</a>
40
+ 1. <a href="#roadmap">Roadmap</a>
41
+
42
+ </td>
43
+ </tr>
44
+ </table>
45
+
46
+ ---
32
47
 
33
48
  ## Motivation
34
49
 
@@ -52,24 +67,28 @@ Check the <a href="#cost-simulation">cost simulation</a> section below for a dee
52
67
 
53
68
  Lets give it a try! :)
54
69
 
55
- ## Install
70
+ ---
71
+
72
+ ## Usage
73
+
74
+ You may check the snippets bellow or go straight to the <a href="#examples">Examples</a> section!
75
+
76
+ ### Install
56
77
 
57
78
  ```bash
58
79
  npm i s3db.js
80
+
59
81
  # or
82
+
60
83
  yarn add s3db.js
61
84
  ```
62
85
 
63
- ## Usage
64
-
65
- You may check the snippets bellow or go straight to the <a href="#examples">Examples</a> section!
66
-
67
86
  ### Quick setup
68
87
 
69
88
  Our S3db client use connection string params.
70
89
 
71
90
  ```javascript
72
- import S3db from "s3db.js";
91
+ import { S3db } from "s3db.js";
73
92
 
74
93
  const {
75
94
  AWS_BUCKET,
@@ -92,14 +111,14 @@ If you do use `dotenv` package:
92
111
  import * as dotenv from "dotenv";
93
112
  dotenv.config();
94
113
 
95
- import S3db from "s3db.js";
114
+ import { S3db } from "s3db.js";
96
115
  ```
97
116
 
98
117
  ### Insights
99
118
 
100
119
  - This implementation of ORM simulates a document repository. Due to the fact that `s3db.js` uses `aws-sdk`'s' S3 api; all requests are GET/PUT as `key=value` resources. So the best case scenario is to access like a document implementation.
101
120
 
102
- - For better use of the <a href="#cache">`cache`</a> (and listing), the best ID format is to use sequential ids with leading zeros (eq: 00001, 00002, 00003) due to S3 internal keys sorting method.
121
+ - For better use of the <a href="#cache">cache</a> and listing, the best ID format is to use sequential ids with leading zeros (eq: 00001, 00002, 00003) due to S3 internal keys sorting method. But you will need to manage this incremental ID by your own.
103
122
 
104
123
  ### Database
105
124
 
@@ -113,7 +132,7 @@ Your `s3db.js` client can be initiated with options:
113
132
  | ttl | true | (Coming soon) TTL to your cache duration in seconds | `number` | 86400 |
114
133
  | uri | false | A url as your S3 connection string | `string` | `undefined` |
115
134
 
116
- URI as a connection string:
135
+ Config example:
117
136
 
118
137
  ```javascript
119
138
  const {
@@ -124,11 +143,7 @@ const {
124
143
  } = process.env;
125
144
 
126
145
  const uri = `s3://${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}@${AWS_BUCKET}/${AWS_BUCKET_PREFIX}`;
127
- ```
128
-
129
- Config example:
130
146
 
131
- ```javascript
132
147
  const options = {
133
148
  uri,
134
149
  parallelism: 25,
@@ -136,19 +151,21 @@ const options = {
136
151
  };
137
152
  ```
138
153
 
139
- ##### s3db.connect()
154
+ #### s3db.connect()
140
155
 
141
- Interacts with the bucket to check:
156
+ This method must always be invoked before any operation take place. This will interact with AWS' S3 api and check the itens below:
142
157
 
143
- 1. If the client has access to the S3 bucket with current keys
144
- 1. If there is already a defined database at this prefix. If there is, it downloads the medatada and loads each Resource definition.
145
- 1. If there isnt any database defined in this prefix, it will generate an empty metadata file into this prefix.
158
+ 1. With current credentials:
159
+ - Check if client has access to the S3 bucket.
160
+ - Check if client has access to bucket life-cycle policies.
161
+ 1. With defined database:
162
+ - Check if there is already a database in this connection string.
163
+ - If any database is found, downloads it's medatada and loads each `Resource` definition.
164
+ - Else, it will generate an empty <a href="#metadata-file">`metadata`</a> file into this prefix and mark that this is a new database from scratch.
146
165
 
147
166
  #### Metadata file
148
167
 
149
- `s3db.js` will generate a file `s3db.json` at the defined prefix.
150
-
151
- It has this structure:
168
+ `s3db.js` will generate a file `/s3db.json` at the pre-defined prefix with this structure:
152
169
 
153
170
  ```javascript
154
171
  {
@@ -180,7 +197,7 @@ It has this structure:
180
197
  }
181
198
  ```
182
199
 
183
- #### Create a resource
200
+ ### Create a resource
184
201
 
185
202
  Resources are definitions of data collections.
186
203
 
@@ -200,13 +217,13 @@ const attributes = {
200
217
  },
201
218
  };
202
219
 
203
- await s3db.createResource({
204
- resourceName: "leads",
220
+ const resource = await s3db.createResource({
221
+ name: "leads",
205
222
  attributes,
206
223
  });
207
224
  ```
208
225
 
209
- Resources' names **cannot** prefix each other, like: `leads` and `leads-copy`! S3's api will consider both one single resource.
226
+ Resources' names **cannot** prefix each other, like: `leads` and `leads-copy`! S3's api lists keys using prefix notation, so every time you list `leads`, all keys of `leads-copy` will appear as well.
210
227
 
211
228
  ##### Attributes
212
229
 
@@ -240,11 +257,19 @@ const attributes = {
240
257
  };
241
258
  ```
242
259
 
260
+ ##### Reference:
261
+
262
+ You may just use the reference:
263
+
264
+ ```javascript
265
+ const Leads = s3db.resource("leads");
266
+ ```
267
+
243
268
  ##### Limitations:
244
269
 
245
270
  As we need to store the resource definition within a JSON file, to keep your definitions intact the best way is to use the [string-based shorthand definitions](https://github.com/icebob/fastest-validator#shorthand-definitions) in your resource definition.
246
271
 
247
- By design, in your resource definition, `s3db.js` **will not handle functions** on your attributes like default value generators, etc.
272
+ By design, the resource definition **will will strip all functions** in attributes to avoid `eval()` calls.
248
273
 
249
274
  The `fastest-validator` starts with the params below:
250
275
 
@@ -260,15 +285,9 @@ The `fastest-validator` starts with the params below:
260
285
  }
261
286
  ```
262
287
 
263
- ##### Reference:
288
+ ---
264
289
 
265
- You may just use the reference:
266
-
267
- ```javascript
268
- const Leads = s3db.resource("leads");
269
- ```
270
-
271
- ### Resources methods
290
+ ## Resources methods
272
291
 
273
292
  Consider `resource` as:
274
293
 
@@ -276,11 +295,11 @@ Consider `resource` as:
276
295
  const resource = s3db.resource("leads");
277
296
  ```
278
297
 
279
- #### Insert
298
+ ### Insert one
280
299
 
281
300
  ```javascript
282
301
  // data
283
- const data = {
302
+ const insertedData = await resource.insert({
284
303
  id: "mypersonal@email.com", // if not defined a id will be generated!
285
304
  utm: {
286
305
  source: "abc",
@@ -291,44 +310,28 @@ const data = {
291
310
  mobileNumber: "+5511234567890",
292
311
  },
293
312
  invalidAttr: "this attribute will disappear",
294
- };
313
+ });
295
314
 
296
- const insertedData = await resource.insert(data);
315
+ // {
316
+ // id: "mypersonal@email.com",
317
+ // utm: {
318
+ // source: "abc",
319
+ // },
320
+ // lead: {
321
+ // fullName: "My Complex Name",
322
+ // personalEmail: "mypersonal@email.com",
323
+ // mobileNumber: "+5511234567890",
324
+ // },
325
+ // invalidAttr: "this attribute will disappear",
326
+ // }
297
327
  ```
298
328
 
299
329
  If not defined an id attribute, `s3db.js` will use [`nanoid`](https://github.com/ai/nanoid) to generate a random unique id!
300
330
 
301
- #### Bulk insert
302
-
303
- You may bulk insert data with a friendly method.
304
-
305
- This method uses [`supercharge/promise-pool`](https://github.com/supercharge/promise-pool) to organize the parallelism of your promises.
331
+ ### Get one
306
332
 
307
333
  ```javascript
308
- const s3db = new S3db({
309
- parallelism: 10, // default
310
- });
311
- ```
312
-
313
- Bulk insert:
314
-
315
- ```javascript
316
- const objects = new Array(100).fill(0).map((v, k) => ({
317
- id: `bulk-${k}@mymail.com`,
318
- lead: {
319
- fullName: "My Test Name",
320
- personalEmail: `bulk-${k}@mymail.com`,
321
- mobileNumber: "+55 11 1234567890",
322
- },
323
- }));
324
-
325
- await resource.bulkInsert(objects);
326
- ```
327
-
328
- #### Get
329
-
330
- ```javascript
331
- const obj = await resource.getById("mypersonal@email.com");
334
+ const obj = await resource.get("mypersonal@email.com");
332
335
 
333
336
  // {
334
337
  // id: "mypersonal@email.com",
@@ -343,11 +346,12 @@ const obj = await resource.getById("mypersonal@email.com");
343
346
  // }
344
347
  ```
345
348
 
346
- #### Update
349
+ ### Update one
347
350
 
348
351
  ```javascript
349
- const obj = await resource.updateById("mypersonal@email.com", {
352
+ const obj = await resource.update("mypersonal@email.com", {
350
353
  lead: {
354
+ fullName: "My New Name",
351
355
  mobileNumber: "+5511999999999",
352
356
  },
353
357
  });
@@ -358,20 +362,20 @@ const obj = await resource.updateById("mypersonal@email.com", {
358
362
  // source: "abc",
359
363
  // },
360
364
  // lead: {
361
- // fullName: "My Complex Name",
365
+ // fullName: "My New Name",
362
366
  // personalEmail: "mypersonal@email.com",
363
367
  // mobileNumber: "+5511999999999",
364
368
  // },
365
369
  // }
366
370
  ```
367
371
 
368
- #### Delete
372
+ ### Delete one
369
373
 
370
374
  ```javascript
371
- await resource.deleteById(id);
375
+ await resource.delete(id);
372
376
  ```
373
377
 
374
- #### Count
378
+ ### Count
375
379
 
376
380
  ```javascript
377
381
  await resource.count();
@@ -379,38 +383,88 @@ await resource.count();
379
383
  // 101
380
384
  ```
381
385
 
382
- #### Bulk Delete
386
+ ### Insert many
387
+
388
+ You may bulk insert data with a friendly method that receives a list of objects.
389
+
390
+ ```javascript
391
+ const objects = new Array(100).fill(0).map((v, k) => ({
392
+ id: `bulk-${k}@mymail.com`,
393
+ lead: {
394
+ fullName: "My Test Name",
395
+ personalEmail: `bulk-${k}@mymail.com`,
396
+ mobileNumber: "+55 11 1234567890",
397
+ },
398
+ }));
399
+
400
+ await resource.insertMany(objects);
401
+ ```
402
+
403
+ Keep in mind that we need to send a request to each object to be created. There is an option to change the amount of simultaneos connections that your client will handle.
383
404
 
384
405
  ```javascript
385
- await resource.bulkDelete(["id1", "id2", "id3 "]);
406
+ const s3db = new S3db({
407
+ parallelism: 100, // default = 10
408
+ });
386
409
  ```
387
410
 
388
- #### Get all Ids
411
+ This method uses [`supercharge/promise-pool`](https://github.com/supercharge/promise-pool) to organize the parallel promises.
412
+
413
+ ### Get many
389
414
 
390
415
  ```javascript
391
- const ids = await resource.getAllIds();
416
+ await resource.getMany(["id1", "id2", "id3 "]);
417
+
392
418
  // [
393
- // 'id1',
394
- // 'id2',
395
- // 'id3',
419
+ // obj1,
420
+ // obj2,
421
+ // obj3,
422
+ // ]
423
+ ```
424
+
425
+ ### Get all
426
+
427
+ ```javascript
428
+ const data = await resource.getAll();
429
+
430
+ // [
431
+ // obj1,
432
+ // obj2,
433
+ // ...
396
434
  // ]
397
435
  ```
398
436
 
399
- #### Delete all
437
+ ### Delete many
438
+
439
+ ```javascript
440
+ await resource.deleteMany(["id1", "id2", "id3 "]);
441
+ ```
442
+
443
+ ### Delete all
400
444
 
401
445
  ```javascript
402
446
  await resource.deleteAll();
403
447
  ```
404
448
 
405
- #### Get all
449
+ ### List ids
406
450
 
407
451
  ```javascript
408
- const data = await resource.getAll();
452
+ const ids = await resource.listIds();
453
+
454
+ // [
455
+ // 'id1',
456
+ // 'id2',
457
+ // 'id3',
458
+ // ]
409
459
  ```
410
460
 
411
- ### Resource streams
461
+ ---
412
462
 
413
- #### Readable stream
463
+ ## Resource streams
464
+
465
+ As we need to request the metadata for each id to return it's attributes, a better way to handle a huge amount off data might be using streams.
466
+
467
+ ### Readable stream
414
468
 
415
469
  ```javascript
416
470
  const readableStream = await resource.readable();
@@ -420,7 +474,7 @@ readableStream.on("data", (lead) => console.log("lead.id =", lead.id));
420
474
  readableStream.on("end", console.log("end"));
421
475
  ```
422
476
 
423
- #### Writable stream
477
+ ### Writable stream
424
478
 
425
479
  ```javascript
426
480
  const writableStream = await resource.writable();
@@ -434,178 +488,317 @@ writableStream.write({
434
488
  });
435
489
  ```
436
490
 
437
- ### Events
491
+ ---
492
+
493
+ ## S3 Client
494
+
495
+ `s3db.js` has a S3 proxied client named [`S3Client`](https://github.com/forattini-dev/s3db.js/blob/main/src/s3-client.class.ts). It brings a few handy and less verbose functions to deal with AWS S3's api.
496
+
497
+ ```javascript
498
+ import { S3Client } from "s3db.js";
438
499
 
439
- 1. s3db
440
- - connected
441
- - resource.created
442
- - resource.inserted
443
- - resource.deleted
444
- - error
445
- 1. client
446
- - action
447
- - error
448
- 1. resource
449
- - id
450
- - inserted
451
- - deleted
452
- - error
453
- 1. stream
454
- - resource.id
455
- - resource.data
456
- - error
500
+ const client = new S3Client({ connectionString });
501
+ ```
457
502
 
458
- #### s3db
503
+ Each method has a **[:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) link** to the official `aws-sdk` docs.
459
504
 
460
- ##### connected
505
+ ##### getObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property)
461
506
 
462
507
  ```javascript
463
- s3db.on("connected", () => console.log("s3db connected"));
508
+ const { Body, Metadata } = await client.getObject({
509
+ key: `my-prefixed-file.csv`,
510
+ });
511
+
512
+ // AWS.Response
464
513
  ```
465
514
 
466
- ##### resource.created
515
+ ##### putObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property)
467
516
 
468
517
  ```javascript
469
- s3db.on("resource.created", (resourceName) =>
470
- console.log(`resource ${resourceName} created`)
471
- );
518
+ const response = await client.putObject({
519
+ key: `my-prefixed-file.csv`,
520
+ contentType: "text/csv",
521
+ metadata: { a: "1", b: "2", c: "3" },
522
+ body: "a;b;c\n1;2;3\n4;5;6",
523
+ });
524
+
525
+ // AWS.Response
472
526
  ```
473
527
 
474
- ##### resource.inserted
528
+ ##### headObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#headObject-property)
475
529
 
476
530
  ```javascript
477
- s3db.on("resource.inserted", (resourceName, data) =>
478
- console.log(`inserted ${resourceName}.id=${data.id}`)
479
- );
531
+ const { Metadata } = await client.headObject({
532
+ key: `my-prefixed-file.csv`,
533
+ });
534
+
535
+ // AWS.Response
536
+ ```
537
+
538
+ ##### deleteObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property)
539
+
540
+ ```javascript
541
+ const response = await client.deleteObject({
542
+ key: `my-prefixed-file.csv`,
543
+ });
544
+
545
+ // AWS.Response
546
+ ```
547
+
548
+ ##### deleteObjects [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObjects-property)
549
+
550
+ ```javascript
551
+ const response = await client.deleteObjects({
552
+ keys: [`my-prefixed-file.csv`, `my-other-prefixed-file.csv`],
553
+ });
554
+
555
+ // AWS.Response
556
+ ```
557
+
558
+ ##### listObjects [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#listObjects-property)
559
+
560
+ ```javascript
561
+ const response = await client.listObjects({
562
+ prefix: `my-subdir`,
563
+ });
564
+
565
+ // AWS.Response
566
+ ```
567
+
568
+ ##### count
569
+
570
+ Custom made method to make it easier to count keys within a listObjects loop.
571
+
572
+ ```javascript
573
+ const count = await client.count({
574
+ prefix: `my-subdir`,
575
+ });
576
+
577
+ // 10
480
578
  ```
481
579
 
482
- ##### resource.deleted
580
+ ##### getAllKeys
581
+
582
+ Custom made method to make it easier to return all keys in a subpath within a listObjects loop.
583
+
584
+ All returned keys will have the it's fullpath replaced with the current "scope" path.
483
585
 
484
586
  ```javascript
485
- s3db.on("resource.deleted", (resourceName, data) =>
486
- console.log(`deleted ${resourceName}.id=${data.id}`)
487
- );
587
+ const keys = await client.getAllKeys({
588
+ prefix: `my-subdir`,
589
+ });
590
+
591
+ // [
592
+ // key1,
593
+ // key2,
594
+ // ...
595
+ // ]
488
596
  ```
489
597
 
490
- ##### error
598
+ ---
599
+
600
+ ## Events
601
+
602
+ The 3 main classes `S3db`, `Resource` and `S3Client` are extensions of Javascript's `EventEmitter`.
603
+
604
+ | S3Database | S3Client | S3Resource | S3Resource Readable Stream |
605
+ | ---------- | ------------- | ---------- | -------------------------- |
606
+ | error | error | error | error |
607
+ | connected | request | insert | id |
608
+ | | response | get | data |
609
+ | | response | update | |
610
+ | | getObject | delete | |
611
+ | | putObject | count | |
612
+ | | headObject | insertMany | |
613
+ | | deleteObject | deleteAll | |
614
+ | | deleteObjects | listIds | |
615
+ | | listObjects | getMany | |
616
+ | | count | getAll | |
617
+ | | getAllKeys | | |
618
+
619
+ ### S3Database
620
+
621
+ #### error
491
622
 
492
623
  ```javascript
493
624
  s3db.on("error", (error) => console.error(error));
494
625
  ```
495
626
 
496
- #### s3Client
627
+ #### connected
628
+
629
+ ```javascript
630
+ s3db.on("connected", () => {});
631
+ ```
632
+
633
+ ### S3Client
497
634
 
498
- ##### action
635
+ Using this reference for the events:
499
636
 
500
637
  ```javascript
501
- s3db.client.on("action", (action) =>
502
- console.log(`resource ${resourceName} created`)
503
- );
638
+ const client = s3db.client;
504
639
  ```
505
640
 
506
- ##### error
641
+ #### error
507
642
 
508
643
  ```javascript
509
- s3db.client.on("error", (error) => console.error(error));
644
+ client.on("error", (error) => console.error(error));
510
645
  ```
511
646
 
512
- #### resource
647
+ #### request
513
648
 
514
- #### on: id
649
+ Emitted when a request is generated to AWS.
515
650
 
516
651
  ```javascript
517
- const stream = s3db.resource("leads").stream();
652
+ client.on("request", (action, params) => {});
653
+ ```
654
+
655
+ #### response
656
+
657
+ Emitted when a response is received from AWS.
518
658
 
519
- stream.on("data", (id) => console.log("id = ", id));
659
+ ```javascript
660
+ client.on("response", (action, params, response) => {});
520
661
  ```
521
662
 
522
- #### on: data
663
+ #### getObject
523
664
 
524
665
  ```javascript
525
- const stream = s3db.resource("leads").stream();
666
+ client.on("getObject", (options, response) => {});
667
+ ```
526
668
 
527
- stream.on("data", (obj) => console.log("id = ", obj.id));
669
+ #### putObject
670
+
671
+ ```javascript
672
+ client.on("putObject", (options, response) => {});
528
673
  ```
529
674
 
530
- ### S3 Client
675
+ #### headObject
531
676
 
532
- `s3db.js` has a S3 proxied client named [`S3Client`](https://github.com/forattini-dev/s3db.js/blob/main/src/s3-client.class.ts). It brings a few handy and less verbose functions to deal with AWS S3's api.
677
+ ```javascript
678
+ client.on("headObject", (options, response) => {});
679
+ ```
680
+
681
+ #### deleteObject
533
682
 
534
683
  ```javascript
535
- import { S3Client } from "s3db.js/src/client";
684
+ client.on("deleteObject", (options, response) => {});
685
+ ```
536
686
 
537
- const client = new S3Client({ connectionString });
687
+ #### deleteObjects
688
+
689
+ ```javascript
690
+ client.on("deleteObjects", (options, response) => {});
538
691
  ```
539
692
 
540
- ##### s3client.getObject()
693
+ #### listObjects
541
694
 
542
695
  ```javascript
543
- const { Body, Metadata } = await client.getObject({
544
- key: `my-prefixed-file.csv`,
545
- });
696
+ client.on("listObjects", (options, response) => {});
546
697
  ```
547
698
 
548
- ##### s3client.putObject()
699
+ #### count
549
700
 
550
701
  ```javascript
551
- const response = await client.putObject({
552
- key: `my-prefixed-file.csv`,
553
- contentType: "text/csv",
554
- metadata: { a: "1", b: "2", c: "3" },
555
- body: "a;b;c\n1;2;3\n4;5;6",
556
- });
702
+ client.on("count", (options, response) => {});
557
703
  ```
558
704
 
559
- ##### s3client.headObject()
705
+ #### getAllKeys
560
706
 
561
707
  ```javascript
562
- const { Metadata } = await client.headObject({
563
- key: `my-prefixed-file.csv`,
564
- });
708
+ client.on("getAllKeys", (options, response) => {});
565
709
  ```
566
710
 
567
- ##### s3client.deleteObject()
711
+ ### S3Resource
712
+
713
+ Using this reference for the events:
568
714
 
569
715
  ```javascript
570
- const response = await client.deleteObject({
571
- key: `my-prefixed-file.csv`,
572
- });
716
+ const resource = s3db.resource("leads");
573
717
  ```
574
718
 
575
- ##### s3client.deleteObjects()
719
+ #### error
576
720
 
577
721
  ```javascript
578
- const response = await client.deleteObjects({
579
- keys: [`my-prefixed-file.csv`, `my-other-prefixed-file.csv`],
580
- });
722
+ resource.on("error", (err) => console.error(err));
581
723
  ```
582
724
 
583
- ##### s3client.listObjects()
725
+ #### insert
584
726
 
585
727
  ```javascript
586
- const response = await client.listObjects({
587
- prefix: `my-subdir`,
588
- });
728
+ resource.on("insert", (data) => {});
589
729
  ```
590
730
 
591
- ##### s3client.count()
731
+ #### get
592
732
 
593
733
  ```javascript
594
- const count = await client.count({
595
- prefix: `my-subdir`,
596
- });
734
+ resource.on("get", (data) => {});
597
735
  ```
598
736
 
599
- ##### s3client.getAllKeys()
737
+ #### update
600
738
 
601
- All keys have the fullpath replaced into the current "scope" path.
739
+ ```javascript
740
+ resource.on("update", (attrs, data) => {});
741
+ ```
742
+
743
+ #### delete
602
744
 
603
745
  ```javascript
604
- const keys = await client.getAllKeys({
605
- prefix: `my-subdir`,
606
- });
746
+ resource.on("delete", (id) => {});
747
+ ```
748
+
749
+ #### count
750
+
751
+ ```javascript
752
+ resource.on("count", (count) => {});
753
+ ```
754
+
755
+ #### insertMany
756
+
757
+ ```javascript
758
+ resource.on("insertMany", (count) => {});
759
+ ```
760
+
761
+ #### getMany
762
+
763
+ ```javascript
764
+ resource.on("getMany", (count) => {});
765
+ ```
766
+
767
+ #### getAll
768
+
769
+ ```javascript
770
+ resource.on("getAll", (count) => {});
771
+ ```
772
+
773
+ #### deleteAll
774
+
775
+ ```javascript
776
+ resource.on("deleteAll", (count) => {});
777
+ ```
778
+
779
+ #### listIds
780
+
781
+ ```javascript
782
+ resource.on("listIds", (count) => {});
607
783
  ```
608
784
 
785
+ ---
786
+
787
+ ## Plugins
788
+
789
+ Anatomy of a plugin:
790
+
791
+ ```javascript
792
+ const MyPlugin = {
793
+ setup(s3db: S3db) {},
794
+ start() {},
795
+ };
796
+ ```
797
+
798
+ We have an example of a _costs simulator plugin_ [here!](https://github.com/forattini-dev/s3db.js/blob/main/src/plugins/costs.plugin.js)
799
+
800
+ ---
801
+
609
802
  ## Examples
610
803
 
611
804
  The processing power here was not the priority, just used my little nodebook Dell XPS. Check the `./examples` directory to get some ideas on how to use this package and the code of the examples below.
@@ -784,7 +977,7 @@ Lets save some JWT tokens using the [RFC:7519](https://www.rfc-editor.org/rfc/rf
784
977
 
785
978
  ```javascript
786
979
  await s3db.createResource({
787
- resourceName: "tokens",
980
+ name: "tokens",
788
981
  attributes: {
789
982
  iss: 'url|max:256',
790
983
  sub: 'string',
@@ -818,3 +1011,9 @@ function validateToken (token) {
818
1011
  return resource.getById(id)
819
1012
  }
820
1013
  ```
1014
+
1015
+ ## Roadmap
1016
+
1017
+ Tasks board can be found at [this link](https://github.com/orgs/forattini-dev/projects/5/views/1)!
1018
+
1019
+ Feel free to interact and PRs are welcome! :)