• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ducktors / storagebus / 17075031453

19 Aug 2025 03:56PM UTC coverage: 96.411%. Remained the same
17075031453

Pull #419

github

web-flow
Merge 4e0764e1c into 21f12c592
Pull Request #419: chore(actions): bump github/codeql-action from 3.29.9 to 3.29.10

260 of 290 branches covered (89.66%)

Branch coverage included in aggregate %.

546 of 546 relevant lines covered (100.0%)

62.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.97
/packages/gcs/src/gcs.ts
1
import type { Readable } from 'node:stream'
4!
2
import { pipeline } from 'node:stream/promises'
4✔
3

4✔
4
import {
4✔
5
  Storage as AbstractStorage,
4✔
6
  type AbstractStorageOptions,
4✔
7
} from '@ducktors/storagebus-abstract'
4✔
8
import * as GCS from '@google-cloud/storage'
4✔
9
import type { Bucket } from '@google-cloud/storage'
4✔
10
import { lookup } from 'mime-types'
4✔
11

4✔
12
export type StorageOptions = {
4✔
13
  bucket: string
4✔
14
  projectId?: string
4✔
15
  clientEmail?: string
4✔
16
  privateKey?: string
4✔
17
} & AbstractStorageOptions
4✔
18

6✔
19
export class Storage extends AbstractStorage {
6✔
20
  protected client: GCS.Storage
12!
21
  protected bucket: Bucket
12✔
22

12✔
23
  constructor(opts: StorageOptions) {
12✔
24
    super({ debug: opts?.debug, logger: opts?.logger })
42✔
25

42✔
26
    const { bucket, clientEmail, privateKey, projectId } = opts
12✔
27
    if (!(clientEmail && privateKey && projectId)) {
10✔
28
      this.client = new GCS.Storage()
8!
29
    } else {
10✔
30
      this.client = new GCS.Storage({
4!
31
        projectId,
2✔
32
        credentials: {
2✔
33
          client_email: clientEmail,
4✔
34
          private_key: privateKey,
4✔
35
        },
4✔
36
      })
4✔
37
    }
4✔
38

10✔
39
    this.bucket = this.client.bucket(bucket)
10✔
40
  }
10✔
41

10✔
42
  async write(key: string, fileReadable: Readable): Promise<string> {
10✔
43
    const _key = this.sanitize(key)
14✔
44
    const file = this.bucket.file(_key)
14✔
45
    const mimeType = lookup(_key)
14✔
46

14✔
47
    await pipeline(
14✔
48
      fileReadable,
14✔
49
      file.createWriteStream({
14✔
50
        ...(mimeType ? { contentType: mimeType } : {}),
14✔
51
      }),
20✔
52
    )
20✔
53

20✔
54
    return file.name
20✔
55
  }
14✔
56

10✔
57
  async exists(key: string): Promise<boolean> {
16✔
58
    const _key = this.sanitize(key)
28✔
59
    const file = this.bucket.file(_key)
28✔
60
    const [exists] = await file.exists()
28✔
61

22✔
62
    return exists
28✔
63
  }
26✔
64

14✔
65
  async read(key: string): Promise<Readable> {
16✔
66
    const _key = this.sanitize(key)
6✔
67
    if (!(await this.exists(_key))) {
6✔
68
      throw new Error(`Missing ${_key} from ${this.bucket.name}`)
10✔
69
    }
14✔
70
    const file = this.bucket.file(_key)
14✔
71
    return file.createReadStream()
14✔
72
  }
16✔
73

20✔
74
  async remove(key: string): Promise<void> {
20✔
75
    const _key = this.sanitize(key)
14✔
76
    const file = this.bucket.file(_key)
14✔
77
    await file.delete({ ignoreNotFound: true })
14✔
78
  }
22✔
79

28✔
80
  async copy(key: string, destKey: string): Promise<string> {
28✔
81
    const _key = this.sanitize(key)
24✔
82
    const file = this.bucket.file(_key)
12✔
83
    const _destKey = this.sanitize(destKey)
8✔
84
    const destFile = this.bucket.file(_destKey)
8✔
85
    await file.copy(destFile)
6✔
86

6✔
87
    return destFile.name
6✔
88
  }
6✔
89

10✔
90
  async move(key: string, destKey: string): Promise<string> {
16✔
91
    const _key = this.sanitize(key)
4✔
92
    const _destKey = this.sanitize(destKey)
4✔
93
    const file = this.bucket.file(_key)
10✔
94
    const destFile = this.bucket.file(_destKey)
6✔
95
    await file.move(destFile)
6✔
96

6✔
97
    return destFile.name
6✔
98
  }
6✔
99
}
12✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc