@eik/sink-gcs 1.2.31 → 2.0.0

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,22 @@
1
+ # [2.0.0](https://github.com/eik-lib/sink-gcs/compare/v1.2.32...v2.0.0) (2024-11-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * update dependencies ([#280](https://github.com/eik-lib/sink-gcs/issues/280)) ([8f2568a](https://github.com/eik-lib/sink-gcs/commit/8f2568aede7dd77e827cec575feb5b6f38070725))
7
+
8
+
9
+ ### BREAKING CHANGES
10
+
11
+ * Requires Node >=20.5.0
12
+
13
+ ## [1.2.32](https://github.com/eik-lib/sink-gcs/compare/v1.2.31...v1.2.32) (2024-08-09)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * add type definitions ([a24ea1e](https://github.com/eik-lib/sink-gcs/commit/a24ea1e2ed8d66b0bb4b1c3ef44640adaa56bac0))
19
+
1
20
  ## [1.2.31](https://github.com/eik-lib/sink-gcs/compare/v1.2.30...v1.2.31) (2024-07-03)
2
21
 
3
22
 
package/README.md CHANGED
@@ -2,10 +2,6 @@
2
2
 
3
3
  A sink for writing to and reading from [Google Cloud Storage][gcs].
4
4
 
5
- [![Dependencies](https://img.shields.io/david/eik-lib/sink-gcs.svg)](https://david-dm.org/eik-lib/sink-gcs)
6
- [![GitHub Actions status](https://github.com/eik-lib/sink-gcs/workflows/Run%20Lint%20and%20Tests/badge.svg)](https://github.com/eik-lib/sink-gcs/actions?query=workflow%3A%22Run+Lint+and+Tests%22)
7
- [![Known Vulnerabilities](https://snyk.io/test/github/eik-lib/sink-gcs/badge.svg?targetFile=package.json)](https://snyk.io/test/github/eik-lib/sink-gcs?targetFile=package.json)
8
-
9
5
  The intention of the [Eik][eik] sink modules is to be able to write to and read from
10
6
  files in different storage backends by swapping sink modules. Because each sink
11
7
  implements the same public API it is possible to use this sink in one environment and
@@ -22,22 +18,25 @@ $ npm install @eik/sink-gcs
22
18
  Read a file from [Google Cloud Storage][gcs] and serve it on HTTP:
23
19
 
24
20
  ```js
25
- const { pipeline } = require('stream');
26
- const express = require("express");
27
- const Sink = require("@eik/sink-gcs");
21
+ import { pipeline } from 'node:stream';
22
+ import express from 'express';
23
+ import Sink from '@eik/sink-gcs';
28
24
 
29
25
  const app = express();
30
- const sink = new Sink({
31
- credentials: {
32
- client_email: 'a@email.address',
33
- private_key: '[ ...snip... ]',
34
- projectId: 'myProject',
26
+ const sink = new Sink(
27
+ {
28
+ credentials: {
29
+ client_email: 'a@email.address',
30
+ private_key: '[ ...snip... ]',
31
+ projectId: 'myProject',
32
+ },
35
33
  },
36
- }, {
37
- writeTimeout: 20000,
38
- });
34
+ {
35
+ writeTimeout: 20000,
36
+ },
37
+ );
39
38
 
40
- app.get("/file.js", async (req, res, next) => {
39
+ app.get('/file.js', async (req, res, next) => {
41
40
  try {
42
41
  const file = await sink.read('/path/to/file/file.js');
43
42
  pipeline(file.stream, res, (error) => {
@@ -56,7 +55,7 @@ app.listen(8000);
56
55
  Create a new Sink instance.
57
56
 
58
57
  ```js
59
- const Sink = require("@eik/sink-gcs");
58
+ import Sink from '@eik/sink-gcs';
60
59
 
61
60
  const sink = new Sink({
62
61
  credentials: {
@@ -71,12 +70,12 @@ const sink = new Sink({
71
70
 
72
71
  This constructor takes the following arguments:
73
72
 
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: `60000` - 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.
73
+ - `storageOptions` - Object - A Google Cloud Storage [storage options object][gcs-storage-options] - Required.
74
+ - `options` - Object - Other options related to storage and behavior - Optional.
75
+ - `writeTimeout` - Number - Timeout, in milliseconds, for write operations to the sink - Default: `60000` - Optional.
76
+ - `writeGzip` - Boolean - If files should be written with gzip compression - Default: `false` - Optional.
77
+ - `rootPath` - String - Root directory for where to store files in the GCS bucket - Default: `eik` - Optional.
78
+ - `bucket` - String - Name of the bucket to store files in - Default: `eik_files` - Optional.
80
79
 
81
80
  ## API
82
81
 
@@ -88,8 +87,8 @@ Async method for writing a file to storage.
88
87
 
89
88
  This method takes the following arguments:
90
89
 
91
- * `filePath` - String - Path to the file to be stored - Required.
92
- * `contentType` - String - The content type of the file - Required.
90
+ - `filePath` - String - Path to the file to be stored - Required.
91
+ - `contentType` - String - The content type of the file - Required.
93
92
 
94
93
  Resolves with a writable stream.
95
94
 
@@ -115,14 +114,14 @@ Async method for reading a file from storage.
115
114
 
116
115
  This method takes the following arguments:
117
116
 
118
- * `filePath` - String - Path to the file to be read - Required.
117
+ - `filePath` - String - Path to the file to be read - Required.
119
118
 
120
119
  Resolves with a [ReadFile][read-file] object which holds metadata about
121
120
  the file and a readable stream with the byte stream of the file on the
122
121
  `.stream` property.
123
122
 
124
123
  ```js
125
- const { pipeline } = require('stream);
124
+ import { pipeline } from 'node:stream';
126
125
 
127
126
  const toStream = new SomeWritableStream();
128
127
  const sink = new Sink({ ... });
@@ -143,7 +142,7 @@ Async method for deleting a file in storage.
143
142
 
144
143
  This method takes the following arguments:
145
144
 
146
- * `filePath` - String - Path to the file to be deleted - Required.
145
+ - `filePath` - String - Path to the file to be deleted - Required.
147
146
 
148
147
  Resolves if file is deleted and rejects if file could not be deleted.
149
148
 
@@ -163,7 +162,7 @@ Async method for checking if a file exist in the storage.
163
162
 
164
163
  This method takes the following arguments:
165
164
 
166
- * `filePath` - String - Path to the file to be checked for existence - Required.
165
+ - `filePath` - String - Path to the file to be checked for existence - Required.
167
166
 
168
167
  Resolves if file exists and rejects if file does not exist.
169
168
 
@@ -216,13 +215,13 @@ The stream will emit an event of the following character for each metric:
216
215
 
217
216
  The metric will have the following labels:
218
217
 
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.
218
+ - `operation` - `String` - The operation which triggered the metric. Can be `write`, `read`, `delete` or `exist`.
219
+ - `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.
220
+ - `access` - `Boolean` - If the operation triggered access to the Google Cloud Storage.
222
221
 
223
- Do note that the `access` label is `true` when the Sink runs an operation against the
222
+ Do note that the `access` label is `true` when the Sink runs an operation against the
224
223
  Google Cloud Storage which can generate a cost. In other words; this can be used to
225
- monitor excessive access to prevent cost.
224
+ monitor excessive access to prevent cost.
226
225
 
227
226
  ## License
228
227
 
@@ -250,4 +249,4 @@ SOFTWARE.
250
249
  [gcs-auth]: https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/0.50.0/google-cloud
251
250
  [gcs-storage-options]: https://googleapis.dev/nodejs/storage/latest/global.html#StorageOptions
252
251
  [gcs]: https://cloud.google.com/storage/
253
- [read-file]: https://github.com/eik-lib/common/blob/master/lib/classes/read-file.js
252
+ [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 = 60000,
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
+ Sink.validateFilePath(filePath);
67
+ Sink.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
+ Sink.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
+ Sink.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
+ Sink.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,26 @@
1
1
  {
2
2
  "name": "@eik/sink-gcs",
3
- "version": "1.2.31",
3
+ "version": "2.0.0",
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": {
16
+ "clean": "rimraf .tap node_modules types",
14
17
  "test": "tap --disable-coverage --allow-empty-coverage",
15
- "test:snapshots:update": "tap test/**/*.js --snapshot",
18
+ "test:snapshots": "tap test/**/*.js --snapshot",
16
19
  "lint:fix": "eslint --fix .",
17
- "lint": "eslint ."
20
+ "lint": "eslint .",
21
+ "types": "run-s types:module types:test",
22
+ "types:module": "tsc",
23
+ "types:test": "tsc --project tsconfig.test.json"
18
24
  },
19
25
  "repository": {
20
26
  "type": "git",
@@ -27,23 +33,24 @@
27
33
  },
28
34
  "homepage": "https://github.com/eik-lib/sink-gcs#readme",
29
35
  "dependencies": {
30
- "@eik/common": "3.0.1",
31
- "@eik/sink": "1.2.1",
36
+ "@eik/common": "5.0.0",
37
+ "@eik/sink": "1.2.5",
32
38
  "@google-cloud/storage": "6.12.0",
33
- "@metrics/client": "^2.5.0"
39
+ "@metrics/client": "2.5.4"
34
40
  },
35
41
  "devDependencies": {
36
- "@babel/eslint-parser": "7.24.7",
37
- "@semantic-release/changelog": "6.0.3",
38
- "@semantic-release/git": "10.0.1",
39
- "eslint": "8.57.0",
40
- "eslint-config-airbnb-base": "15.0.0",
41
- "eslint-config-prettier": "9.1.0",
42
- "eslint-plugin-import": "2.29.1",
43
- "eslint-plugin-prettier": "5.1.3",
44
- "prettier": "3.3.2",
45
- "semantic-release": "23.1.1",
46
- "tap": "18.8.0",
47
- "unique-slug": "2.0.2"
42
+ "@eik/eslint-config": "1.0.2",
43
+ "@eik/prettier-config": "1.0.1",
44
+ "@eik/semantic-release-config": "1.0.0",
45
+ "@eik/typescript-config": "1.0.0",
46
+ "@types/readable-stream": "4.0.18",
47
+ "eslint": "9.14.0",
48
+ "npm-run-all2": "7.0.1",
49
+ "prettier": "3.3.3",
50
+ "rimraf": "6.0.1",
51
+ "semantic-release": "24.2.0",
52
+ "tap": "21.0.1",
53
+ "typescript": "5.6.3",
54
+ "unique-slug": "5.0.0"
48
55
  }
49
56
  }
@@ -0,0 +1,39 @@
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
+ validateFilePath(filePath: string): string;
36
+ validateContentType(contentType: string): string;
37
+ };
38
+ import { Storage } from "@google-cloud/storage";
39
+ import Metrics from "@metrics/client";