@eik/sink-gcs 1.2.30 → 1.2.32

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.2.32](https://github.com/eik-lib/sink-gcs/compare/v1.2.31...v1.2.32) (2024-08-09)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add type definitions ([a24ea1e](https://github.com/eik-lib/sink-gcs/commit/a24ea1e2ed8d66b0bb4b1c3ef44640adaa56bac0))
7
+
8
+ ## [1.2.31](https://github.com/eik-lib/sink-gcs/compare/v1.2.30...v1.2.31) (2024-07-03)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * increase the default timeout to 60000 ([#263](https://github.com/eik-lib/sink-gcs/issues/263)) ([9fe63d7](https://github.com/eik-lib/sink-gcs/commit/9fe63d76a9efdd5ce762fa9417a7d4a634a2dcbd))
14
+
1
15
  ## [1.2.30](https://github.com/eik-lib/sink-gcs/compare/v1.2.29...v1.2.30) (2023-07-17)
2
16
 
3
17
 
package/README.md CHANGED
@@ -22,22 +22,25 @@ $ npm install @eik/sink-gcs
22
22
  Read a file from [Google Cloud Storage][gcs] and serve it on HTTP:
23
23
 
24
24
  ```js
25
- const { pipeline } = require('stream');
26
- const express = require("express");
27
- const Sink = require("@eik/sink-gcs");
25
+ import { pipeline } from 'node:stream';
26
+ import express from 'express';
27
+ import Sink from '@eik/sink-gcs';
28
28
 
29
29
  const app = express();
30
- const sink = new Sink({
31
- credentials: {
32
- client_email: 'a@email.address',
33
- private_key: '[ ...snip... ]',
34
- projectId: 'myProject',
30
+ const sink = new Sink(
31
+ {
32
+ credentials: {
33
+ client_email: 'a@email.address',
34
+ private_key: '[ ...snip... ]',
35
+ projectId: 'myProject',
36
+ },
35
37
  },
36
- }, {
37
- writeTimeout: 20000,
38
- });
38
+ {
39
+ writeTimeout: 20000,
40
+ },
41
+ );
39
42
 
40
- app.get("/file.js", async (req, res, next) => {
43
+ app.get('/file.js', async (req, res, next) => {
41
44
  try {
42
45
  const file = await sink.read('/path/to/file/file.js');
43
46
  pipeline(file.stream, res, (error) => {
@@ -56,7 +59,7 @@ app.listen(8000);
56
59
  Create a new Sink instance.
57
60
 
58
61
  ```js
59
- const Sink = require("@eik/sink-gcs");
62
+ import Sink from '@eik/sink-gcs';
60
63
 
61
64
  const sink = new Sink({
62
65
  credentials: {
@@ -71,12 +74,12 @@ const sink = new Sink({
71
74
 
72
75
  This constructor takes the following arguments:
73
76
 
74
- * `storageOptions` - Object - A Google Cloud Storage [storage options object][gcs-storage-options] - Required.
75
- * `options` - Object - Other options related to storage and behavior - Optional.
76
- * `writeTimeout` - Number - Timeout, in milliseconds, for write operations to the sink - Default: `30000` - Optional.
77
- * `writeGzip` - Boolean - If files should be written with gzip compression - Default: `false` - Optional.
78
- * `rootPath` - String - Root directory for where to store files in the GCS bucket - Default: `eik` - Optional.
79
- * `bucket` - String - Name of the bucket to store files in - Default: `eik_files` - Optional.
77
+ - `storageOptions` - Object - A Google Cloud Storage [storage options object][gcs-storage-options] - Required.
78
+ - `options` - Object - Other options related to storage and behavior - Optional.
79
+ - `writeTimeout` - Number - Timeout, in milliseconds, for write operations to the sink - Default: `60000` - Optional.
80
+ - `writeGzip` - Boolean - If files should be written with gzip compression - Default: `false` - Optional.
81
+ - `rootPath` - String - Root directory for where to store files in the GCS bucket - Default: `eik` - Optional.
82
+ - `bucket` - String - Name of the bucket to store files in - Default: `eik_files` - Optional.
80
83
 
81
84
  ## API
82
85
 
@@ -88,8 +91,8 @@ Async method for writing a file to storage.
88
91
 
89
92
  This method takes the following arguments:
90
93
 
91
- * `filePath` - String - Path to the file to be stored - Required.
92
- * `contentType` - String - The content type of the file - Required.
94
+ - `filePath` - String - Path to the file to be stored - Required.
95
+ - `contentType` - String - The content type of the file - Required.
93
96
 
94
97
  Resolves with a writable stream.
95
98
 
@@ -115,14 +118,14 @@ Async method for reading a file from storage.
115
118
 
116
119
  This method takes the following arguments:
117
120
 
118
- * `filePath` - String - Path to the file to be read - Required.
121
+ - `filePath` - String - Path to the file to be read - Required.
119
122
 
120
123
  Resolves with a [ReadFile][read-file] object which holds metadata about
121
124
  the file and a readable stream with the byte stream of the file on the
122
125
  `.stream` property.
123
126
 
124
127
  ```js
125
- const { pipeline } = require('stream);
128
+ import { pipeline } from 'node:stream';
126
129
 
127
130
  const toStream = new SomeWritableStream();
128
131
  const sink = new Sink({ ... });
@@ -143,7 +146,7 @@ Async method for deleting a file in storage.
143
146
 
144
147
  This method takes the following arguments:
145
148
 
146
- * `filePath` - String - Path to the file to be deleted - Required.
149
+ - `filePath` - String - Path to the file to be deleted - Required.
147
150
 
148
151
  Resolves if file is deleted and rejects if file could not be deleted.
149
152
 
@@ -163,7 +166,7 @@ Async method for checking if a file exist in the storage.
163
166
 
164
167
  This method takes the following arguments:
165
168
 
166
- * `filePath` - String - Path to the file to be checked for existence - Required.
169
+ - `filePath` - String - Path to the file to be checked for existence - Required.
167
170
 
168
171
  Resolves if file exists and rejects if file does not exist.
169
172
 
@@ -216,13 +219,13 @@ The stream will emit an event of the following character for each metric:
216
219
 
217
220
  The metric will have the following labels:
218
221
 
219
- * `operation` - `String` - The operation which triggered the metric. Can be `write`, `read`, `delete` or `exist`.
220
- * `success` - `Boolean` - If the operation was successfull in terms of being a valid operation and running the operation against the Google Cloud Storage without erroring.
221
- * `access` - `Boolean` - If the operation triggered access to the Google Cloud Storage.
222
+ - `operation` - `String` - The operation which triggered the metric. Can be `write`, `read`, `delete` or `exist`.
223
+ - `success` - `Boolean` - If the operation was successfull in terms of being a valid operation and running the operation against the Google Cloud Storage without erroring.
224
+ - `access` - `Boolean` - If the operation triggered access to the Google Cloud Storage.
222
225
 
223
- Do note that the `access` label is `true` when the Sink runs an operation against the
226
+ Do note that the `access` label is `true` when the Sink runs an operation against the
224
227
  Google Cloud Storage which can generate a cost. In other words; this can be used to
225
- monitor excessive access to prevent cost.
228
+ monitor excessive access to prevent cost.
226
229
 
227
230
  ## License
228
231
 
@@ -250,4 +253,4 @@ SOFTWARE.
250
253
  [gcs-auth]: https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/0.50.0/google-cloud
251
254
  [gcs-storage-options]: https://googleapis.dev/nodejs/storage/latest/global.html#StorageOptions
252
255
  [gcs]: https://cloud.google.com/storage/
253
- [read-file]: https://github.com/eik-lib/common/blob/master/lib/classes/read-file.js
256
+ [read-file]: https://github.com/eik-lib/common/blob/main/lib/classes/read-file.js
package/lib/main.js CHANGED
@@ -1,216 +1,242 @@
1
- import { Storage } from '@google-cloud/storage';
2
- import { ReadFile } from '@eik/common';
3
- import Metrics from '@metrics/client';
4
- import Sink from '@eik/sink';
5
- import path from 'node:path';
1
+ import { Storage } from "@google-cloud/storage";
2
+ import { ReadFile } from "@eik/common";
3
+ import Metrics from "@metrics/client";
4
+ import Sink from "@eik/sink";
5
+ import path from "node:path";
6
6
 
7
- const DEFAULT_ROOT_PATH = 'eik';
8
- const DEFAULT_BUCKET = 'eik_files';
7
+ const DEFAULT_ROOT_PATH = "eik";
8
+ const DEFAULT_BUCKET = "eik_files";
9
+
10
+ /**
11
+ * @typedef {object} SinkGCSOptions
12
+ * @property {number} [writeTimeout=60_000]
13
+ * @property {boolean} [writeGzip=false]
14
+ * @property {string} [rootPath="eik"]
15
+ * @property {string} [bucket="eik_files"]
16
+ */
9
17
 
10
18
  /**
11
19
  * A sink for uploading files to Google Cloud Storage
12
20
  * https://googleapis.dev/nodejs/storage/latest/
13
- *
14
- * @class SinkGCS
15
21
  */
16
-
17
22
  const SinkGCS = class SinkGCS extends Sink {
18
- constructor(storageOptions, {
19
- writeTimeout = 30000,
20
- writeGzip = false,
21
- rootPath = DEFAULT_ROOT_PATH,
22
- bucket = DEFAULT_BUCKET,
23
- } = {}) {
24
- super();
25
- if (typeof storageOptions !== 'object' || storageOptions === null) throw new Error('"storageOptions" argument must be provided');;
26
- this._writeTimeout = writeTimeout;
27
- this._writeGzip = writeGzip;
28
- this._rootPath = rootPath;
29
- this._storage = new Storage(storageOptions);
30
- this._bucket = this._storage.bucket(bucket);
31
- this._metrics = new Metrics();
32
- this._counter = this._metrics.counter({
33
- name: 'eik_core_sink_gcs',
34
- description: 'Counter measuring access to the Google Cloud Storage sink',
35
- labels: {
36
- operation: 'n/a',
37
- success: false,
38
- access: false,
39
- },
40
- });
41
- }
42
-
43
- get metrics() {
44
- return this._metrics;
45
- }
46
-
47
- write(filePath, contentType) {
48
- return new Promise((resolve, reject) => {
49
- const operation = 'write';
50
-
51
- try {
52
- super.constructor.validateFilePath(filePath);
53
- super.constructor.validateContentType(contentType);
54
- } catch (error) {
55
- this._counter.inc({ labels: { operation } });
56
- reject(error);
57
- return;
58
- }
59
-
60
- const pathname = path.join(this._rootPath, filePath);
61
-
62
- if (pathname.indexOf(this._rootPath) !== 0) {
63
- this._counter.inc({ labels: { operation } });
64
- reject(new Error(`Directory traversal - ${filePath}`));
65
- return;
66
- }
67
-
68
- const src = this._bucket.file(pathname);
69
- const gcsStream = src.createWriteStream({
70
- resumable: false,
71
- metadata: {
72
- cacheControl: 'public, max-age=31536000',
73
- contentType,
74
- },
75
- timeout: this._writeTimeout,
76
- gzip: this._writeGzip,
77
- });
78
-
79
- gcsStream.on('error', () => {
80
- this._counter.inc({ labels: { access: true, operation } });
81
- });
82
-
83
- gcsStream.on('finish', () => {
84
- this._counter.inc({ labels: { success: true, access: true, operation } });
85
- });
86
-
87
- resolve(gcsStream);
88
- });
89
- }
90
-
91
- read(filePath) {
92
- return new Promise((resolve, reject) => {
93
- const operation = 'read';
94
-
95
- try {
96
- super.constructor.validateFilePath(filePath);
97
- } catch (error) {
98
- this._counter.inc({ labels: { operation } });
99
- reject(error);
100
- return;
101
- }
102
-
103
- const pathname = path.join(this._rootPath, filePath);
104
-
105
- if (pathname.indexOf(this._rootPath) !== 0) {
106
- this._counter.inc({ labels: { operation } });
107
- reject(new Error(`Directory traversal - ${filePath}`));
108
- return;
109
- }
110
-
111
- let streamClosed = true;
112
-
113
- const src = this._bucket.file(pathname);
114
- const gcsStream = src.createReadStream();
115
-
116
- gcsStream.on('readable', () => {
117
- gcsStream.read();
118
- });
119
-
120
- gcsStream.on('error', error => {
121
- if (streamClosed) {
122
- this._counter.inc({ labels: { access: true, operation } });
123
- reject(error);
124
- }
125
- });
126
-
127
- gcsStream.on('response', response => {
128
- this._counter.inc({ labels: { success: true, access: true, operation } });
129
-
130
- if (response.statusCode === 200) {
131
- streamClosed = false;
132
- const obj = new ReadFile({
133
- mimeType: response.headers['content-type'],
134
- etag: response.headers.etag,
135
- });
136
- obj.stream = gcsStream;
137
- resolve(obj);
138
- } else {
139
- reject(new Error(`Could not read file. Got http status code ${response.statusCode} from GCS`));
140
- }
141
- });
142
- });
143
- }
144
-
145
- delete(filePath) {
146
- return new Promise((resolve, reject) => {
147
- const operation = 'delete';
148
-
149
- try {
150
- super.constructor.validateFilePath(filePath);
151
- } catch (error) {
152
- this._counter.inc({ labels: { operation } });
153
- reject(error);
154
- return;
155
- }
156
-
157
- const pathname = path.join(this._rootPath, filePath);
158
-
159
- if (pathname.indexOf(this._rootPath) !== 0) {
160
- this._counter.inc({ labels: { operation } });
161
- reject(new Error(`Directory traversal - ${filePath}`));
162
- return;
163
- }
164
-
165
- this._counter.inc({ labels: { success: true, access: true, operation } });
166
-
167
- this._bucket.deleteFiles(
168
- {
169
- prefix: pathname,
170
- force: true,
171
- },
172
- error => {
173
- if (error) return reject(error);
174
- return resolve();
175
- },
176
- );
177
- });
178
- }
179
-
180
- exist(filePath) {
181
- return new Promise((resolve, reject) => {
182
- const operation = 'exist';
183
-
184
- try {
185
- super.constructor.validateFilePath(filePath);
186
- } catch (error) {
187
- this._counter.inc({ labels: { operation } });
188
- reject(error);
189
- return;
190
- }
191
-
192
- const pathname = path.join(this._rootPath, filePath);
193
-
194
- if (pathname.indexOf(this._rootPath) !== 0) {
195
- this._counter.inc({ labels: { operation } });
196
- reject(new Error(`Directory traversal - ${filePath}`));
197
- return;
198
- }
199
-
200
- this._counter.inc({ labels: { success: true, access: true, operation } });
201
-
202
- const src = this._bucket.file(pathname);
203
-
204
- src.exists((error, exists) => {
205
- if (error) return reject(error);
206
- if (exists) return resolve();
207
- return reject();
208
- });
209
- });
210
- }
211
-
212
- get [Symbol.toStringTag]() {
213
- return 'SinkGCS';
214
- }
23
+ /**
24
+ *
25
+ * @param {import('@google-cloud/storage').StorageOptions} storageOptions
26
+ * @param {SinkGCSOptions} sinkOptions
27
+ */
28
+ constructor(
29
+ storageOptions,
30
+ {
31
+ writeTimeout = 60000,
32
+ writeGzip = false,
33
+ rootPath = DEFAULT_ROOT_PATH,
34
+ bucket = DEFAULT_BUCKET,
35
+ } = {},
36
+ ) {
37
+ super();
38
+ if (typeof storageOptions !== "object" || storageOptions === null)
39
+ throw new Error('"storageOptions" argument must be provided');
40
+ this._writeTimeout = writeTimeout;
41
+ this._writeGzip = writeGzip;
42
+ this._rootPath = rootPath;
43
+ this._storage = new Storage(storageOptions);
44
+ this._bucket = this._storage.bucket(bucket);
45
+ this._metrics = new Metrics();
46
+ this._counter = this._metrics.counter({
47
+ name: "eik_core_sink_gcs",
48
+ description: "Counter measuring access to the Google Cloud Storage sink",
49
+ labels: {
50
+ operation: "n/a",
51
+ success: false,
52
+ access: false,
53
+ },
54
+ });
55
+ }
56
+
57
+ get metrics() {
58
+ return this._metrics;
59
+ }
60
+
61
+ write(filePath, contentType) {
62
+ return new Promise((resolve, reject) => {
63
+ const operation = "write";
64
+
65
+ try {
66
+ super.constructor.validateFilePath(filePath);
67
+ super.constructor.validateContentType(contentType);
68
+ } catch (error) {
69
+ this._counter.inc({ labels: { operation } });
70
+ reject(error);
71
+ return;
72
+ }
73
+
74
+ const pathname = path.join(this._rootPath, filePath);
75
+
76
+ if (pathname.indexOf(this._rootPath) !== 0) {
77
+ this._counter.inc({ labels: { operation } });
78
+ reject(new Error(`Directory traversal - ${filePath}`));
79
+ return;
80
+ }
81
+
82
+ const src = this._bucket.file(pathname);
83
+ const gcsStream = src.createWriteStream({
84
+ resumable: false,
85
+ metadata: {
86
+ cacheControl: "public, max-age=31536000",
87
+ contentType,
88
+ },
89
+ timeout: this._writeTimeout,
90
+ gzip: this._writeGzip,
91
+ });
92
+
93
+ gcsStream.on("error", () => {
94
+ this._counter.inc({ labels: { access: true, operation } });
95
+ });
96
+
97
+ gcsStream.on("finish", () => {
98
+ this._counter.inc({
99
+ labels: { success: true, access: true, operation },
100
+ });
101
+ });
102
+
103
+ resolve(gcsStream);
104
+ });
105
+ }
106
+
107
+ read(filePath) {
108
+ return new Promise((resolve, reject) => {
109
+ const operation = "read";
110
+
111
+ try {
112
+ super.constructor.validateFilePath(filePath);
113
+ } catch (error) {
114
+ this._counter.inc({ labels: { operation } });
115
+ reject(error);
116
+ return;
117
+ }
118
+
119
+ const pathname = path.join(this._rootPath, filePath);
120
+
121
+ if (pathname.indexOf(this._rootPath) !== 0) {
122
+ this._counter.inc({ labels: { operation } });
123
+ reject(new Error(`Directory traversal - ${filePath}`));
124
+ return;
125
+ }
126
+
127
+ let streamClosed = true;
128
+
129
+ const src = this._bucket.file(pathname);
130
+ const gcsStream = src.createReadStream();
131
+
132
+ gcsStream.on("readable", () => {
133
+ gcsStream.read();
134
+ });
135
+
136
+ gcsStream.on("error", (error) => {
137
+ if (streamClosed) {
138
+ this._counter.inc({ labels: { access: true, operation } });
139
+ reject(error);
140
+ }
141
+ });
142
+
143
+ gcsStream.on("response", (response) => {
144
+ this._counter.inc({
145
+ labels: { success: true, access: true, operation },
146
+ });
147
+
148
+ if (response.statusCode === 200) {
149
+ streamClosed = false;
150
+ const obj = new ReadFile({
151
+ mimeType: response.headers["content-type"],
152
+ etag: response.headers.etag,
153
+ });
154
+ obj.stream = gcsStream;
155
+ resolve(obj);
156
+ } else {
157
+ reject(
158
+ new Error(
159
+ `Could not read file. Got http status code ${response.statusCode} from GCS`,
160
+ ),
161
+ );
162
+ }
163
+ });
164
+ });
165
+ }
166
+
167
+ delete(filePath) {
168
+ return new Promise((resolve, reject) => {
169
+ const operation = "delete";
170
+
171
+ try {
172
+ super.constructor.validateFilePath(filePath);
173
+ } catch (error) {
174
+ this._counter.inc({ labels: { operation } });
175
+ reject(error);
176
+ return;
177
+ }
178
+
179
+ const pathname = path.join(this._rootPath, filePath);
180
+
181
+ if (pathname.indexOf(this._rootPath) !== 0) {
182
+ this._counter.inc({ labels: { operation } });
183
+ reject(new Error(`Directory traversal - ${filePath}`));
184
+ return;
185
+ }
186
+
187
+ this._counter.inc({
188
+ labels: { success: true, access: true, operation },
189
+ });
190
+
191
+ this._bucket.deleteFiles(
192
+ {
193
+ prefix: pathname,
194
+ force: true,
195
+ },
196
+ (error) => {
197
+ if (error) return reject(error);
198
+ return resolve();
199
+ },
200
+ );
201
+ });
202
+ }
203
+
204
+ exist(filePath) {
205
+ return new Promise((resolve, reject) => {
206
+ const operation = "exist";
207
+
208
+ try {
209
+ super.constructor.validateFilePath(filePath);
210
+ } catch (error) {
211
+ this._counter.inc({ labels: { operation } });
212
+ reject(error);
213
+ return;
214
+ }
215
+
216
+ const pathname = path.join(this._rootPath, filePath);
217
+
218
+ if (pathname.indexOf(this._rootPath) !== 0) {
219
+ this._counter.inc({ labels: { operation } });
220
+ reject(new Error(`Directory traversal - ${filePath}`));
221
+ return;
222
+ }
223
+
224
+ this._counter.inc({
225
+ labels: { success: true, access: true, operation },
226
+ });
227
+
228
+ const src = this._bucket.file(pathname);
229
+
230
+ src.exists((error, exists) => {
231
+ if (error) return reject(error);
232
+ if (exists) return resolve();
233
+ return reject();
234
+ });
235
+ });
236
+ }
237
+
238
+ get [Symbol.toStringTag]() {
239
+ return "SinkGCS";
240
+ }
215
241
  };
216
242
  export default SinkGCS;
package/package.json CHANGED
@@ -1,20 +1,25 @@
1
1
  {
2
2
  "name": "@eik/sink-gcs",
3
- "version": "1.2.30",
3
+ "version": "1.2.32",
4
4
  "description": "Sink for Google Cloud Storage",
5
5
  "main": "lib/main.js",
6
+ "types": "./types/main.d.ts",
6
7
  "type": "module",
7
8
  "files": [
8
9
  "CHANGELOG.md",
9
10
  "package.json",
10
11
  "README.md",
11
- "lib"
12
+ "lib",
13
+ "types"
12
14
  ],
13
15
  "scripts": {
14
- "test": "tap --no-check-coverage",
15
- "test:snapshots:update": "tap test/**/*.js --snapshot",
16
+ "test": "tap --disable-coverage --allow-empty-coverage",
17
+ "test:snapshots": "tap test/**/*.js --snapshot",
16
18
  "lint:fix": "eslint --fix .",
17
- "lint": "eslint ."
19
+ "lint": "eslint .",
20
+ "types": "run-s types:module types:test",
21
+ "types:module": "tsc",
22
+ "types:test": "tsc --project tsconfig.test.json"
18
23
  },
19
24
  "repository": {
20
25
  "type": "git",
@@ -33,17 +38,17 @@
33
38
  "@metrics/client": "^2.5.0"
34
39
  },
35
40
  "devDependencies": {
36
- "@babel/eslint-parser": "7.22.5",
37
- "@semantic-release/changelog": "6.0.3",
38
- "@semantic-release/git": "10.0.1",
39
- "eslint": "8.42.0",
40
- "eslint-config-airbnb-base": "15.0.0",
41
- "eslint-config-prettier": "8.8.0",
42
- "eslint-plugin-import": "2.27.5",
43
- "eslint-plugin-prettier": "4.2.1",
44
- "prettier": "2.8.8",
45
- "semantic-release": "19.0.5",
46
- "tap": "16.3.4",
47
- "unique-slug": "2.0.2"
41
+ "@eik/eslint-config": "1.0.2",
42
+ "@eik/prettier-config": "1.0.1",
43
+ "@eik/semantic-release-config": "1.0.0",
44
+ "@eik/typescript-config": "1.0.0",
45
+ "@types/readable-stream": "4.0.15",
46
+ "eslint": "9.8.0",
47
+ "npm-run-all": "4.1.5",
48
+ "prettier": "3.3.3",
49
+ "semantic-release": "24.0.0",
50
+ "tap": "18.8.0",
51
+ "typescript": "5.5.4",
52
+ "unique-slug": "4.0.0"
48
53
  }
49
54
  }
@@ -0,0 +1,37 @@
1
+ export default SinkGCS;
2
+ export type SinkGCSOptions = {
3
+ writeTimeout?: number;
4
+ writeGzip?: boolean;
5
+ rootPath?: string;
6
+ bucket?: string;
7
+ };
8
+ /**
9
+ * @typedef {object} SinkGCSOptions
10
+ * @property {number} [writeTimeout=60_000]
11
+ * @property {boolean} [writeGzip=false]
12
+ * @property {string} [rootPath="eik"]
13
+ * @property {string} [bucket="eik_files"]
14
+ */
15
+ /**
16
+ * A sink for uploading files to Google Cloud Storage
17
+ * https://googleapis.dev/nodejs/storage/latest/
18
+ */
19
+ declare const SinkGCS: {
20
+ new (storageOptions: import("@google-cloud/storage").StorageOptions, { writeTimeout, writeGzip, rootPath, bucket, }?: SinkGCSOptions): {
21
+ _writeTimeout: number;
22
+ _writeGzip: boolean;
23
+ _rootPath: string;
24
+ _storage: Storage;
25
+ _bucket: import("@google-cloud/storage").Bucket;
26
+ _metrics: Metrics;
27
+ _counter: Metrics.MetricsCounter;
28
+ readonly metrics: Metrics;
29
+ write(filePath: any, contentType: any): Promise<any>;
30
+ read(filePath: any): Promise<any>;
31
+ delete(filePath: any): Promise<any>;
32
+ exist(filePath: any): Promise<any>;
33
+ readonly [Symbol.toStringTag]: string;
34
+ };
35
+ };
36
+ import { Storage } from "@google-cloud/storage";
37
+ import Metrics from "@metrics/client";