gcf-common-lib 0.28.61 → 0.29.62

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.
@@ -12,10 +12,10 @@ jobs:
12
12
  build:
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v2
16
- - uses: actions/setup-node@v2
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-node@v4
17
17
  with:
18
- node-version: 14
18
+ node-version: 18
19
19
  - run: npm ci
20
20
  - run: npm test
21
21
 
@@ -23,10 +23,10 @@ jobs:
23
23
  needs: build
24
24
  runs-on: ubuntu-latest
25
25
  steps:
26
- - uses: actions/checkout@v2
27
- - uses: actions/setup-node@v2
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/setup-node@v4
28
28
  with:
29
- node-version: 14
29
+ node-version: 18
30
30
  registry-url: https://registry.npmjs.org/
31
31
  - run: npm ci
32
32
  - run: npm publish
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gcf-common-lib",
3
3
  "description": "",
4
- "version": "0.28.61",
4
+ "version": "0.29.62",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "branches": [
@@ -9,7 +9,7 @@
9
9
  ]
10
10
  },
11
11
  "engines": {
12
- "node": ">=16"
12
+ "node": ">=18"
13
13
  },
14
14
  "main": "src/index",
15
15
  "scripts": {
@@ -20,31 +20,30 @@
20
20
  "url": "https://github.com/TopTechnologies/gcf-common.git"
21
21
  },
22
22
  "dependencies": {
23
- "@types/amqplib": "^0.10.4",
23
+ "@types/amqplib": "^0.10.5",
24
24
  "@types/bluebird": "^3.5.42",
25
- "@types/lodash": "^4.14.201",
26
- "@types/node": "^16.18.61",
27
- "@google-cloud/pubsub": "^4.1.1",
28
- "@google-cloud/secret-manager": "^5.0.1",
29
- "@google-cloud/storage": "^7.7.0",
25
+ "@types/lodash": "^4.17.0",
26
+ "@types/node": "^18.19.26",
27
+ "@google-cloud/pubsub": "^4.3.3",
28
+ "@google-cloud/storage": "^7.9.0",
30
29
  "amqplib": "^0.10.3",
31
30
  "bluebird": "^3.7.2",
32
31
  "lodash": "^4.17.21",
33
32
  "moment": "^2.30.1",
34
- "mongodb": "^4.17.1",
33
+ "mongodb": "^4.17.2",
35
34
  "rxjs": "^7.8.1"
36
35
  },
37
36
  "devDependencies": {
38
- "@typescript-eslint/eslint-plugin": "^6.10.0",
39
- "@typescript-eslint/parser": "^6.10.0",
40
- "@tsconfig/node16": "^16.1.1",
41
- "eslint": "^8.53.0",
37
+ "@typescript-eslint/eslint-plugin": "^7.3.1",
38
+ "@typescript-eslint/parser": "^7.3.1",
39
+ "@tsconfig/node18": "^18.2.2",
40
+ "eslint": "^8.57.0",
42
41
  "eslint-import-resolver-typescript": "^3.6.1",
43
- "eslint-plugin-import": "^2.29.0",
42
+ "eslint-plugin-import": "^2.29.1",
44
43
  "eslint-plugin-lodash": "^7.4.0",
45
44
  "eslint-plugin-promise": "^6.1.1",
46
45
  "eslint-plugin-rxjs": "^5.0.3",
47
- "eslint-plugin-unicorn": "^49.0.0"
46
+ "eslint-plugin-unicorn": "^51.0.1"
48
47
  },
49
48
  "author": "alert83@gmail.com",
