@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.
- package/package.json +14 -14
- package/readme.md +96 -51
- package/schemas/annotation.cos.yaml +1 -0
- package/schemas/cloudinary.cos.yaml +37 -0
- package/schemas/fs.cos.yaml +2 -0
- package/schemas/s3.cos.yaml +1 -0
- package/schemas/tmp.cos.yaml +0 -1
- package/source/Entry.ts +13 -11
- package/source/Factory.ts +16 -9
- package/source/Provider.ts +22 -19
- package/source/Scanner.ts +58 -26
- package/source/Secrets.ts +6 -0
- package/source/Storage.test.ts +118 -274
- package/source/Storage.ts +62 -207
- package/source/deployment.ts +52 -16
- package/source/errors.ts +3 -0
- package/source/index.ts +3 -1
- package/source/manifest.ts +7 -6
- package/source/providers/Cloudinary.ts +320 -0
- package/source/providers/Declaration.ts +2 -1
- package/source/providers/FileSystem.ts +79 -25
- package/source/providers/S3.ts +81 -80
- package/source/providers/Temporary.ts +2 -3
- package/source/providers/Test.ts +4 -4
- package/source/providers/index.test.ts +102 -76
- package/source/providers/index.ts +10 -4
- package/source/schemas.ts +1 -0
- package/source/test/.env.example +4 -0
- package/source/test/arny.jpg +0 -0
- package/source/test/lenna.48x48.jpeg +0 -0
- package/source/test/plank.mp4 +0 -0
- package/source/test/sample.avi +0 -0
- package/source/test/sample.wav +0 -0
- package/source/test/sport.mp4 +0 -0
- package/source/test/util.ts +62 -12
- package/transpiled/Entry.d.ts +15 -11
- package/transpiled/Factory.js +11 -5
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Provider.d.ts +17 -16
- package/transpiled/Provider.js +6 -4
- package/transpiled/Provider.js.map +1 -1
- package/transpiled/Scanner.d.ts +6 -2
- package/transpiled/Scanner.js +49 -22
- package/transpiled/Scanner.js.map +1 -1
- package/transpiled/Secrets.d.ts +5 -0
- package/transpiled/Secrets.js +3 -0
- package/transpiled/Secrets.js.map +1 -0
- package/transpiled/Storage.d.ts +13 -21
- package/transpiled/Storage.js +52 -155
- package/transpiled/Storage.js.map +1 -1
- package/transpiled/deployment.d.ts +1 -1
- package/transpiled/deployment.js +43 -16
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/errors.d.ts +2 -0
- package/transpiled/errors.js +6 -0
- package/transpiled/errors.js.map +1 -0
- package/transpiled/index.d.ts +3 -1
- package/transpiled/manifest.js +5 -2
- package/transpiled/manifest.js.map +1 -1
- package/transpiled/providers/Cloudinary.d.ts +51 -0
- package/transpiled/providers/Cloudinary.js +223 -0
- package/transpiled/providers/Cloudinary.js.map +1 -0
- package/transpiled/providers/Declaration.d.ts +3 -2
- package/transpiled/providers/FileSystem.d.ts +15 -7
- package/transpiled/providers/FileSystem.js +64 -24
- package/transpiled/providers/FileSystem.js.map +1 -1
- package/transpiled/providers/S3.d.ts +14 -14
- package/transpiled/providers/S3.js +62 -60
- package/transpiled/providers/S3.js.map +1 -1
- package/transpiled/providers/Temporary.d.ts +1 -2
- package/transpiled/providers/Temporary.js +2 -2
- package/transpiled/providers/Temporary.js.map +1 -1
- package/transpiled/providers/Test.d.ts +3 -3
- package/transpiled/providers/Test.js +2 -2
- package/transpiled/providers/Test.js.map +1 -1
- package/transpiled/providers/index.d.ts +7 -2
- package/transpiled/providers/index.js +2 -2
- package/transpiled/providers/index.js.map +1 -1
- package/transpiled/schemas.d.ts +1 -0
- package/transpiled/schemas.js +2 -1
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/test/util.d.ts +89 -5
- package/transpiled/test/util.js +51 -4
- package/transpiled/test/util.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
- package/source/providers/FileSystem.test.ts +0 -5
- package/source/providers/Memory.ts +0 -41
- package/source/providers/S3.test.ts +0 -133
- package/transpiled/providers/Memory.d.ts +0 -13
- package/transpiled/providers/Memory.js +0 -60
- package/transpiled/providers/Memory.js.map +0 -1
package/source/Storage.test.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Readable } from 'node:stream'
|
|
2
1
|
import { randomUUID } from 'node:crypto'
|
|
3
2
|
import { buffer } from 'node:stream/consumers'
|
|
4
3
|
import { createReadStream } from 'node:fs'
|
|
@@ -6,28 +5,22 @@ import path from 'node:path'
|
|
|
6
5
|
import assert from 'node:assert'
|
|
7
6
|
import { Storage } from './Storage'
|
|
8
7
|
import { suites } from './test/util'
|
|
9
|
-
import { type Entry } from './Entry'
|
|
10
8
|
import { providers } from './providers'
|
|
11
|
-
import type {
|
|
9
|
+
import type { Entry, Metadata, Stream } from './Entry'
|
|
10
|
+
import type { Constructor } from './Provider'
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
let dir: string
|
|
12
|
+
jest.setTimeout(15_000)
|
|
15
13
|
|
|
16
14
|
const suite = suites[0]
|
|
15
|
+
const Provider: Constructor = providers[suite.provider]
|
|
16
|
+
const provider = new Provider(suite.options, suite.secrets)
|
|
17
|
+
const storage = new Storage(provider)
|
|
18
|
+
const dir = '/' + randomUUID()
|
|
17
19
|
|
|
18
20
|
beforeAll(async () => {
|
|
19
21
|
process.chdir(path.join(__dirname, 'test'))
|
|
20
22
|
})
|
|
21
23
|
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
dir = '/' + randomUUID()
|
|
24
|
-
|
|
25
|
-
const Provider: ProviderConstructor = providers[suite.provider]
|
|
26
|
-
const provider = new Provider(suite.options)
|
|
27
|
-
|
|
28
|
-
storage = new Storage(provider)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
24
|
it('should be', async () => {
|
|
32
25
|
expect(storage).toBeInstanceOf(Storage)
|
|
33
26
|
})
|
|
@@ -40,6 +33,7 @@ it('should return error if entry is not found', async () => {
|
|
|
40
33
|
})
|
|
41
34
|
|
|
42
35
|
describe('put', () => {
|
|
36
|
+
let path: string
|
|
43
37
|
let lenna: Entry
|
|
44
38
|
let startCreation: number
|
|
45
39
|
|
|
@@ -47,7 +41,10 @@ describe('put', () => {
|
|
|
47
41
|
const stream = createReadStream('lenna.png')
|
|
48
42
|
|
|
49
43
|
startCreation = Date.now()
|
|
50
|
-
lenna =
|
|
44
|
+
lenna = await storage.put(dir, stream) as Entry
|
|
45
|
+
path = `${dir}/${lenna.id}`
|
|
46
|
+
|
|
47
|
+
assert(!(lenna instanceof Error))
|
|
51
48
|
})
|
|
52
49
|
|
|
53
50
|
it('should not return error', async () => {
|
|
@@ -56,14 +53,7 @@ describe('put', () => {
|
|
|
56
53
|
|
|
57
54
|
it('should return entry id', async () => {
|
|
58
55
|
expect(lenna.id).toBeDefined()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
it('should return id as checksum', async () => {
|
|
62
|
-
const stream = createReadStream('lenna.png')
|
|
63
|
-
const dir2 = '/' + randomUUID()
|
|
64
|
-
const copy = (await storage.put(dir2, stream)) as Entry
|
|
65
|
-
|
|
66
|
-
expect(copy).toHaveProperty('id', lenna.id)
|
|
56
|
+
expect(lenna.id).toHaveLength(32)
|
|
67
57
|
})
|
|
68
58
|
|
|
69
59
|
it('should detect file type', async () => {
|
|
@@ -78,257 +68,96 @@ describe('put', () => {
|
|
|
78
68
|
expect(lenna).toMatchObject({
|
|
79
69
|
id: lenna.id,
|
|
80
70
|
type: 'image/png',
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
71
|
+
size: 473831,
|
|
72
|
+
checksum: lenna.checksum,
|
|
73
|
+
created: expect.any(String),
|
|
74
|
+
attributes: {}
|
|
75
|
+
} satisfies Entry)
|
|
84
76
|
})
|
|
85
77
|
|
|
86
|
-
it('should create
|
|
87
|
-
const entry = await storage.
|
|
78
|
+
it('should create metadata', async () => {
|
|
79
|
+
const entry = await storage.head(path) as Entry
|
|
88
80
|
|
|
89
81
|
expect(entry).toMatchObject({
|
|
90
|
-
id: lenna.id,
|
|
91
82
|
type: 'image/png',
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
size: 473831,
|
|
84
|
+
checksum: lenna.checksum,
|
|
85
|
+
created: expect.any(String),
|
|
86
|
+
attributes: {}
|
|
87
|
+
} satisfies Metadata)
|
|
95
88
|
})
|
|
96
89
|
|
|
97
90
|
it('should set timestamp', async () => {
|
|
98
|
-
const now = Date.now()
|
|
99
|
-
const entry =
|
|
100
|
-
|
|
101
|
-
expect(entry.created).toBeLessThanOrEqual(now)
|
|
102
|
-
expect(entry.created).toBeGreaterThanOrEqual(startCreation)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
describe('existing entry', () => {
|
|
106
|
-
it('should unhide existing', async () => {
|
|
107
|
-
const stream = createReadStream('lenna.png')
|
|
108
|
-
const path = `${dir}/${lenna.id}`
|
|
109
|
-
|
|
110
|
-
await storage.conceal(path)
|
|
111
|
-
await storage.put(dir, stream)
|
|
112
|
-
|
|
113
|
-
const list = await storage.list(dir)
|
|
114
|
-
|
|
115
|
-
expect(list).toContainEqual(lenna.id)
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('should preserve meta', async () => {
|
|
119
|
-
const path = `${dir}/${lenna.id}`
|
|
120
|
-
const stream = createReadStream('lenna.png')
|
|
121
|
-
|
|
122
|
-
await storage.annotate(path, 'foo', 'bar')
|
|
123
|
-
await storage.put(dir, stream)
|
|
124
|
-
|
|
125
|
-
const entry = await storage.get(path)
|
|
126
|
-
|
|
127
|
-
expect(entry).toHaveProperty('meta', expect.objectContaining({ foo: 'bar' }))
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
describe('list', () => {
|
|
133
|
-
let albert: Entry
|
|
134
|
-
let lenna: Entry
|
|
135
|
-
|
|
136
|
-
beforeEach(async () => {
|
|
137
|
-
const stream0 = createReadStream('albert.jpg')
|
|
138
|
-
const stream1 = createReadStream('lenna.png')
|
|
139
|
-
|
|
140
|
-
albert = (await storage.put(dir, stream0)) as Entry
|
|
141
|
-
lenna = (await storage.put(dir, stream1)) as Entry
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it('should list entries', async () => {
|
|
145
|
-
const list = await storage.list(dir)
|
|
146
|
-
|
|
147
|
-
expect(list).toEqual([albert.id, lenna.id])
|
|
148
|
-
})
|
|
91
|
+
const now = Date.now() + 1000 // Cloudinary has 1s resolution
|
|
92
|
+
const entry = await storage.get(path) as Stream
|
|
93
|
+
const created = new Date(entry.created).getTime()
|
|
149
94
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
expect(error).toBeUndefined()
|
|
154
|
-
|
|
155
|
-
const list = await storage.list(dir)
|
|
156
|
-
|
|
157
|
-
expect(list).toEqual([lenna.id, albert.id])
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('should return PERMUTATION_MISMATCH', async () => {
|
|
161
|
-
const cases = [
|
|
162
|
-
[lenna.id],
|
|
163
|
-
[albert.id, lenna.id, 'unknown'],
|
|
164
|
-
[lenna.id, lenna.id],
|
|
165
|
-
[lenna.id, lenna.id, albert.id]
|
|
166
|
-
]
|
|
167
|
-
|
|
168
|
-
for (const permutation of cases) {
|
|
169
|
-
const error = await storage.permute(dir, permutation)
|
|
170
|
-
|
|
171
|
-
expect(error).toBeInstanceOf(Error)
|
|
172
|
-
expect(error).toHaveProperty('code', 'PERMUTATION_MISMATCH')
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it('should exclude concealed', async () => {
|
|
177
|
-
const path = `${dir}/${lenna.id}`
|
|
178
|
-
|
|
179
|
-
await storage.conceal(path)
|
|
180
|
-
|
|
181
|
-
const entries = await storage.list(dir)
|
|
182
|
-
|
|
183
|
-
expect(entries).toEqual([albert.id])
|
|
95
|
+
expect(created).toBeLessThanOrEqual(now)
|
|
96
|
+
expect(created).toBeGreaterThanOrEqual(startCreation)
|
|
184
97
|
})
|
|
185
98
|
|
|
186
|
-
it('should
|
|
187
|
-
const path = `${dir}/${lenna.id}`
|
|
188
|
-
|
|
189
|
-
await storage.conceal(path)
|
|
190
|
-
await storage.reveal(path)
|
|
191
|
-
await storage.reveal(path) // test that no duplicates are created
|
|
192
|
-
|
|
193
|
-
const entries = await storage.list(dir)
|
|
194
|
-
|
|
195
|
-
expect(entries).toEqual([albert.id, lenna.id])
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('should return ERR_NOT_FOOUD if entry doesnt exist', async () => {
|
|
199
|
-
const path = `${dir}/oopsie`
|
|
200
|
-
|
|
201
|
-
const methods: Array<'reveal' | 'conceal'> = ['reveal', 'conceal']
|
|
202
|
-
|
|
203
|
-
for (const method of methods) {
|
|
204
|
-
const error = await storage[method](path)
|
|
205
|
-
|
|
206
|
-
expect(error).toBeInstanceOf(Error)
|
|
207
|
-
expect(error).toHaveProperty('code', 'NOT_FOUND')
|
|
208
|
-
}
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
describe('annotate', () => {
|
|
213
|
-
let lenna: Entry
|
|
214
|
-
|
|
215
|
-
beforeEach(async () => {
|
|
99
|
+
it('should store with given id', async () => {
|
|
216
100
|
const stream = createReadStream('lenna.png')
|
|
101
|
+
const id = Math.random().toString(36).slice(2)
|
|
217
102
|
|
|
218
|
-
|
|
219
|
-
})
|
|
103
|
+
const entry = await storage.put(dir, stream, { id }) as Entry
|
|
220
104
|
|
|
221
|
-
|
|
222
|
-
const path = `${dir}/${lenna.id}`
|
|
105
|
+
expect(entry.id).toBe(id)
|
|
223
106
|
|
|
224
|
-
await storage.
|
|
107
|
+
const check = await storage.head(`${dir}/${id}`)
|
|
225
108
|
|
|
226
|
-
|
|
109
|
+
if (check instanceof Error)
|
|
110
|
+
throw check
|
|
227
111
|
|
|
228
|
-
expect(
|
|
229
|
-
|
|
230
|
-
await storage.annotate(path, 'foo')
|
|
231
|
-
|
|
232
|
-
const state1 = (await storage.get(path)) as Entry
|
|
233
|
-
|
|
234
|
-
expect(state1.meta).not.toHaveProperty('foo')
|
|
112
|
+
expect(check.id).toBe(id)
|
|
235
113
|
})
|
|
236
114
|
})
|
|
237
115
|
|
|
238
|
-
describe('
|
|
116
|
+
describe('get, head', () => {
|
|
239
117
|
let lenna: Entry
|
|
118
|
+
let path: string
|
|
240
119
|
|
|
241
120
|
beforeEach(async () => {
|
|
242
121
|
const stream = createReadStream('lenna.png')
|
|
243
122
|
|
|
244
|
-
lenna =
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
it('should add variant', async () => {
|
|
248
|
-
const stream = createReadStream('sample.jpeg')
|
|
249
|
-
|
|
250
|
-
const path = `${dir}/${lenna.id}`
|
|
251
|
-
|
|
252
|
-
await storage.diversify(path, 'foo', stream)
|
|
123
|
+
lenna = await storage.put(dir, stream) as Entry
|
|
253
124
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
expect(state).toHaveProperty('variants',
|
|
257
|
-
expect.arrayContaining([{ name: 'foo', size: 73444, type: 'image/jpeg' }]))
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
it('should replace variant', async () => {
|
|
261
|
-
const stream0 = createReadStream('sample.jpeg')
|
|
262
|
-
const stream1 = createReadStream('sample.webp')
|
|
263
|
-
const path = `${dir}/${lenna.id}`
|
|
264
|
-
|
|
265
|
-
await storage.diversify(path, 'foo', stream0)
|
|
266
|
-
await storage.diversify(path, 'foo', stream1)
|
|
267
|
-
|
|
268
|
-
const state = (await storage.get(path)) as Entry
|
|
269
|
-
|
|
270
|
-
expect(state).toHaveProperty('variants',
|
|
271
|
-
expect.arrayContaining([expect.objectContaining({ name: 'foo', type: 'image/webp' })]))
|
|
272
|
-
})
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
describe('fetch', () => {
|
|
276
|
-
let lenna: Entry
|
|
277
|
-
|
|
278
|
-
beforeEach(async () => {
|
|
279
|
-
const stream = createReadStream('lenna.png')
|
|
280
|
-
|
|
281
|
-
lenna = (await storage.put(dir, stream)) as Entry
|
|
125
|
+
path = `${dir}/${lenna.id}`
|
|
282
126
|
})
|
|
283
127
|
|
|
284
|
-
it('should
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
assert.ok(stream instanceof Readable)
|
|
289
|
-
|
|
290
|
-
const stored = await buffer(stream)
|
|
128
|
+
it('should get', async () => {
|
|
129
|
+
const entry = await storage.get(path) as Stream
|
|
130
|
+
const stored = await buffer(entry.stream)
|
|
291
131
|
const buf = await buffer(createReadStream('lenna.png'))
|
|
292
132
|
|
|
293
|
-
expect(stored.compare(buf)).toBe(0)
|
|
133
|
+
expect(stored.compare(new Uint8Array(buf.buffer))).toBe(0)
|
|
294
134
|
})
|
|
295
135
|
|
|
296
|
-
it('should
|
|
297
|
-
const
|
|
298
|
-
const entry = (await storage.put(dir, stream)) as Entry
|
|
299
|
-
const stored = await storage.fetch(entry.id)
|
|
300
|
-
|
|
301
|
-
if (stored instanceof Error) throw stored
|
|
136
|
+
it('should get entry', async () => {
|
|
137
|
+
const entry = await storage.head(path) as Entry
|
|
302
138
|
|
|
303
|
-
|
|
304
|
-
const expected = await buffer(createReadStream('lenna.ascii'))
|
|
305
|
-
|
|
306
|
-
expect(buf.compare(expected)).toBe(0)
|
|
139
|
+
expect(entry.id).toBe(lenna.id)
|
|
307
140
|
})
|
|
308
141
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const buf = await buffer(stream)
|
|
313
|
-
const path = `${dir}/${lenna.id}`
|
|
314
|
-
|
|
315
|
-
await storage.diversify(path, '100x100.jpeg', Readable.from(buf))
|
|
316
|
-
|
|
317
|
-
const variant = await storage.fetch(`${path}.100x100.jpeg`)
|
|
142
|
+
if (suite.provider === 'cloudinary') {
|
|
143
|
+
it('should return cloudinary url', async () => {
|
|
144
|
+
const entry = await storage.head(`${path}.jpeg`) as Entry
|
|
318
145
|
|
|
319
|
-
|
|
146
|
+
expect(entry.attributes.url).toMatch(/^https:\/\//)
|
|
147
|
+
})
|
|
320
148
|
|
|
321
|
-
|
|
149
|
+
it('should support conditions', async () => {
|
|
150
|
+
const entry = await storage.head(`${path}.vertical.jpeg`) as Entry
|
|
322
151
|
|
|
323
|
-
|
|
324
|
-
|
|
152
|
+
expect(entry.attributes.url.includes('/if_w_gt_h/a_90/if_end/')).toBe(true)
|
|
153
|
+
})
|
|
325
154
|
|
|
326
|
-
|
|
327
|
-
|
|
155
|
+
it('should return entry id when requested with extensions', async () => {
|
|
156
|
+
const entry = await storage.head(`${path}.jpeg`) as Entry
|
|
328
157
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
158
|
+
expect(entry.id).toBe(lenna.id)
|
|
159
|
+
})
|
|
160
|
+
}
|
|
332
161
|
})
|
|
333
162
|
|
|
334
163
|
describe('delete', () => {
|
|
@@ -337,46 +166,26 @@ describe('delete', () => {
|
|
|
337
166
|
beforeEach(async () => {
|
|
338
167
|
const stream = createReadStream('lenna.png')
|
|
339
168
|
|
|
340
|
-
lenna =
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
it('should remove from the list', async () => {
|
|
344
|
-
await storage.delete(`${dir}/${lenna.id}`)
|
|
345
|
-
|
|
346
|
-
const list = await storage.list(dir)
|
|
347
|
-
|
|
348
|
-
expect(list).not.toContain(lenna.id)
|
|
169
|
+
lenna = await storage.put(dir, stream) as Entry
|
|
349
170
|
})
|
|
350
171
|
|
|
351
172
|
it('should delete entry', async () => {
|
|
352
173
|
await storage.delete(`${dir}/${lenna.id}`)
|
|
353
174
|
|
|
175
|
+
// Cloudinary needs some time to invalidate the cache
|
|
176
|
+
if (suite.provider === 'cloudinary')
|
|
177
|
+
await new Promise((resolve) => setTimeout(resolve, 10_000))
|
|
178
|
+
|
|
354
179
|
const result = await storage.get(`${dir}/${lenna.id}`)
|
|
355
180
|
|
|
356
181
|
expect(result).toBeInstanceOf(Error)
|
|
357
182
|
expect(result).toHaveProperty('code', 'NOT_FOUND')
|
|
358
183
|
})
|
|
359
184
|
|
|
360
|
-
it('should
|
|
361
|
-
const stream = createReadStream('sample.jpeg')
|
|
362
|
-
|
|
363
|
-
const path = `${dir}/${lenna.id}`
|
|
364
|
-
|
|
365
|
-
await storage.diversify(path, 'foo', stream)
|
|
366
|
-
await storage.delete(`${dir}/${lenna.id}`)
|
|
367
|
-
stream.destroy()
|
|
368
|
-
|
|
369
|
-
const variant = await storage.fetch(`${path}.foo`)
|
|
370
|
-
|
|
371
|
-
expect(variant).toBeInstanceOf(Error)
|
|
372
|
-
expect(variant).toHaveProperty('code', 'NOT_FOUND')
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
it('should throw if path is not an entry', async () => {
|
|
185
|
+
it('should not return error', async () => {
|
|
376
186
|
const result = await storage.delete(dir)
|
|
377
187
|
|
|
378
|
-
expect(result).
|
|
379
|
-
expect(result).toMatchObject({ code: 'NOT_FOUND' })
|
|
188
|
+
expect(result).toBeUndefined()
|
|
380
189
|
})
|
|
381
190
|
})
|
|
382
191
|
|
|
@@ -384,14 +193,36 @@ describe('signatures', () => {
|
|
|
384
193
|
it.each(['jpeg', 'gif', 'webp', 'heic', 'jxl', 'avif'])('should detect image/%s',
|
|
385
194
|
async (type) => {
|
|
386
195
|
const stream = createReadStream('sample.' + type)
|
|
196
|
+
const entry = await storage.put(dir, stream) as Entry
|
|
197
|
+
|
|
198
|
+
expect(entry).toHaveProperty('type', 'image/' + type)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it.each(['avi'])('should detect video/%s',
|
|
202
|
+
async (type) => {
|
|
203
|
+
const stream = createReadStream('sample.' + type)
|
|
204
|
+
const entry = await storage.put(dir, stream) as Entry
|
|
205
|
+
|
|
206
|
+
expect(entry).toHaveProperty('type', 'video/' + type)
|
|
207
|
+
})
|
|
387
208
|
|
|
209
|
+
it.each(['wav'])('should detect audio/%s',
|
|
210
|
+
async (type) => {
|
|
211
|
+
const stream = createReadStream('sample.' + type)
|
|
388
212
|
const entry = (await storage.put(dir, stream)) as Entry
|
|
389
213
|
|
|
390
|
-
expect(entry).toHaveProperty('type', '
|
|
214
|
+
expect(entry).toHaveProperty('type', 'audio/' + type)
|
|
391
215
|
})
|
|
216
|
+
|
|
217
|
+
it('should be ok with Arny', async () => {
|
|
218
|
+
const stream = createReadStream('arny.jpg')
|
|
219
|
+
const entry = (await storage.put(dir, stream)) as Entry
|
|
220
|
+
|
|
221
|
+
expect(entry).toHaveProperty('type', 'image/jpeg')
|
|
222
|
+
})
|
|
392
223
|
})
|
|
393
224
|
|
|
394
|
-
it(
|
|
225
|
+
it('should return error if type doesn\'t match', async () => {
|
|
395
226
|
const stream = createReadStream('sample.jpeg')
|
|
396
227
|
|
|
397
228
|
const result = await storage.put(dir, stream, { claim: 'image/png' })
|
|
@@ -447,27 +278,40 @@ it('should accept wildcard types', async () => {
|
|
|
447
278
|
|
|
448
279
|
it('should handle root entries', async () => {
|
|
449
280
|
const stream = createReadStream('sample.jpeg')
|
|
450
|
-
|
|
451
|
-
const result = (await storage.put('hello', stream)) as Entry
|
|
281
|
+
const result = await storage.put('/', stream) as Entry
|
|
452
282
|
|
|
453
283
|
expect(result).not.toBeInstanceOf(Error)
|
|
454
284
|
|
|
455
|
-
const stored = await storage.
|
|
285
|
+
const stored = await storage.get(result.id)
|
|
456
286
|
|
|
457
287
|
expect(stored).not.toBeInstanceOf(Error)
|
|
458
288
|
})
|
|
459
289
|
|
|
460
|
-
it('should
|
|
461
|
-
const stream = createReadStream('
|
|
462
|
-
const result =
|
|
290
|
+
it('should return error of stream size limit exceeded', async () => {
|
|
291
|
+
const stream = createReadStream('sample.jpeg')
|
|
292
|
+
const result = await storage.put(dir, stream, { limit: 1024 })
|
|
463
293
|
|
|
464
|
-
expect(result).
|
|
294
|
+
expect(result).toBeInstanceOf(Error)
|
|
295
|
+
expect(result).toHaveProperty('code', 'LIMIT_EXCEEDED')
|
|
296
|
+
})
|
|
465
297
|
|
|
466
|
-
|
|
298
|
+
if (suite.provider !== 'cloudinary')
|
|
299
|
+
it('should add origin attribute', async () => {
|
|
300
|
+
const origin = 'https://example.com/image.jpeg'
|
|
301
|
+
const stream = createReadStream('sample.jpeg')
|
|
302
|
+
const result = await storage.put('/origins', stream, { origin }) as Entry
|
|
467
303
|
|
|
468
|
-
|
|
304
|
+
assert.ok(!(result instanceof Error))
|
|
305
|
+
|
|
306
|
+
const entry = await storage.get('/origins/' + result.id)
|
|
307
|
+
|
|
308
|
+
assert.ok(!(entry instanceof Error))
|
|
309
|
+
|
|
310
|
+
expect(entry.attributes.origin).toBe(origin)
|
|
311
|
+
})
|
|
469
312
|
|
|
470
|
-
|
|
313
|
+
it('should expose path', () => {
|
|
314
|
+
const path = storage.path()
|
|
471
315
|
|
|
472
|
-
expect(
|
|
316
|
+
expect(typeof path === 'string' || path === null)
|
|
473
317
|
})
|