@toa.io/extensions.storages 1.0.0-alpha.21 → 1.0.0-alpha.219

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 (91) hide show
  1. package/package.json +14 -14
  2. package/readme.md +96 -51
  3. package/schemas/annotation.cos.yaml +1 -0
  4. package/schemas/cloudinary.cos.yaml +37 -0
  5. package/schemas/fs.cos.yaml +2 -0
  6. package/schemas/s3.cos.yaml +1 -0
  7. package/schemas/tmp.cos.yaml +0 -1
  8. package/source/Entry.ts +13 -11
  9. package/source/Factory.ts +16 -9
  10. package/source/Provider.ts +22 -19
  11. package/source/Scanner.ts +58 -26
  12. package/source/Secrets.ts +6 -0
  13. package/source/Storage.test.ts +118 -274
  14. package/source/Storage.ts +62 -207
  15. package/source/deployment.ts +52 -16
  16. package/source/errors.ts +3 -0
  17. package/source/index.ts +3 -1
  18. package/source/manifest.ts +7 -6
  19. package/source/providers/Cloudinary.ts +320 -0
  20. package/source/providers/Declaration.ts +2 -1
  21. package/source/providers/FileSystem.ts +79 -25
  22. package/source/providers/S3.ts +81 -80
  23. package/source/providers/Temporary.ts +2 -3
  24. package/source/providers/Test.ts +4 -4
  25. package/source/providers/index.test.ts +102 -76
  26. package/source/providers/index.ts +10 -4
  27. package/source/schemas.ts +1 -0
  28. package/source/test/.env.example +4 -0
  29. package/source/test/arny.jpg +0 -0
  30. package/source/test/lenna.48x48.jpeg +0 -0
  31. package/source/test/plank.mp4 +0 -0
  32. package/source/test/sample.avi +0 -0
  33. package/source/test/sample.wav +0 -0
  34. package/source/test/sport.mp4 +0 -0
  35. package/source/test/util.ts +62 -12
  36. package/transpiled/Entry.d.ts +15 -11
  37. package/transpiled/Factory.js +11 -5
  38. package/transpiled/Factory.js.map +1 -1
  39. package/transpiled/Provider.d.ts +17 -16
  40. package/transpiled/Provider.js +6 -4
  41. package/transpiled/Provider.js.map +1 -1
  42. package/transpiled/Scanner.d.ts +6 -2
  43. package/transpiled/Scanner.js +49 -22
  44. package/transpiled/Scanner.js.map +1 -1
  45. package/transpiled/Secrets.d.ts +5 -0
  46. package/transpiled/Secrets.js +3 -0
  47. package/transpiled/Secrets.js.map +1 -0
  48. package/transpiled/Storage.d.ts +13 -21
  49. package/transpiled/Storage.js +52 -155
  50. package/transpiled/Storage.js.map +1 -1
  51. package/transpiled/deployment.d.ts +1 -1
  52. package/transpiled/deployment.js +43 -16
  53. package/transpiled/deployment.js.map +1 -1
  54. package/transpiled/errors.d.ts +2 -0
  55. package/transpiled/errors.js +6 -0
  56. package/transpiled/errors.js.map +1 -0
  57. package/transpiled/index.d.ts +3 -1
  58. package/transpiled/manifest.js +5 -2
  59. package/transpiled/manifest.js.map +1 -1
  60. package/transpiled/providers/Cloudinary.d.ts +51 -0
  61. package/transpiled/providers/Cloudinary.js +223 -0
  62. package/transpiled/providers/Cloudinary.js.map +1 -0
  63. package/transpiled/providers/Declaration.d.ts +3 -2
  64. package/transpiled/providers/FileSystem.d.ts +15 -7
  65. package/transpiled/providers/FileSystem.js +64 -24
  66. package/transpiled/providers/FileSystem.js.map +1 -1
  67. package/transpiled/providers/S3.d.ts +14 -14
  68. package/transpiled/providers/S3.js +62 -60
  69. package/transpiled/providers/S3.js.map +1 -1
  70. package/transpiled/providers/Temporary.d.ts +1 -2
  71. package/transpiled/providers/Temporary.js +2 -2
  72. package/transpiled/providers/Temporary.js.map +1 -1
  73. package/transpiled/providers/Test.d.ts +3 -3
  74. package/transpiled/providers/Test.js +2 -2
  75. package/transpiled/providers/Test.js.map +1 -1
  76. package/transpiled/providers/index.d.ts +7 -2
  77. package/transpiled/providers/index.js +2 -2
  78. package/transpiled/providers/index.js.map +1 -1
  79. package/transpiled/schemas.d.ts +1 -0
  80. package/transpiled/schemas.js +2 -1
  81. package/transpiled/schemas.js.map +1 -1
  82. package/transpiled/test/util.d.ts +89 -5
  83. package/transpiled/test/util.js +51 -4
  84. package/transpiled/test/util.js.map +1 -1
  85. package/transpiled/tsconfig.tsbuildinfo +1 -1
  86. package/source/providers/FileSystem.test.ts +0 -5
  87. package/source/providers/Memory.ts +0 -41
  88. package/source/providers/S3.test.ts +0 -133
  89. package/transpiled/providers/Memory.d.ts +0 -13
  90. package/transpiled/providers/Memory.js +0 -60
  91. package/transpiled/providers/Memory.js.map +0 -1