50
49
  "license": ""
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AmqpHelper = void 0;
7
+ const amqplib_1 = require("amqplib");
8
+ const bluebird_1 = __importDefault(require("bluebird"));
9
+ exports.AmqpHelper = {
10
+ async withAmqpConn(fn, url) {
11
+ function withDisposer() {
12
+ return bluebird_1.default.method(async () => {
13
+ const amqpConn = await (0, amqplib_1.connect)(url);
14
+ amqpConn.on('close', () => console.info('Amqp connection closed!'));
15
+ return amqpConn;
16
+ })().disposer((conn, promise) => conn.close());
17
+ }
18
+ return bluebird_1.default.using(withDisposer(), conn => fn(conn));
19
+ },
20
+ async withAmqpCh(fn, url, useConfirmChannel = false, prefetch = 1) {
21
+ return exports.AmqpHelper.withAmqpConn(async (conn) => {
22
+ function withDisposer() {
23
+ return bluebird_1.default.method(async () => {
24
+ const ch = useConfirmChannel ? await conn.createConfirmChannel() : await conn.createChannel();
25
+ await ch.prefetch(prefetch);
26
+ return ch;
27
+ })().disposer((ch, promise) => ch.close());
28
+ }
29
+ return bluebird_1.default.using(withDisposer(), ch => fn(ch));
30
+ }, url);
31
+ },
32
+ async publishAmqp(ch, exchange, routingKey, json, options) {
33
+ const payload = Buffer.from(JSON.stringify(json));
34
+ const keepSending = exchange
35
+ ? ch.publish(exchange, routingKey, payload, options)
36
+ : ch.sendToQueue(routingKey, payload, options);
37
+ if (!keepSending)
38
+ await new Promise(resolve => ch.once('drain', () => resolve()));
39
+ },
40
+ async sendToQueueConfAmqp(ch, queue, json, options) {
41
+ const payload = Buffer.from(JSON.stringify(json));
42
+ await new Promise((resolve, reject) => ch.sendToQueue(queue, payload, options, (err, ok) => (err ? reject(err) : resolve(ok))));
43
+ },
44
+ };
@@ -0,0 +1,52 @@
1
+ import { Channel, ConfirmChannel, connect, Connection, Options } from 'amqplib';
2
+ import Bluebird from 'bluebird';
3
+ import Dict = NodeJS.Dict;
4
+
5
+ export const AmqpHelper = {
6
+ async withAmqpConn(fn: (conn: Connection) => Promise<any>, url: string) {
7
+ function withDisposer() {
8
+ return Bluebird.method(async () => {
9
+ const amqpConn = await connect(url);
10
+ amqpConn.on('close', () => console.info('Amqp connection closed!'));
11
+ return amqpConn;
12
+ })().disposer((conn, promise) => conn.close());
13
+ }
14
+
15
+ return Bluebird.using(withDisposer(), conn => fn(conn));
16
+ },
17
+
18
+ async withAmqpCh(fn: (ch: Channel) => Promise<any>, url: string, useConfirmChannel = false, prefetch = 1) {
19
+ return AmqpHelper.withAmqpConn(async conn => {
20
+ function withDisposer() {
21
+ return Bluebird.method(async () => {
22
+ const ch = useConfirmChannel ? await conn.createConfirmChannel() : await conn.createChannel();
23
+ await ch.prefetch(prefetch);
24
+ return ch;
25
+ })().disposer((ch, promise) => ch.close());
26
+ }
27
+
28
+ return Bluebird.using(withDisposer(), ch => fn(ch));
29
+ }, url);
30
+ },
31
+
32
+ async publishAmqp(
33
+ ch: Channel,
34
+ exchange: string | undefined,
35
+ routingKey: string,
36
+ json: Dict<any>,
37
+ options?: Options.Publish,
38
+ ) {
39
+ const payload = Buffer.from(JSON.stringify(json));
40
+ const keepSending = exchange
41
+ ? ch.publish(exchange, routingKey, payload, options)
42
+ : ch.sendToQueue(routingKey, payload, options);
43
+ if (!keepSending) await new Promise<void>(resolve => ch.once('drain', () => resolve()));
44
+ },
45
+
46
+ async sendToQueueConfAmqp(ch: ConfirmChannel, queue: string, json: Dict<any>, options?: Options.Publish) {
47
+ const payload = Buffer.from(JSON.stringify(json));
48
+ await new Promise((resolve, reject) =>
49
+ ch.sendToQueue(queue, payload, options, (err, ok) => (err ? reject(err) : resolve(ok))),
50
+ );
51
+ },
52
+ };
package/src/index.js CHANGED
@@ -29,27 +29,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
29
  return (mod && mod.__esModule) ? mod : { "default": mod };
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.GcfCommon = exports.secretClient = exports.storage = exports.pubSub = exports.MongoDb = exports.RxJs = exports.SecretManager = exports.PubSub = exports.Storage = void 0;
32
+ exports.GcfCommon = exports.storage = exports.pubSub = exports.MongoDb = exports.RxJs = exports.PubSub = exports.Storage = void 0;
33
33
  const pubsub_1 = require("@google-cloud/pubsub");
34
- const secret_manager_1 = require("@google-cloud/secret-manager");
35
34
  const storage_1 = require("@google-cloud/storage");
