s3db.js 1.0.7 → 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 +379 -189
  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} +69 -74
  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,8 +217,8 @@ 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
  ```
@@ -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:
264
-
265
- You may just use the reference:
288
+ ---
266
289
 
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.
306
-
307
- ```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
331
+ ### Get one
329
332
 
330
333
  ```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,31 +383,46 @@ 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.
383
389
 
384
390
  ```javascript
385
- await resource.bulkDelete(["id1", "id2", "id3 "]);
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);
386
401
  ```
387
402
 
388
- #### Get all Ids
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.
389
404
 
390
405
  ```javascript
391
- const ids = await resource.getAllIds();
392
-
393
- // [
394
- // 'id1',
395
- // 'id2',
396
- // 'id3',
397
- // ]
406
+ const s3db = new S3db({
407
+ parallelism: 100, // default = 10
408
+ });
398
409
  ```
399
410
 
400
- #### Delete all
411
+ This method uses [`supercharge/promise-pool`](https://github.com/supercharge/promise-pool) to organize the parallel promises.
412
+
413
+ ### Get many
401
414
 
402
415
  ```javascript
403
- await resource.deleteAll();
416
+ await resource.getMany(["id1", "id2", "id3 "]);
417
+
418
+ // [
419
+ // obj1,
420
+ // obj2,
421
+ // obj3,
422
+ // ]
404
423
  ```
405
424
 
406
- #### Get all
425
+ ### Get all
407
426
 
408
427
  ```javascript
409
428
  const data = await resource.getAll();
@@ -415,9 +434,37 @@ const data = await resource.getAll();
415
434
  // ]
416
435
  ```
417
436
 
418
- ### Resource streams
437
+ ### Delete many
438
+
439
+ ```javascript
440
+ await resource.deleteMany(["id1", "id2", "id3 "]);
441
+ ```
442
+
443
+ ### Delete all
444
+
445
+ ```javascript
446
+ await resource.deleteAll();
447
+ ```
448
+
449
+ ### List ids
450
+
451
+ ```javascript
452
+ const ids = await resource.listIds();
453
+
454
+ // [
455
+ // 'id1',
456
+ // 'id2',
457
+ // 'id3',
458
+ // ]
459
+ ```
460
+
461
+ ---
462
+
463
+ ## Resource streams
419
464
 
420
- #### Readable stream
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
421
468
 
422
469
  ```javascript
423
470
  const readableStream = await resource.readable();
@@ -427,7 +474,7 @@ readableStream.on("data", (lead) => console.log("lead.id =", lead.id));
427
474
  readableStream.on("end", console.log("end"));
428
475
  ```
429
476
 
430
- #### Writable stream
477
+ ### Writable stream
431
478
 
432
479
  ```javascript
433
480
  const writableStream = await resource.writable();
@@ -441,180 +488,317 @@ writableStream.write({
441
488
  });
442
489
  ```
443
490
 
444
- ### Events
491
+ ---
445
492
 
446
- The 3 main classes `S3db`, `Resource` and `S3Client` are extensions of Javascript's `EventEmitter`.
493
+ ## S3 Client
447
494
 
448
- 1. S3db
449
- - connected
450
- - resource.created
451
- - resource.inserted
452
- - resource.deleted
453
- - error
454
- 1. S3Client
455
- - action
456
- - error
457
- 1. Resource
458
- - id
459
- - inserted
460
- - deleted
461
- - error
462
- 1. stream
463
- - resource.id
464
- - resource.data
465
- - error
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";
466
499
 
467
- #### s3db
500
+ const client = new S3Client({ connectionString });
501
+ ```
468
502
 
469
- ##### connected
503
+ Each method has a **[:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) link** to the official `aws-sdk` docs.
504
+
505
+ ##### getObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property)
470
506
 
471
507
  ```javascript
472
- 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
473
513
  ```
474
514
 
475
- ##### resource.created
515
+ ##### putObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property)
476
516
 
477
517
  ```javascript
478
- s3db.on("resource.created", (resourceName) =>
479
- console.log(`resource ${resourceName} created`)
480
- );
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
481
526
  ```
482
527
 
483
- ##### resource.inserted
528
+ ##### headObject [:link:](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#headObject-property)
484
529
 
485
530
  ```javascript
486
- s3db.on("resource.inserted", (resourceName, data) =>
487
- console.log(`inserted ${resourceName}.id=${data.id}`)
488
- );
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
489
578
  ```
490
579
 
491
- ##### 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.
492
585
 
493
586
  ```javascript
494
- s3db.on("resource.deleted", (resourceName, data) =>
495
- console.log(`deleted ${resourceName}.id=${data.id}`)
496
- );
587
+ const keys = await client.getAllKeys({
588
+ prefix: `my-subdir`,
589
+ });
590
+
591
+ // [
592
+ // key1,
593
+ // key2,
594
+ // ...
595
+ // ]
497
596
  ```
498
597
 
499
- ##### 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
500
622
 
501
623
  ```javascript
502
624
  s3db.on("error", (error) => console.error(error));
503
625
  ```
504
626
 
505
- #### s3Client
627
+ #### connected
506
628
 
507
- ##### action
629
+ ```javascript
630
+ s3db.on("connected", () => {});
631
+ ```
632
+
633
+ ### S3Client
634
+
635
+ Using this reference for the events:
508
636
 