@@ -1,5 +0,0 @@
1
- import { FileSystem } from './FileSystem'
2
-
3
- it('should be ok', async () => {
4
- expect(() => new FileSystem({ path: 'path' })).not.toThrow()
5
- })
@@ -1,41 +0,0 @@
1
- import { Readable } from 'node:stream'
2
- import { join } from 'node:path'
3
- import { buffer } from 'node:stream/consumers'
4
- import * as assert from 'node:assert'
5
-
6
- import { Provider } from '../Provider'
7
-
8
- /**
9
- * In-memory provider
10
- */
11
- export class InMemory extends Provider {
12
- private readonly storage = new Map<string, Buffer>()
13
-
14
- public override async get (path: string): Promise<Readable | null> {
15
- const data = this.storage.get(path)
16
-
17
- if (data === undefined) return null
18
-
19
- return Readable.from(data)
20
- }
21
-
22
- public override async put (path: string, filename: string, stream: Readable): Promise<void> {
23
- this.storage.set(join(path, filename), await buffer(stream))
24
- }
25
-
26
- public override async delete (path: string): Promise<void> {
27
- for (const f of this.storage.keys())
28
- if (f.startsWith(path)) this.storage.delete(f)
29
- }
30
-
31
- public override async move (from: string, to: string): Promise<void> {
32
- assert.notEqual(from, to, 'Source and destination are the same')
33
-
34
- const buf = this.storage.get(from)
35
-
36
- assert.ok(buf !== undefined, `File not found: ${from}`)
37
-
38
- this.storage.set(to, buf)
39
- this.storage.delete(from)
40
- }
41
- }
@@ -1,133 +0,0 @@
1
- import { Readable } from 'node:stream'
2
- import { randomUUID } from 'node:crypto'
3
- import streamConsumers from 'node:stream/consumers'
4
- import { http, HttpResponse } from 'msw'
5
- import { setupServer } from 'msw/node'
6
-
7
- import { S3 } from './S3'
8
-
9
- /* eslint-disable @typescript-eslint/no-non-null-assertion -- jest expect is not type guard */
10
-
11
- describe('S3 storage provider', () => {
12
- let provider: S3
13
- let s3endpoint: ReturnType<typeof setupServer>
14
-
15
- const AWS_REGION = 'us-east-1'
16
-
17
- const TEST_BUCKET_NAME = 'test-bucket'
18
- const S3_ENDPOINT = `https://${TEST_BUCKET_NAME}.s3.${AWS_REGION}.amazonaws.com`
19
-
20
- beforeAll(async () => {
21
- jest.useRealTimers()
22
- s3endpoint = setupServer()
23
- s3endpoint.listen({ onUnhandledRequest: 'error' })
24
-
25
- provider = new S3({
26
- bucket: TEST_BUCKET_NAME,
27
- region: AWS_REGION
28
- }, {
29
- ACCESS_KEY_ID: 'test-key',
30
- SECRET_ACCESS_KEY: 'test-key-secret'
31
- })
32
- })
33
-
34
- afterEach(() => {
35
- s3endpoint.resetHandlers()
36
- })
37
-
38
- afterAll(() => {
39
- s3endpoint.close()
40
- })
41
-
42
- test('should be able to get file from S3 handling leading slash', async () => {
43
- const testBody = randomUUID().repeat(10)
44
-
45
- s3endpoint.use(http.get(`${S3_ENDPOINT}/some/absolute/path/filename`,
46
- () => HttpResponse.text(testBody)))
47
-
48
- const body = await provider.get('/some/absolute/path/filename')
49
-
50
- expect(body).toBeInstanceOf(Readable)
51
- expect((await streamConsumers.text(body!))).toBe(testBody)
52
- })
53
-
54
- test('should remove folder with all files', async () => {
55
- const headHandler = jest.fn().mockReturnValue(HttpResponse.xml('', { status: 404 }))
56
-
57
- const listHandler = jest.fn().mockReturnValueOnce(HttpResponse.xml(`
58
- <ListBucketResult>
59
- <NextContinuationToken>someToken</NextContinuationToken>
60
- <KeyCount>1001</KeyCount>
61
- <MaxKeys>1000</MaxKeys>
62
- <IsTruncated>true</IsTruncated>
63
- <Contents>
64
- <Key>happy_face1.jpg</Key>
65
- </Contents>
66
- </ListBucketResult>
67
- `, {
68
- status: 200
69
- })).mockReturnValueOnce(HttpResponse.xml(`
70
- <ListBucketResult>
71
- <KeyCount>1001</KeyCount>
72
- <MaxKeys>1000</MaxKeys>
73
- <Contents>
74
- <Key>happy_face2.jpg</Key>
75
- </Contents>
76
- <Contents>
77
- <Key>happy_face3.jpg</Key>
78
- </Contents>
79
- </ListBucketResult>
80
- `, {
81
- status: 200
82
- }))
83
-
84
- const deleteHandler = jest.fn().mockReturnValue(HttpResponse.xml(`
85
- <DeleteResult>
86
- <Deleted>
87
- <Key>happy_face1.jpg</Key>
88
- </Deleted>
89
- <Deleted>
90
- <Key>happy_face2.jpg</Key>
91
- </Deleted>
92
- <Deleted>
93
- <Key>happy_face3.jpg</Key>
94
- </Deleted>
95
- </DeleteResult>
96
- `, {
97
- status: 200
98
- }))
99
-
100
- s3endpoint.use(http.head(`${S3_ENDPOINT}/some/absolute/path_to_remove`,
101
- headHandler),
102
- http.get(`${S3_ENDPOINT}/`,
103
- listHandler),
104
- http.post(`${S3_ENDPOINT}/`,
105
- deleteHandler))
106
-
107
- await provider.delete('/some/absolute/path_to_remove')
108
- expect(headHandler).toHaveBeenCalledTimes(1)
109
- expect(listHandler).toHaveBeenCalledTimes(2)
110
- expect(deleteHandler).toHaveBeenCalledTimes(1)
111
- })
112
-
113
- test('should be able to upload a file to S3', async () => {
114
- const body = Readable.from('test content')
115
-
116
- const handler = jest.fn().mockReturnValue(HttpResponse.xml('', {
117
- status: 200,
118
- headers: {
119
- ETag: 'test-etag',
120
- 'x-amz-id-2': 'test_id_2',
121
- 'x-amz-request-id': 'test_request_id',
122
- Server: 'AmazonS3'
123
- }
124
- }))
125
-
126
- s3endpoint.use(http.put(`${S3_ENDPOINT}/some/absolute/path/filename`,
127
- handler))
128
-
129
- await provider.put('/some/absolute/path', 'filename', body)
130
- expect(handler).toHaveBeenCalledTimes(1)
131
- expect(body.readableEnded).toBe(true)
132
- })
133
- })
@@ -1,13 +0,0 @@
1
- /// <reference types="node" />
2
- import { Readable } from 'node:stream';
3
- import { Provider } from '../Provider';
4
- /**
5
- * In-memory provider
6
- */
7
- export declare class InMemory extends Provider {
8
- private readonly storage;
9
- get(path: string): Promise<Readable | null>;
10
- put(path: string, filename: string, stream: Readable): Promise<void>;
11
- delete(path: string): Promise<void>;
12
- move(from: string, to: string): Promise<void>;
13
- }
@@ -1,60 +0,0 @@
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
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.InMemory = void 0;
27
- const node_stream_1 = require("node:stream");
28
- const node_path_1 = require("node:path");
29
- const consumers_1 = require("node:stream/consumers");
30
- const assert = __importStar(require("node:assert"));
31
- const Provider_1 = require("../Provider");
32
- /**
33
- * In-memory provider
34
- */
35
- class InMemory extends Provider_1.Provider {
36
- storage = new Map();
37
- async get(path) {
38
- const data = this.storage.get(path);
39
- if (data === undefined)
40
- return null;
41
- return node_stream_1.Readable.from(data);
42
- }
43
- async put(path, filename, stream) {
44
- this.storage.set((0, node_path_1.join)(path, filename), await (0, consumers_1.buffer)(stream));
45
- }
46
- async delete(path) {
47
- for (const f of this.storage.keys())
48
- if (f.startsWith(path))
49
- this.storage.delete(f);
50
- }
51
- async move(from, to) {
52
- assert.notEqual(from, to, 'Source and destination are the same');
53
- const buf = this.storage.get(from);
54
- assert.ok(buf !== undefined, `File not found: ${from}`);
55
- this.storage.set(to, buf);
56
- this.storage.delete(from);
57
- }
58
- }
59
- exports.InMemory = InMemory;
60
- //# sourceMappingURL=Memory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Memory.js","sourceRoot":"","sources":["../../source/providers/Memory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAsC;AACtC,yCAAgC;AAChC,qDAA8C;AAC9C,oDAAqC;AAErC,0CAAsC;AAEtC;;GAEG;AACH,MAAa,QAAS,SAAQ,mBAAQ;IACnB,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEpC,KAAK,CAAC,GAAG,CAAE,IAAY;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAEnC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAEnC,OAAO,sBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;IAEe,KAAK,CAAC,GAAG,CAAE,IAAY,EAAE,QAAgB,EAAE,MAAgB;QACzE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,gBAAI,EAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAA,kBAAM,EAAC,MAAM,CAAC,CAAC,CAAA;IAC9D,CAAC;IAEe,KAAK,CAAC,MAAM,CAAE,IAAY;QACxC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YACjC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAClD,CAAC;IAEe,KAAK,CAAC,IAAI,CAAE,IAAY,EAAE,EAAU;QAClD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,qCAAqC,CAAC,CAAA;QAEhE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAElC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,SAAS,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAA;QAEvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;CACF;AA9BD,4BA8BC"}