gcf-common-lib 0.23.15 → 0.23.17

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gcf-common-lib",
3
3
  "description": "",
4
- "version": "0.23.15",
4
+ "version": "0.23.17",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "branches": [
@@ -20,7 +20,7 @@
20
20
  "dependencies": {
21
21
  "@google-cloud/pubsub": "^3.3.0",
22
22
  "@google-cloud/secret-manager": "^4.2.1",
23
- "@google-cloud/storage": "^6.9.3",
23
+ "@google-cloud/storage": "^6.9.4",
24
24
  "lodash": "^4.17.21",
25
25
  "moment": "^2.29.4",
26
26
  "mongodb": "^4.14.0",
@@ -29,8 +29,8 @@
29
29
  "devDependencies": {
30
30
  "@tsconfig/node14": "^1.0.3",
31
31
  "@types/lodash": "^4.14.191",
32
- "@types/node": "^14.18.36"
32
+ "@types/node": "^14.18.37"
33
33
  },
34
34
  "author": "alert83@gmail.com",
35
- "license": "MIT"
35
+ "license": ""
36
36
  }
package/src/index.js CHANGED
@@ -1,4 +1,18 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
17
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
18
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -14,12 +28,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
28
  Object.defineProperty(exports, "__esModule", { value: true });
15
29
  exports.GcfCommon = exports.secretClient = exports.storage = exports.pubSub = void 0;
16
30
  const pubsub_1 = require("@google-cloud/pubsub");
17
- const fromPairs_1 = __importDefault(require("lodash/fromPairs"));
18
31
  const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
19
32
  const noop_1 = __importDefault(require("lodash/noop"));
20
33
  const utils_1 = require("./utils");
21
34
  const storage_1 = require("@google-cloud/storage");
22
35
  const secret_manager_1 = require("@google-cloud/secret-manager");
36
+ const lodash_1 = require("lodash");
37
+ __exportStar(require("./types"), exports);
38
+ __exportStar(require("./utils"), exports);
23
39
  exports.pubSub = new pubsub_1.PubSub();
24
40
  exports.storage = new storage_1.Storage();
25
41
  exports.secretClient = new secret_manager_1.SecretManagerServiceClient();
@@ -55,64 +71,60 @@ class GcfCommon {
55
71
  }
56
72
  static publish(event, context, json, attributes) {
57
73
  return __awaiter(this, void 0, void 0, function* () {
58
- const { topic, requestId, env } = yield this.getTopic(event, context);
59
- console.log('publish:', topic, env, json, attributes);
74
+ const { topic, appId, env, requestId } = yield this.getTopic(event, context);
60
75
  if (!(0, isEmpty_1.default)(topic)) {
76
+ console.log('publish:', topic, appId, env, json, attributes);
61
77
  return exports.pubSub.topic(topic).publishMessage({
62
78
  json: json !== null && json !== void 0 ? json : {},
63
- attributes: Object.assign(Object.assign({}, (0, fromPairs_1.default)(Object.entries(attributes !== null && attributes !== void 0 ? attributes : {}).map(([k, v]) => [k, '' + v]))), { env: env !== null && env !== void 0 ? env : '', requestId: requestId !== null && requestId !== void 0 ? requestId : '', type: 'response', response: '1' }),
79
+ attributes: Object.assign(Object.assign({}, (0, lodash_1.mapValues)(attributes !== null && attributes !== void 0 ? attributes : {}, (v) => '' + v)), { requestId: requestId !== null && requestId !== void 0 ? requestId : '', appId: appId !== null && appId !== void 0 ? appId : '', env: env !== null && env !== void 0 ? env : '', type: 'response', response: '1' }),
64
80
  });
65
81
  }
66
82
  });
67
83
  }
68
84
  static getTopic(event, context) {
69
- var _a, _b, _c, _d;
85
+ var _a, _b;
70
86
  return __awaiter(this, void 0, void 0, function* () {
71
- /** t_{GUID}__{YYYY-MM-DD} */
72
- let topic;
73
- let requestId;
74
- let env;
75
- switch (context === null || context === void 0 ? void 0 : context.eventType) {
76
- case 'google.storage.object.finalize': {
87
+ let { topic, appId, env, requestId } = this.getMetadata(event, context);
88
+ if (!topic && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
89
+ if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
77
90
  const gsEvent = event;
78
- ({ topic, requestId, env } = (_a = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata) !== null && _a !== void 0 ? _a : {});
79
- if (!topic && ((_b = context === null || context === void 0 ? void 0 : context.resource) === null || _b === void 0 ? void 0 : _b.type) === 'storage#object') {
80
- const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
81
- ({ topic, requestId, env } = (_c = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _c !== void 0 ? _c : {});
82
- }
83
- break;
84
- }
85
- case 'google.pubsub.topic.publish': {
86
- const psEvent = event;
87
- ({ topic, requestId, env } = (_d = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes) !== null && _d !== void 0 ? _d : {});
88
- break;
91
+ const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
92
+ ({ topic, appId, env, requestId } = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {});
89
93
  }
90
94
  }
91
- return { topic, requestId, env };
95
+ return { topic, appId, env, requestId };
92
96
  });
93
97
  }
94
98
  static getOptions(event, context) {
95
- var _a, _b, _c, _d, _e, _f, _g;
99
+ var _a;
96
100
  return __awaiter(this, void 0, void 0, function* () {
97
- switch (context === null || context === void 0 ? void 0 : context.eventType) {
98
- case 'google.storage.object.finalize': {
101
+ let { options } = this.getMetadata(event, context);
102
+ if (!options) {
103
+ if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
99
104
  const gsEvent = event;
100
- if ((_a = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata) === null || _a === void 0 ? void 0 : _a.options) {
101
- return JSON.parse((_c = (_b = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata) === null || _b === void 0 ? void 0 : _b.options) !== null && _c !== void 0 ? _c : '{}');
102
- }
103
- else {
104
- const file = exports.storage.bucket(gsEvent.bucket).file(gsEvent.name);
105
- const [meta] = yield file.getMetadata();
106
- return JSON.parse((_e = (_d = meta === null || meta === void 0 ? void 0 : meta.metadata) === null || _d === void 0 ? void 0 : _d.options) !== null && _e !== void 0 ? _e : '{}');
107
- }
108
- }
109
- case 'google.pubsub.topic.publish': {
110
- const psEvent = event;
111
- return JSON.parse((_g = (_f = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes) === null || _f === void 0 ? void 0 : _f.options) !== null && _g !== void 0 ? _g : '{}');
105
+ const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
106
+ options = (_a = meta === null || meta === void 0 ? void 0 : meta.metadata) === null || _a === void 0 ? void 0 : _a.options;
112
107
  }
113
108
  }
109
+ return JSON.parse(options !== null && options !== void 0 ? options : '{}');
114
110
  });
115
111
  }
112
+ static getMetadata(event, context) {
113
+ let metadata;
114
+ switch (context === null || context === void 0 ? void 0 : context.eventType) {
115
+ case 'google.storage.object.finalize': {
116
+ const gsEvent = event;
117
+ metadata = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata;
118
+ break;
119
+ }
120
+ case 'google.pubsub.topic.publish': {
121
+ const psEvent = event;
122
+ metadata = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes;
123
+ break;
124
+ }
125
+ }
126
+ return metadata !== null && metadata !== void 0 ? metadata : {};
127
+ }
116
128
  static getSecret(name, version) {
117
129
  var _a, _b;
118
130
  return __awaiter(this, void 0, void 0, function* () {
package/src/index.ts CHANGED
@@ -1,72 +1,15 @@
1
1
  import { PubSub } from '@google-cloud/pubsub';
2
- import fromPairs from 'lodash/fromPairs';
3
2
  import isEmpty from 'lodash/isEmpty';
4
3
  import noop from 'lodash/noop';
5
4
  import { timeoutAfter } from './utils';
6
- import { File, Storage } from '@google-cloud/storage';
5
+ import { Storage } from '@google-cloud/storage';
7
6
  import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
7
+ import { TContext, TEvent, TGSEvent, TMetadata, TPSEvent, TResponse } from './types';
8
+ import { mapValues } from 'lodash';
8
9
  import Dict = NodeJS.Dict;
9
10
 
10
- export type TGSEvent = {
11
- bucket: string;
12
- contentType: string;
13
- crc32c: string;
14
- etag: string;
15
- generation: string;
16
- id: string;
17
- kind: string; // 'storage#object'
18
- md5Hash: string;
19
- mediaLink: string;
20
- metadata: {
21
- // [key: string]: string,
22
- topic: string;
23
- requestId: string;
24
- env: string;
25
- options?: any;
26
- };
27
- metageneration: string;
28
- name: string;
29
- selfLink: string;
30
- size: string;
31
- storageClass: string;
32
- timeCreated: string;
33
- timeStorageClassUpdated: string;
34
- updated: string;
35
- };
36
-
37
- export type TPSEvent = {
38
- '@type': string; // 'type.googleapis.com/google.pubsub.v1.PubsubMessage'
39
- attributes?: {
40
- // [k: string]: string,
41
- topic: string;
42
- requestId: string;
43
- env: string;
44
- options?: any;
45
- };
46
- data?: string | Dict<any>;
47
- };
48
-
49
- export type TEvent = TGSEvent | TPSEvent;
50
-
51
- export type TContext = {
52
- eventId: string;
53
- timestamp: string;
54
- eventType: 'google.storage.object.finalize' | 'google.pubsub.topic.publish';
55
- resource: {
56
- service: 'storage.googleapis.com' | 'pubsub.googleapis.com';
57
- type: 'storage#object' | 'type.googleapis.com/google.pubsub.v1.PubsubMessage';
58
- name: string;
59
- };
60
- };
61
-
62
- export type TResponse = {
63
- [prop: string]: any;
64
- error?: {
65
- name: string;
66
- message: string;
67
- stack?: string;
68
- };
69
- };
11
+ export * from './types';
12
+ export * from './utils';
70
13
 
71
14
  export const pubSub = new PubSub();
72
15
  export const storage = new Storage();
@@ -106,16 +49,17 @@ export class GcfCommon {
106
49
  }
107
50
 
108
51
  static async publish(event: TEvent, context: TContext, json?: TResponse, attributes?: Dict<any>) {
109
- const { topic, requestId, env } = await this.getTopic(event, context);
110
- console.log('publish:', topic, env, json, attributes);
52
+ const { topic, appId, env, requestId } = await this.getTopic(event, context);
111
53
 
112
54
  if (!isEmpty(topic)) {
55
+ console.log('publish:', topic, appId, env, json, attributes);
113
56
  return pubSub.topic(topic as string).publishMessage({
114
57
  json: json ?? {},
115
58
  attributes: {
116
- ...fromPairs(Object.entries(attributes ?? {}).map(([k, v]) => [k, '' + v])),
117
- env: env ?? '',
59
+ ...mapValues(attributes ?? {}, (v) => '' + v),
118
60
  requestId: requestId ?? '',
61
+ appId: appId ?? '',
62
+ env: env ?? '',
119
63
  type: 'response',
120
64
  response: '1',
121
65
  },
@@ -124,48 +68,50 @@ export class GcfCommon {
124
68
  }
125
69
 
126
70
  static async getTopic(event: TEvent, context: TContext) {
127
- /** t_{GUID}__{YYYY-MM-DD} */
128
- let topic: string | undefined;
129
- let requestId: string | undefined;
130
- let env: string | undefined;
71
+ let { topic, appId, env, requestId } = this.getMetadata(event, context);
131
72
 
132
- switch (context?.eventType) {
133
- case 'google.storage.object.finalize': {
73
+ if (!topic && context?.resource?.type === 'storage#object') {
74
+ if (context?.eventType === 'google.storage.object.finalize') {
134
75
  const gsEvent = event as TGSEvent;
135
- ({ topic, requestId, env } = gsEvent?.metadata ?? {});
136
- if (!topic && context?.resource?.type === 'storage#object') {
137
- const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
138
- ({ topic, requestId, env } = meta?.metadata ?? {});
139
- }
140
- break;
141
- }
142
- case 'google.pubsub.topic.publish': {
143
- const psEvent = event as TPSEvent;
144
- ({ topic, requestId, env } = psEvent?.attributes ?? ({} as any));
145
- break;
76
+ const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
77
+ ({ topic, appId, env, requestId } = meta?.metadata ?? {});
146
78
  }
147
79
  }
148
80
 
149
- return { topic, requestId, env };
81
+ return { topic, appId, env, requestId };
150
82
  }
151
83
 
152
84
  static async getOptions(event: TEvent, context: TContext): Promise<Dict<any>> {
85
+ let { options } = this.getMetadata(event, context);
86
+
87
+ if (!options) {
88
+ if (context?.eventType === 'google.storage.object.finalize') {
89
+ const gsEvent = event as TGSEvent;
90
+ const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
91
+ options = meta?.metadata?.options;
92
+ }
93
+ }
94
+
95
+ return JSON.parse(options ?? '{}');
96
+ }
97
+
98
+ static getMetadata(event: TEvent, context: TContext) {
99
+ let metadata: TMetadata | undefined;
100
+
153
101
  switch (context?.eventType) {
154
102
  case 'google.storage.object.finalize': {
155
103
  const gsEvent = event as TGSEvent;
156
- if (gsEvent?.metadata?.options) {
157
- return JSON.parse(gsEvent?.metadata?.options ?? '{}');
158
- } else {
159
- const file: File = storage.bucket(gsEvent.bucket).file(gsEvent.name);
160
- const [meta] = await file.getMetadata();
161
- return JSON.parse(meta?.metadata?.options ?? '{}');
162
- }
104
+ metadata = gsEvent?.metadata;
105
+ break;
163
106
  }
164
107
  case 'google.pubsub.topic.publish': {
165
108
  const psEvent = event as TPSEvent;
166
- return JSON.parse(psEvent?.attributes?.options ?? '{}');
109
+ metadata = psEvent?.attributes;
110
+ break;
167
111
  }
168
112
  }
113
+
114
+ return metadata ?? {};
169
115
  }
170
116
 
171
117
  static async getSecret(name: string, version?: string) {
@@ -179,4 +125,4 @@ export class GcfCommon {
179
125
  static async getSecrets(names: string[], versions?: string[]) {
180
126
  return Promise.all(names.map(async (name, idx) => this.getSecret(name, versions?.[idx]).catch()));
181
127
  }
182
- }
128
+ }
package/src/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/src/types.ts ADDED
@@ -0,0 +1,58 @@
1
+ import Dict = NodeJS.Dict;
2
+
3
+ export type TMetadata = {
4
+ topic?: string; // response topic [t_{GUID}__{YYYY-MM-DD}]
5
+ requestId?: string; // for rpc response [GUID]
6
+ env?: string; // app environment
7
+ appId?: string; // app id
8
+ options?: string;
9
+ }
10
+
11
+ export type TGSEvent = {
12
+ bucket: string;
13
+ contentType: string;
14
+ crc32c: string;
15
+ etag: string;
16
+ generation: string;
17
+ id: string;
18
+ kind: string; // 'storage#object'
19
+ md5Hash: string;
20
+ mediaLink: string;
21
+ metadata: TMetadata;
22
+ metageneration: string;
23
+ name: string;
24
+ selfLink: string;
25
+ size: string;
26
+ storageClass: string;
27
+ timeCreated: string;
28
+ timeStorageClassUpdated: string;
29
+ updated: string;
30
+ };
31
+
32
+ export type TPSEvent = {
33
+ '@type': string; // 'type.googleapis.com/google.pubsub.v1.PubsubMessage'
34
+ attributes?: TMetadata;
35
+ data?: string | Dict<any>;
36
+ };
37
+
38
+ export type TEvent = TGSEvent | TPSEvent;
39
+
40
+ export type TContext = {
41
+ eventId: string;
42
+ timestamp: string;
43
+ eventType: 'google.storage.object.finalize' | 'google.pubsub.topic.publish';
44
+ resource: {
45
+ service: 'storage.googleapis.com' | 'pubsub.googleapis.com';
46
+ type: 'storage#object' | 'type.googleapis.com/google.pubsub.v1.PubsubMessage';
47
+ name: string;
48
+ };
49
+ };
50
+
51
+ export type TResponse = {
52
+ [prop: string]: any;
53
+ error?: {
54
+ name: string;
55
+ message: string;
56
+ stack?: string;
57
+ };
58
+ };
package/src/utils.js CHANGED
@@ -9,21 +9,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.timeoutAfter = void 0;
12
+ exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.delay = exports.timeoutAfter = void 0;
13
13
  /**
14
14
  *
15
- * @param seconds Google function timeout limit (max: 9 min)
15
+ * @param seconds Google function v1 timeout limit (max: 9 min)
16
16
  */
17
17
  function timeoutAfter(seconds = 540) {
18
18
  return __awaiter(this, void 0, void 0, function* () {
19
19
  return new Promise((resolve, reject) => {
20
- setTimeout(() => {
21
- reject(new Error(`${seconds} seconds timeout exceeded`));
22
- }, seconds * 1000);
20
+ setTimeout(() => reject(new Error(`${seconds} seconds timeout exceeded`)), seconds * 1000);
23
21
  });
24
22
  });
25
23
  }
26
24
  exports.timeoutAfter = timeoutAfter;
25
+ function delay(seconds) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ return new Promise((resolve, reject) => {
28
+ setTimeout(() => resolve(undefined), seconds * 1000);
29
+ });
30
+ });
31
+ }
32
+ exports.delay = delay;
27
33
  //
28
34
  function indexToA1(idx) {
29
35
  return colNumToA1(idx + 1);
package/src/utils.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  *
3
- * @param seconds Google function timeout limit (max: 9 min)
3
+ * @param seconds Google function v1 timeout limit (max: 9 min)
4
4
  */
5
5
  export async function timeoutAfter(seconds: number = 540) {
6
6
  return new Promise<undefined>((resolve, reject) => {
7
- setTimeout(() => {
8
- reject(new Error(`${seconds} seconds timeout exceeded`));
9
- }, seconds * 1000);
7
+ setTimeout(() => reject(new Error(`${seconds} seconds timeout exceeded`)), seconds * 1000);
8
+ });
9
+ }
10
+
11
+ export async function delay(seconds: number) {
12
+ return new Promise<undefined>((resolve, reject) => {
13
+ setTimeout(() => resolve(undefined), seconds * 1000);
10
14
  });
11
15
  }
12
16