509
637
  ```javascript
510
- s3db.client.on("action", (action) =>
511
- console.log(`resource ${resourceName} created`)
512
- );
638
+ const client = s3db.client;
513
639
  ```
514
640
 
515
- ##### error
641
+ #### error
516
642
 
517
643
  ```javascript
518
- s3db.client.on("error", (error) => console.error(error));
644
+ client.on("error", (error) => console.error(error));
519
645
  ```
520
646
 
521
- #### resource
647
+ #### request
522
648
 
523
- #### on: id
649
+ Emitted when a request is generated to AWS.
524
650
 
525
651
  ```javascript
526
- const stream = s3db.resource("leads").stream();
652
+ client.on("request", (action, params) => {});
653
+ ```
654
+
655
+ #### response
527
656
 
528
- stream.on("data", (id) => console.log("id = ", id));
657
+ Emitted when a response is received from AWS.
658
+
659
+ ```javascript
660
+ client.on("response", (action, params, response) => {});
529
661
  ```
530
662
 
531
- #### on: data
663
+ #### getObject
532
664
 
533
665
  ```javascript
534
- const stream = s3db.resource("leads").stream();
666
+ client.on("getObject", (options, response) => {});
667
+ ```
668
+
669
+ #### putObject
535
670
 
536
- stream.on("data", (obj) => console.log("id = ", obj.id));
671
+ ```javascript
672
+ client.on("putObject", (options, response) => {});
537
673
  ```
538
674
 
539
- ### S3 Client
675
+ #### headObject
540
676
 
541
- `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
542
682
 
543
683
  ```javascript
544
- import { S3Client } from "s3db.js/src/client";
684
+ client.on("deleteObject", (options, response) => {});
685
+ ```
545
686
 
546
- const client = new S3Client({ connectionString });
687
+ #### deleteObjects
688
+
689
+ ```javascript
690
+ client.on("deleteObjects", (options, response) => {});
547
691
  ```
548
692
 
549
- ##### s3client.getObject()
693
+ #### listObjects
550
694
 
551
695
  ```javascript
552
- const { Body, Metadata } = await client.getObject({
553
- key: `my-prefixed-file.csv`,
554
- });
696
+ client.on("listObjects", (options, response) => {});
555
697
  ```
556
698
 
557
- ##### s3client.putObject()
699
+ #### count
558
700
 
559
701
  ```javascript
560
- const response = await client.putObject({
561
- key: `my-prefixed-file.csv`,
562
- contentType: "text/csv",
563
- metadata: { a: "1", b: "2", c: "3" },
564
- body: "a;b;c\n1;2;3\n4;5;6",
565
- });
702
+ client.on("count", (options, response) => {});
566
703
  ```
567
704
 
568
- ##### s3client.headObject()
705
+ #### getAllKeys
569
706
 
570
707
  ```javascript
571
- const { Metadata } = await client.headObject({
572
- key: `my-prefixed-file.csv`,
573
- });
708
+ client.on("getAllKeys", (options, response) => {});
574
709
  ```
575
710
 
576
- ##### s3client.deleteObject()
711
+ ### S3Resource
712
+
713
+ Using this reference for the events:
577
714
 
578
715
  ```javascript
579
- const response = await client.deleteObject({
580
- key: `my-prefixed-file.csv`,
581
- });
716
+ const resource = s3db.resource("leads");
582
717
  ```
583
718
 
584
- ##### s3client.deleteObjects()
719
+ #### error
585
720
 
586
721
  ```javascript
587
- const response = await client.deleteObjects({
588
- keys: [`my-prefixed-file.csv`, `my-other-prefixed-file.csv`],
589
- });
722
+ resource.on("error", (err) => console.error(err));
590
723
  ```
591
724
 
592
- ##### s3client.listObjects()
725
+ #### insert
593
726
 
594
727
  ```javascript
595
- const response = await client.listObjects({
596
- prefix: `my-subdir`,
597
- });
728
+ resource.on("insert", (data) => {});
598
729
  ```
599
730
 
600
- ##### s3client.count()
731
+ #### get
601
732
 
602
733
  ```javascript
603
- const count = await client.count({
604
- prefix: `my-subdir`,
605
- });
734
+ resource.on("get", (data) => {});
606
735
  ```
607
736
 
608
- ##### s3client.getAllKeys()
737
+ #### update
609
738
 
610
- All keys have the fullpath replaced into the current "scope" path.
739
+ ```javascript
740
+ resource.on("update", (attrs, data) => {});
741
+ ```
742
+
743
+ #### delete
611
744
 
612
745
  ```javascript
613
- const keys = await client.getAllKeys({
614
- prefix: `my-subdir`,
615
- });
746
+ resource.on("delete", (id) => {});
616
747
  ```
617
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) => {});
783
+ ```
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
+
618
802
  ## Examples
619
803
 
620
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.
@@ -793,7 +977,7 @@ Lets save some JWT tokens using the [RFC:7519](https://www.rfc-editor.org/rfc/rf
793
977
 
794
978
  ```javascript
795
979
  await s3db.createResource({
796
- resourceName: "tokens",
980
+ name: "tokens",
797
981
  attributes: {
798
982
  iss: 'url|max:256',
799
983
  sub: 'string',
@@ -827,3 +1011,9 @@ function validateToken (token) {
827
1011
  return resource.getById(id)
828
1012
  }
829
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! :)