36
35
  const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
37
36
  const mapValues_1 = __importDefault(require("lodash/mapValues"));
38
37
  const noop_1 = __importDefault(require("lodash/noop"));
39
38
  const rxjs_1 = require("rxjs");
39
+ const amqp_helper_1 = require("./amqp-helper");
40
40
  const utils_1 = require("./utils");
41
41
  exports.Storage = __importStar(require("@google-cloud/storage"));
42
42
  exports.PubSub = __importStar(require("@google-cloud/pubsub"));
43
- exports.SecretManager = __importStar(require("@google-cloud/secret-manager"));
44
43
  exports.RxJs = __importStar(require("rxjs"));
45
44
  exports.MongoDb = __importStar(require("mongodb"));
46
45
  __exportStar(require("./types"), exports);
47
46
  __exportStar(require("./utils"), exports);
48
47
  exports.pubSub = new pubsub_1.PubSub();
49
48
  exports.storage = new storage_1.Storage();
50
- exports.secretClient = new secret_manager_1.SecretManagerServiceClient();
49
+ // export const secretClient = new SecretManagerServiceClient();
51
50
  class GcfCommon {
52
51
  constructor() { }
52
+ static amqpOptions = {
53
+ assertExchange: { durable: true, autoDelete: false },
54
+ assertOptions: { durable: true, autoDelete: true, expires: (0, utils_1.ms)({ d: 1 }) },
55
+ publishOptions: { persistent: true },
56
+ };
53
57
  /**
54
58
  *
55
59
  * @param {!TEvent} event Event payload.
@@ -59,20 +63,34 @@ class GcfCommon {
59
63
  */
60
64
  static async process(event, context, handler = rxjs_1.identity, timeoutSec = 535) {
61
65
  const asyncHandler = async (_event, _context) => await handler(_event, _context);
62
- return (0, rxjs_1.firstValueFrom)((0, rxjs_1.defer)(() => (0, rxjs_1.from)(asyncHandler(event, context))).pipe((0, rxjs_1.first)(), (0, rxjs_1.timeout)({ first: (0, utils_1.ms)({ s: timeoutSec }) })));
63
- }
64
- static async processOLd(event, context, handler = rxjs_1.identity, timeoutSec = 535) {
65
- return Promise.race([(0, utils_1.timeoutAfter)(timeoutSec), handler(event, context)])
66
+ return (0, rxjs_1.firstValueFrom)((0, rxjs_1.defer)(() => (0, rxjs_1.from)(asyncHandler(event, context))).pipe((0, rxjs_1.first)(), (0, rxjs_1.timeout)({ first: (0, utils_1.ms)({ s: timeoutSec }) })))
66
67
  .then(async (res) => {
67
68
  // console.log('res:', res);
68
- await this.publish(event, context, res);
69
+ await this.response(event, context, res).catch(noop_1.default);
69
70
  return res;
70
71
  })
71
72
  .catch(async (error) => {
72
- await this.publish(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop_1.default);
73
+ await this.response(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop_1.default);
73
74
  throw error;
74
75
  });
75
76
  }
77
+ // static async processOLd<T extends TResponse, E = TEvent>(
78
+ // event: E,
79
+ // context: TContext,
80
+ // handler: (event: E, context: TContext) => Promise<T | E> | T | E = identity,
81
+ // timeoutSec = 535,
82
+ // ) {
83
+ // return Promise.race([timeoutAfter(timeoutSec), handler(event, context)])
84
+ // .then(async res => {
85
+ // // console.log('res:', res);
86
+ // await this.response(event, context, res as T);
87
+ // return res;
88
+ // })
89
+ // .catch(async (error: Error) => {
90
+ // await this.response(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop);
91
+ // throw error;
92
+ // });
93
+ // }
76
94
  static buildResponse(error) {
77
95
  return {
78
96
  error: {
@@ -82,10 +100,15 @@ class GcfCommon {
82
100
  },
83
101
  };
84
102
  }
85
- static async publish(event, context, json, attributes) {
86
- console.time('safeGetAttributes');
87
- const { topic, exchange, queue, consumer_id, request_id, app_id, env } = await this.safeGetAttributes(event, context, ['consumer_id', 'topic', 'exchange', 'queue']);
88
- console.timeEnd('safeGetAttributes');
103
+ static async response(event, context, json, attributes) {
104
+ // console.time('safeGetAttributes');
105
+ // const { topic, exchange, queue, consumer_id, request_id, app_id, env } = await this.safeGetAttributes(
106
+ // event,
107
+ // context,
108
+ // ['consumer_id', 'topic', 'exchange', 'queue'],
109
+ // );
110
+ // console.timeEnd('safeGetAttributes');
111
+ const { topic, exchange, queue, consumer_id, request_id, app_id, env } = this.getMetadataOrAttribute(event, context);
89
112
  //
90
113
  console.time('publish');
91
114
  if (topic && !(0, isEmpty_1.default)(topic)) {
@@ -103,9 +126,9 @@ class GcfCommon {
103
126
  }
104
127
  if (exchange && !(0, isEmpty_1.default)(exchange)) {
105
128
  console.log('send:', exchange, queue, app_id, env, json, attributes);
106
- await (0, utils_1.withAmqpCh)(async (ch) => {
129
+ await amqp_helper_1.AmqpHelper.withAmqpCh(async (ch) => {
107
130
  await ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
108
- await (0, utils_1.publishAmqp)(ch, exchange, queue ?? '', json ?? {}, {
131
+ await amqp_helper_1.AmqpHelper.publishAmqp(ch, exchange, queue ?? '', json ?? {}, {
109
132
  ...this.amqpOptions.publishOptions,
110
133
  correlationId: request_id,
111
134
  });
@@ -113,9 +136,9 @@ class GcfCommon {
113
136
  }
114
137
  else if (queue && !(0, isEmpty_1.default)(queue)) {
115
138
  console.log('send:', queue, app_id, env, json, attributes);
116
- await (0, utils_1.withAmqpCh)(async (ch) => {
139
+ await amqp_helper_1.AmqpHelper.withAmqpCh(async (ch) => {
117
140
  // await ch.assertQueue(queue, this.amqpOptions.assertOptions);
118
- await (0, utils_1.publishAmqp)(ch, undefined, queue, json ?? {}, {
141
+ await amqp_helper_1.AmqpHelper.publishAmqp(ch, undefined, queue, json ?? {}, {
119
142
  ...this.amqpOptions.publishOptions,
120
143
  correlationId: request_id,
121
144
  });
@@ -123,28 +146,31 @@ class GcfCommon {
123
146
  }
124
147
  console.timeEnd('publish');
125
148
  }
126
- static async safeGetAttributes(event, context, props) {
127
- let metaOrAttr = this.getMetadataOrAttribute(event, context);
128
- // const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
129
- // const someProp = props.map(prop => get(metaOrAttr, prop)).some(v => !isNil(v));
130
- // // if no prop then check file metadata
131
- // if (!someProp && context?.resource?.type === 'storage#object') {
132
- // console.log('get metadata from file');
133
- // if (context?.eventType === 'google.storage.object.finalize') {
134
- // const gsEvent = event as TGSEvent;
135
- // const [meta] = await new Storage().bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
136
- // metaOrAttr = meta?.metadata ?? {};
137
- // }
138
- // }
139
- return {
140
- ...metaOrAttr,
141
- app_id: metaOrAttr.app_id,
142
- request_id: metaOrAttr.request_id,
143
- };
144
- }
149
+ // static async safeGetAttributes<E = TEvent>(event: E, context: TContext, props: string[]) {
150
+ // let metaOrAttr = this.getMetadataOrAttribute(event, context);
151
+ // // const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
152
+ //
153
+ // const someProp = props.map(prop => get(metaOrAttr, prop)).some(v => !isNil(v));
154
+ // // if no prop then check file metadata
155
+ // if (!someProp && context?.resource?.type === 'storage#object') {
156
+ // console.log('get metadata from file');
157
+ // if (context?.eventType === 'google.storage.object.finalize') {
158
+ // const gsEvent = event as TGSEvent;
159
+ // const [meta] = await new Storage().bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
160
+ // metaOrAttr = meta?.metadata ?? {};
161
+ // }
162
+ // }
163
+ //
164
+ // return {
165
+ // ...metaOrAttr,
166
+ // app_id: metaOrAttr.app_id,
167
+ // request_id: metaOrAttr.request_id,
168
+ // } as TMetadataOrAttributes;
169
+ // }
145
170
  static async getOptions(event, context) {
146
- const { options } = await this.safeGetAttributes(event, context, ['options']);
147
- return JSON.parse(options ?? '{}');
171
+ // const { options } = await this.safeGetAttributes(event, context, ['options']);
172
+ const { options } = this.getMetadataOrAttribute(event, context);
173
+ return (0, utils_1.safeJsonParse)(options, {});
148
174
  }
149
175
  static getMetadataOrAttribute(event, context) {
150
176
  let metadataOrAttribute;
@@ -162,20 +188,5 @@ class GcfCommon {
162
188
  }
163
189
  return metadataOrAttribute ?? {};
164
190
  }
165
- static async getSecret(name, version) {
166
- const projectId = await exports.secretClient.getProjectId();
167
- const secretName = `projects/${projectId}/secrets/${name}`;
168
- const secretVersion = `${secretName}/versions/${version ?? 'latest'}`;
169
- const [response] = await exports.secretClient.accessSecretVersion({ name: secretVersion });
170
- return response?.payload?.data?.toString();
171
- }
172
- static async getSecrets(names, versions) {
173
- return Promise.all(names.map(async (name, idx) => this.getSecret(name, versions?.[idx]).catch(noop_1.default)));
174
- }
175
191
  }
176
192
  exports.GcfCommon = GcfCommon;
177
- GcfCommon.amqpOptions = {
178
- assertExchange: { durable: true, autoDelete: false },
179
- assertOptions: { durable: true, autoDelete: true, expires: (0, utils_1.ms)({ d: 1 }) },
180
- publishOptions: { persistent: true },
181
- };
package/src/index.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  import { PubSub } from '@google-cloud/pubsub';
2
- import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
3
2
  import { Storage } from '@google-cloud/storage';
4
3
  import { Options } from 'amqplib';
5
4
  import isEmpty from 'lodash/isEmpty';
6
5
  import mapValues from 'lodash/mapValues';
7
6
  import noop from 'lodash/noop';
8
7
  import { defer, first, firstValueFrom, from, identity, timeout } from 'rxjs';
8
+ import { AmqpHelper } from './amqp-helper';
9
9
  import { TContext, TEvent, TGSEvent, TMetadataOrAttributes, TPSEvent, TResponse } from './types';
10
- import { ms, publishAmqp, timeoutAfter, withAmqpCh } from './utils';
10
+ import { ms, safeJsonParse } from './utils';
11
11
  import Dict = NodeJS.Dict;
12
12
 
13
13
  export * as Storage from '@google-cloud/storage';
14
14
  export * as PubSub from '@google-cloud/pubsub';
15
- export * as SecretManager from '@google-cloud/secret-manager';
16
15
  export * as RxJs from 'rxjs';
17
16
  export * as MongoDb from 'mongodb';
18
17
  export * from './types';
@@ -20,7 +19,7 @@ export * from './utils';
20
19
 
21
20
  export const pubSub = new PubSub();
22
21
  export const storage = new Storage();
23
- export const secretClient = new SecretManagerServiceClient();
22
+ // export const secretClient = new SecretManagerServiceClient();
24
23
 
25
24
  export class GcfCommon {
26
25
  constructor() {}
@@ -52,27 +51,36 @@ export class GcfCommon {
52
51
  const asyncHandler = async (_event: any, _context: any) => await handler(_event, _context);
53
52
  return firstValueFrom(
54
53
  defer(() => from(asyncHandler(event, context))).pipe(first(), timeout({ first: ms({ s: timeoutSec }) })),
55
- );
56
- }
57
-
58
- static async processOLd<T extends TResponse, E = TEvent>(
59
- event: E,
60
- context: TContext,
61
- handler: (event: E, context: TContext) => Promise<T | E> | T | E = identity,
62
- timeoutSec = 535,
63
- ) {
64
- return Promise.race([timeoutAfter(timeoutSec), handler(event, context)])
54
+ )
65
55
  .then(async res => {
66
56
  // console.log('res:', res);
67
- await this.publish(event, context, res as T);
57
+ await this.response(event, context, res as T).catch(noop);
68
58
  return res;
69
59
  })
70
60
  .catch(async (error: Error) => {
71
- await this.publish(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop);
61
+ await this.response(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop);
72
62
  throw error;
73
63
  });
74
64
  }
75
65
 
66
+ // static async processOLd<T extends TResponse, E = TEvent>(
67
+ // event: E,
68
+ // context: TContext,
69
+ // handler: (event: E, context: TContext) => Promise<T | E> | T | E = identity,
70
+ // timeoutSec = 535,
71
+ // ) {
72
+ // return Promise.race([timeoutAfter(timeoutSec), handler(event, context)])
73
+ // .then(async res => {
74
+ // // console.log('res:', res);
75
+ // await this.response(event, context, res as T);
76
+ // return res;
77
+ // })
78
+ // .catch(async (error: Error) => {
79
+ // await this.response(event, context, GcfCommon.buildResponse(error), { error: '1' }).catch(noop);
80
+ // throw error;
81
+ // });
82
+ // }
83
+
76
84
  static buildResponse(error: Error) {
77
85
  return {
78
86
  error: {
@@ -83,17 +91,20 @@ export class GcfCommon {
83
91
  } as TResponse;
84
92
  }
85
93
 
86
- static async publish<E = TEvent>(event: E, context: TContext, json?: TResponse, attributes?: Dict<any>) {
87
- console.time('safeGetAttributes');
94
+ static async response<E = TEvent>(event: E, context: TContext, json?: TResponse, attributes?: Dict<any>) {
95
+ // console.time('safeGetAttributes');
96
+ // const { topic, exchange, queue, consumer_id, request_id, app_id, env } = await this.safeGetAttributes(
97
+ // event,
98
+ // context,
99
+ // ['consumer_id', 'topic', 'exchange', 'queue'],
100
+ // );
101
+ // console.timeEnd('safeGetAttributes');
88
102
 
89
- const { topic, exchange, queue, consumer_id, request_id, app_id, env } = await this.safeGetAttributes(
103
+ const { topic, exchange, queue, consumer_id, request_id, app_id, env } = this.getMetadataOrAttribute(
90
104
  event,
91
105
  context,
92
- ['consumer_id', 'topic', 'exchange', 'queue'],
93
106
  );
94
107
 
95
- console.timeEnd('safeGetAttributes');
96
-
97
108
  //
98
109
 
99
110
  console.time('publish');
@@ -114,18 +125,18 @@ export class GcfCommon {
114
125
 
115
126
  if (exchange && !isEmpty(exchange)) {
116
127
  console.log('send:', exchange, queue, app_id, env, json, attributes);
117
- await withAmqpCh(async ch => {
128
+ await AmqpHelper.withAmqpCh(async ch => {
118
129
  await ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
119
- await publishAmqp(ch, exchange, queue ?? '', json ?? {}, {
130
+ await AmqpHelper.publishAmqp(ch, exchange, queue ?? '', json ?? {}, {
120
131
  ...this.amqpOptions.publishOptions,
121
132
  correlationId: request_id,
122
133
  });
123
134
  }, this.amqpOptions.url as string);
124
135
  } else if (queue && !isEmpty(queue)) {
125
136
  console.log('send:', queue, app_id, env, json, attributes);
126
- await withAmqpCh(async ch => {
137
+ await AmqpHelper.withAmqpCh(async ch => {
127
138
  // await ch.assertQueue(queue, this.amqpOptions.assertOptions);
128
- await publishAmqp(ch, undefined, queue, json ?? {}, {
139
+ await AmqpHelper.publishAmqp(ch, undefined, queue, json ?? {}, {
129
140
  ...this.amqpOptions.publishOptions,
130
141
  correlationId: request_id,
131
142
  });
@@ -135,31 +146,32 @@ export class GcfCommon {
135
146
  console.timeEnd('publish');
136
147
  }
137
148
 
138
- static async safeGetAttributes<E = TEvent>(event: E, context: TContext, props: string[]) {
139
- let metaOrAttr = this.getMetadataOrAttribute(event, context);
140
- // const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
141
-
142
- // const someProp = props.map(prop => get(metaOrAttr, prop)).some(v => !isNil(v));
143
- // // if no prop then check file metadata
144
- // if (!someProp && context?.resource?.type === 'storage#object') {
145
- // console.log('get metadata from file');
146
- // if (context?.eventType === 'google.storage.object.finalize') {
147
- // const gsEvent = event as TGSEvent;
148
- // const [meta] = await new Storage().bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
149
- // metaOrAttr = meta?.metadata ?? {};
150
- // }
151
- // }
152
-
153
- return {
154
- ...metaOrAttr,
155
- app_id: metaOrAttr.app_id,
156
- request_id: metaOrAttr.request_id,
157
- } as TMetadataOrAttributes;
158
- }
149
+ // static async safeGetAttributes<E = TEvent>(event: E, context: TContext, props: string[]) {
150
+ // let metaOrAttr = this.getMetadataOrAttribute(event, context);
151
+ // // const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
152
+ //
153
+ // const someProp = props.map(prop => get(metaOrAttr, prop)).some(v => !isNil(v));
154
+ // // if no prop then check file metadata
155
+ // if (!someProp && context?.resource?.type === 'storage#object') {
156
+ // console.log('get metadata from file');
157
+ // if (context?.eventType === 'google.storage.object.finalize') {
158
+ // const gsEvent = event as TGSEvent;
159
+ // const [meta] = await new Storage().bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
160
+ // metaOrAttr = meta?.metadata ?? {};
161
+ // }
162
+ // }
163
+ //
164
+ // return {
165
+ // ...metaOrAttr,
166
+ // app_id: metaOrAttr.app_id,
167
+ // request_id: metaOrAttr.request_id,
168
+ // } as TMetadataOrAttributes;
169
+ // }
159
170
 
160
171
  static async getOptions(event: TEvent, context: TContext): Promise<Dict<any>> {
161
- const { options } = await this.safeGetAttributes(event, context, ['options']);
162
- return JSON.parse(options ?? '{}');
172
+ // const { options } = await this.safeGetAttributes(event, context, ['options']);
173
+ const { options } = this.getMetadataOrAttribute(event, context);
174
+ return safeJsonParse(options as any, {} as any);
163
175
  }
164
176
 
165
177
  static getMetadataOrAttribute<E = TEvent>(event: E, context: TContext) {
@@ -181,15 +193,15 @@ export class GcfCommon {
181
193
  return metadataOrAttribute ?? {};
182
194
  }
183
195
 
184
- static async getSecret(name: string, version?: string) {
185
- const projectId = await secretClient.getProjectId();
186
- const secretName = `projects/${projectId}/secrets/${name}`;
187
- const secretVersion = `${secretName}/versions/${version ?? 'latest'}`;
188
- const [response] = await secretClient.accessSecretVersion({ name: secretVersion });
189
- return response?.payload?.data?.toString();
190
- }
191
-
192
- static async getSecrets(names: string[], versions?: string[]) {
193
- return Promise.all(names.map(async (name, idx) => this.getSecret(name, versions?.[idx]).catch(noop)));
194
- }
196
+ // static async getSecret(name: string, version?: string) {
197
+ // const projectId = await secretClient.getProjectId();
198
+ // const secretName = `projects/${projectId}/secrets/${name}`;
199
+ // const secretVersion = `${secretName}/versions/${version ?? 'latest'}`;
200
+ // const [response] = await secretClient.accessSecretVersion({ name: secretVersion });
201
+ // return response?.payload?.data?.toString();
202
+ // }
203
+ //
204
+ // static async getSecrets(names: string[], versions?: string[]) {
205
+ // return Promise.all(names.map(async (name, idx) => this.getSecret(name, versions?.[idx]).catch(noop)));
206
+ // }
195
207
  }
package/src/mongo-lock.js CHANGED
@@ -13,6 +13,7 @@ const bluebird_1 = __importDefault(require("bluebird"));
13
13
  * @deprecated
14
14
  */
15
15
  class MongoLock {
16
+ client;
16
17
  constructor(client) {
17
18
  this.client = client;
18
19
  }
package/src/utils.js CHANGED
@@ -1,11 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sendToQueueConfAmqp = exports.publishAmqp = exports.withAmqpCh = exports.withAmqpConn = exports.safeJsonParse = exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.sec = exports.ms = exports.delay = exports.timeoutAfter = void 0;
7
- const amqplib_1 = require("amqplib");
8
- const bluebird_1 = __importDefault(require("bluebird"));
3
+ exports.safeJsonParse = exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.sec = exports.ms = exports.delay = exports.timeoutAfter = void 0;
9
4
  /**
10
5
  *
11
6
  * @param seconds Google function v1 timeout limit (max: 9 min)
@@ -90,39 +85,3 @@ function safeJsonParse(value, fallbackValue) {
90
85
  }
91
86
  exports.safeJsonParse = safeJsonParse;
92
87
  //
93
- async function withAmqpConn(fn, url) {
94
- function withDisposer() {
95
- return bluebird_1.default.method(async () => {
96
- const amqpConn = await (0, amqplib_1.connect)(url);
97
- amqpConn.on('close', () => console.info('Amqp connection closed!'));
98
- return amqpConn;
99
- })().disposer((conn, promise) => conn.close());
100
- }
101
- return bluebird_1.default.using(withDisposer(), conn => fn(conn));
102
- }
103
- exports.withAmqpConn = withAmqpConn;
104
- async function withAmqpCh(fn, url, useConfirmChannel = false) {
105
- return withAmqpConn(async (conn) => {
106
- function withDisposer() {
107
- return bluebird_1.default.method(async () => {
108
- return useConfirmChannel ? conn.createConfirmChannel() : conn.createChannel();
109
- })().disposer((ch, promise) => ch.close());
110
- }
111
- return bluebird_1.default.using(withDisposer(), ch => fn(ch));
112
- }, url);
113
- }
114
- exports.withAmqpCh = withAmqpCh;
115
- async function publishAmqp(ch, exchange, routingKey, json, options) {
116
- const payload = Buffer.from(JSON.stringify(json));
117
- const keepSending = exchange
118
- ? ch.publish(exchange, routingKey, payload, options)
119
- : ch.sendToQueue(routingKey, payload, options);
120
- if (!keepSending)
121
- await new Promise(resolve => ch.once('drain', () => resolve()));
122
- }
123
- exports.publishAmqp = publishAmqp;
124
- async function sendToQueueConfAmqp(ch, queue, json, options) {
125
- const payload = Buffer.from(JSON.stringify(json));
126
- await new Promise((resolve, reject) => ch.sendToQueue(queue, payload, options, (err, ok) => (err ? reject(err) : resolve(ok))));
127
- }
128
- exports.sendToQueueConfAmqp = sendToQueueConfAmqp;
package/src/utils.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { Channel, ConfirmChannel, connect, Connection, Options } from 'amqplib';
2
- import Bluebird from 'bluebird';
3
1
  import Dict = NodeJS.Dict;
4
2
 
5
3
  /**
@@ -92,53 +90,3 @@ export function safeJsonParse<T = Dict<any>>(value: string, fallbackValue?: T) {
92
90
  }
93
91
 
94
92
  //
95
-
96
- export async function withAmqpConn(fn: (conn: Connection) => Promise<any>, url: string) {
97
- function withDisposer() {
98
- return Bluebird.method(async () => {
99
- const amqpConn = await connect(url);
100
- amqpConn.on('close', () => console.info('Amqp connection closed!'));
101
- return amqpConn;
102
- })().disposer((conn, promise) => conn.close());
103
- }
104
-
105
- return Bluebird.using(withDisposer(), conn => fn(conn));
106
- }
107
-
108
- export async function withAmqpCh(fn: (ch: Channel) => Promise<any>, url: string, useConfirmChannel = false) {
109
- return withAmqpConn(async conn => {
110
- function withDisposer() {
111
- return Bluebird.method(async () => {
112
- return useConfirmChannel ? conn.createConfirmChannel() : conn.createChannel();
113
- })().disposer((ch, promise) => ch.close());
114
- }
115
-
116
- return Bluebird.using(withDisposer(), ch => fn(ch));
117
- }, url);
118
- }
119
-
120
- export async function publishAmqp(
121
- ch: Channel,
122
- exchange: string | undefined,
123
- routingKey: string,
124
- json: Dict<any>,
125
- options?: Options.Publish,
126
- ) {
127
- const payload = Buffer.from(JSON.stringify(json));
128
- const keepSending = exchange
129
- ? ch.publish(exchange, routingKey, payload, options)
130
- : ch.sendToQueue(routingKey, payload, options);
131
- if (!keepSending) await new Promise<void>(resolve => ch.once('drain', () => resolve()));
132
- }
133
-
134
- export async function sendToQueueConfAmqp(
135
- ch: ConfirmChannel,
136
- queue: string,
137
- json: Dict<any>,
138
- options?: Options.Publish,
139
- ) {
140
- const payload = Buffer.from(JSON.stringify(json));
141
- await new Promise((resolve, reject) =>
142
- ch.sendToQueue(queue, payload, options, (err, ok) => (err ? reject(err) : resolve(ok))),
143
- );
144
- }
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "$schema": "http://json.schemastore.org/tsconfig",
3
- "extends": "@tsconfig/node16/tsconfig.json",
3
+ "extends": "@tsconfig/node18/tsconfig.json",
4
4
  "compilerOptions": {}
5
5
  }