Skip to content

Commit 7053f03

Browse files
committed
Implemented GET method to service and added badges to README. Close #2
1 parent 8da5ad6 commit 7053f03

File tree

7 files changed

+108
-63
lines changed

7 files changed

+108
-63
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# filesrocket-amazons3
22

3-
[Filesrocket](https://github.com/filesrocket/filesrocket) service to manage your files with [Amazon S3](https://aws.amazon.com/s3) services.
3+
[![npm version](https://badge.fury.io/js/filesrocket-amazons3.svg)](https://badge.fury.io/js/filesrocket-amazons3) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
4+
5+
[**Filesrocket**](https://github.com/filesrocket/filesrocket) service to manage your files with [**Amazon S3**](https://aws.amazon.com/s3)
46

57
## Install
68

@@ -22,7 +24,7 @@ const filesrocket = new Filesrocket();
2224
// Setting service
2325
const amazons3 = new AmazonS3FileService({
2426
Pagination: { default: 15, max: 50 },
25-
Bucket: "filesrocket",
27+
Bucket: "<Your Bucket>",
2628
region: "<Your Region>",
2729
credentials: {
2830
accessKeyId: "<Your ACCESS_KEY>",

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "filesrocket-amazons3",
3-
"version": "0.0.3",
4-
"description": "Filerocket service to manage files from Amazon Storage S3 service",
3+
"version": "0.0.4",
4+
"description": "Filerocket service to manage files from Amazon Storage S3",
55
"main": "lib/index.js",
66
"types": "lib",
77
"author": {
@@ -18,9 +18,9 @@
1818
"lib": "lib"
1919
},
2020
"files": [
21-
"LICENCE",
21+
"lib/**",
2222
"README.md",
23-
"lib/**"
23+
"LICENCE"
2424
],
2525
"keywords": [
2626
"upload",
@@ -32,15 +32,15 @@
3232
],
3333
"license": "MIT",
3434
"scripts": {
35-
"build": "npm run test && npm run lint && tsc -p .",
35+
"build": "npm run lint && npm run test && tsc -p .",
3636
"lint": "eslint . --ext .ts",
3737
"lint:fix": "eslint --fix . --ext .ts",
3838
"test": "jest",
3939
"test:w": "npm run test -- --watch"
4040
},
4141
"dependencies": {
4242
"aws-sdk": "2.1012.0",
43-
"filesrocket": "^0.0.4"
43+
"filesrocket": "^0.0.6"
4444
},
4545
"devDependencies": {
4646
"@types/jest": "^27.0.3",

src/services/file.service.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,47 @@ export class FileService extends BaseAmazonRocket implements ServiceMethods {
6565
.promise()
6666

6767
data.Contents = data.Contents?.map((item) => {
68-
const Bucket = query.Bucket || this.options.Bucket
6968
const Key = item.Key
7069
return this.builder(item, { Bucket, Key }) as any
7170
})
7271

7372
return this.paginate(data)
7473
}
7574

76-
async remove (id: string, query: Query = {}): Promise<OutputEntity> {
77-
const data = await this.list({ path: id })
75+
async get (id: string, query: Query = {}): Promise<OutputEntity> {
76+
const partialQuery = omitProps(query, ['path'])
77+
78+
const Bucket = query.Bucket || this.options.Bucket
7879

79-
if (!data.items.length) {
80-
throw new NotFound('File does not exist')
80+
const payload = {
81+
...partialQuery,
82+
Prefix: id,
83+
Bucket
8184
}
8285

86+
const { Contents = [] } = await this.s3
87+
.listObjectsV2(payload)
88+
.promise()
89+
90+
const items = Contents.map(item => {
91+
const Key = item.Key
92+
return this.builder(item, { Bucket, Key })
93+
})
94+
95+
const file = items.at(0)
96+
97+
if (!file) throw new NotFound('File does not exist')
98+
99+
return file
100+
}
101+
102+
async remove (id: string, query: Query = {}): Promise<OutputEntity> {
103+
const file = await this.get(id, query)
104+
83105
const Bucket = query.Bucket || this.options.Bucket
84-
const file = data.items[0]
106+
const payload = { ...query, Bucket, Key: id }
85107

86-
await this.s3.deleteObject({ ...query, Bucket, Key: id }).promise()
108+
await this.s3.deleteObject(payload).promise()
87109

88110
return file
89111
}

test/file.service.spec.ts

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { Paginated, OutputEntity } from 'filesrocket'
22
import { resolve } from 'path'
33

44
import {
5-
uploadFile,
6-
uploadManyFiles,
7-
getFiles,
8-
deleteOneFile,
9-
deleteManyFiles
5+
uploadOne,
6+
uploadMany,
7+
findOne,
8+
find,
9+
remove
1010
} from './helpers/file.helper'
1111

1212
jest.mock('filesrocket')
@@ -34,59 +34,81 @@ describe('Uploading files', () => {
3434
const path: string = `test/fixtures/${name}`
3535

3636
test('Upload many files', async () => {
37-
const results = await uploadManyFiles(paths)
37+
const results = await uploadMany(paths)
3838
expect(results).toHaveLength(paths.length)
3939
})
4040

4141
test('Upload single file', async () => {
42-
const entity = await uploadFile(path)
42+
const entity = await uploadOne(path)
4343
expect(typeof entity).toBe('object')
4444
expect(entity.name).toBe(name)
4545
})
4646

4747
test('Upload many files in a directory', async () => {
48-
const items = await uploadManyFiles(paths, { path: DIRECTORY_NAME })
48+
const items = await uploadMany(paths, { path: DIRECTORY_NAME })
4949
expect(items).toHaveLength(FILESNAMES.length)
5050
})
5151
})
5252

5353
describe('Getting files', () => {
5454
test('Gets 3 files', async () => {
5555
const SIZE: number = 3
56-
const data: Paginated<OutputEntity> = await getFiles({ size: SIZE })
56+
57+
const data: Paginated<OutputEntity> = await find({ size: SIZE })
58+
5759
expect(data.items).toHaveLength(SIZE)
5860
})
5961

6062
test('Get files from a directory', async () => {
61-
const data = await getFiles({ path: DIRECTORY_NAME })
63+
const data = await find({ path: DIRECTORY_NAME })
64+
6265
expect(data.items).toHaveLength(FILESNAMES.length)
6366
})
67+
68+
test('Get one file', async () => {
69+
const data = await find({ size: 1 })
70+
71+
const entity = data.items.at(0)
72+
73+
const file = await findOne(entity?.id || '')
74+
75+
expect(file).toBeTruthy()
76+
expect(file.name).toBe(entity?.name)
77+
})
78+
79+
test('Get file does not exist', async () => {
80+
await expect(findOne('random.jpg'))
81+
.rejects
82+
.toThrowError('File does not exist')
83+
})
6484
})
6585

6686
describe('Deleting files', () => {
6787
test('Delete 1 file', async () => {
68-
const data: Paginated<OutputEntity> = await getFiles({ size: 1 })
88+
const data: Paginated<OutputEntity> = await find({ size: 1 })
6989
const file: OutputEntity = data.items[0]
7090

71-
const entity: OutputEntity = await deleteOneFile(file.id)
72-
expect(file.name).toBe(entity.name)
73-
})
91+
const entities: OutputEntity[] = await remove([file.id])
92+
const entity = entities.at(0)
7493

75-
test('Delete many files', async () => {
76-
const data = await getFiles()
77-
78-
const keys: string[] = data.items.map(item => item.id)
79-
const items = await deleteManyFiles(keys)
80-
81-
expect(items).toHaveLength(data.items.length)
94+
expect(file.name).toBe(entity?.name)
8295
})
8396

8497
test('Delete files from a directory', async () => {
85-
const data = await getFiles({ path: DIRECTORY_NAME })
98+
const data = await find({ path: DIRECTORY_NAME })
8699

87100
const keys: string[] = data.items.map(item => item.Key)
88-
const items = await deleteManyFiles(keys)
101+
const items = await remove(keys)
89102

90103
expect(items).toHaveLength(keys.length)
91104
})
105+
106+
test('Delete many files', async () => {
107+
const data = await find()
108+
109+
const keys: string[] = data.items.map(item => item.id)
110+
const items = await remove(keys)
111+
112+
expect(items).toHaveLength(data.items.length)
113+
})
92114
})

test/helpers/file.helper.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { parse } from 'path'
44

55
import service from '../config/amazon'
66

7-
export async function uploadFile (
7+
export async function uploadOne (
88
path: string,
99
query: Query = {}
1010
): Promise<Partial<OutputEntity>> {
@@ -21,27 +21,29 @@ export async function uploadFile (
2121
return service.create(data, query)
2222
}
2323

24-
export async function uploadManyFiles (
24+
export async function uploadMany (
2525
paths: string[],
2626
query: Query = {}
2727
): Promise<Partial<OutputEntity>[]> {
28-
return Promise.all(paths.map(path => uploadFile(path, query)))
28+
return Promise.all(
29+
paths.map(path => uploadOne(path, query))
30+
)
2931
}
3032

31-
export async function getFiles (
33+
export function findOne (id: string): Promise<OutputEntity> {
34+
return service.get(id)
35+
}
36+
37+
export async function find (
3238
query: Query = {}
3339
): Promise<Paginated<OutputEntity>> {
3440
return service.list(query)
3541
}
3642

37-
export async function deleteOneFile (
38-
key: string
39-
): Promise<OutputEntity> {
40-
return service.remove(key)
41-
}
42-
43-
export async function deleteManyFiles (
43+
export async function remove (
4444
keys: string[]
4545
): Promise<OutputEntity[]> {
46-
return Promise.all(keys.map(key => deleteOneFile(key)))
46+
return Promise.all(
47+
keys.map(key => service.remove(key))
48+
)
4749
}

tsconfig.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
"strictFunctionTypes": true, /* Ensure 'use strict' is always emitted. */
2323
"noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
2424
"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
25-
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
26-
27-
/* Experimental */
28-
"experimentalDecorators": true
25+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
2926
}
3027
}

0 commit comments

Comments
 (0)