gcf-common-lib 0.31.62 → 0.32.63
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/eslint.config.mjs +33 -0
- package/package.json +13 -13
- package/src/index.ts +35 -51
- package/src/types.ts +8 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
import pluginJs from '@eslint/js';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
|
5
|
+
import pluginPromise from 'eslint-plugin-promise';
|
|
6
|
+
// import pluginLodash from 'eslint-plugin-lodash';
|
|
7
|
+
|
|
8
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
9
|
+
export default [
|
|
10
|
+
{ files: ['**/*.{js,mjs,cjs,ts}'] },
|
|
11
|
+
{ files: ['**/*.js'], languageOptions: { sourceType: 'commonjs' } },
|
|
12
|
+
{ languageOptions: { globals: globals.node } },
|
|
13
|
+
pluginJs.configs.recommended,
|
|
14
|
+
...tseslint.configs.recommended,
|
|
15
|
+
eslintPluginUnicorn.configs.recommended,
|
|
16
|
+
pluginPromise.configs['flat/recommended'],
|
|
17
|
+
// pluginLodash.configs.recommended,
|
|
18
|
+
{
|
|
19
|
+
rules: {
|
|
20
|
+
'block-scoped-var': 'error',
|
|
21
|
+
'no-loop-func': 'error',
|
|
22
|
+
//
|
|
23
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
24
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
25
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
26
|
+
'@typescript-eslint/no-empty-interface': 'off',
|
|
27
|
+
//
|
|
28
|
+
'unicorn/prevent-abbreviations': 'off',
|
|
29
|
+
// 'lodash/prefer-lodash-method': 'off',
|
|
30
|
+
// 'rxjs/no-implicit-any-catch': 'off',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gcf-common-lib",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.32.63",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"branches": [
|
|
@@ -20,12 +20,14 @@
|
|
|
20
20
|
"url": "https://github.com/TopTechnologies/gcf-common.git"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"@google-cloud/pubsub": "^4.4.0",
|
|
24
|
+
"@google-cloud/storage": "^7.11.0",
|
|
25
|
+
"@tsconfig/node18": "^18.2.4",
|
|
23
26
|
"@types/amqplib": "^0.10.5",
|
|
24
27
|
"@types/bluebird": "^3.5.42",
|
|
28
|
+
"@types/express": "^4.17.21",
|
|
25
29
|
"@types/lodash": "^4.17.1",
|
|
26
30
|
"@types/node": "^18.19.32",
|
|
27
|
-
"@google-cloud/pubsub": "^4.4.0",
|
|
28
|
-
"@google-cloud/storage": "^7.11.0",
|
|
29
31
|
"amqplib": "^0.10.4",
|
|
30
32
|
"bluebird": "^3.7.2",
|
|
31
33
|
"lodash": "^4.17.21",
|
|
@@ -34,16 +36,14 @@
|
|
|
34
36
|
"rxjs": "^7.8.1"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"eslint": "^
|
|
41
|
-
"eslint-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"eslint
|
|
45
|
-
"eslint-plugin-rxjs": "^5.0.3",
|
|
46
|
-
"eslint-plugin-unicorn": "^52.0.0"
|
|
39
|
+
"@eslint/js": "^9.21.0",
|
|
40
|
+
"eslint": "^9.21.0",
|
|
41
|
+
"eslint-plugin-lodash": "^8.0.0",
|
|
42
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
43
|
+
"eslint-plugin-unicorn": "^57.0.0",
|
|
44
|
+
"globals": "^15.15.0",
|
|
45
|
+
"prettier": "^3.5.2",
|
|
46
|
+
"typescript-eslint": "^8.25.0"
|
|
47
47
|
},
|
|
48
48
|
"author": "alert83@gmail.com",
|
|
49
49
|
"license": ""
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { PubSub } from '@google-cloud/pubsub';
|
|
2
2
|
import { Storage } from '@google-cloud/storage';
|
|
3
3
|
import { Options } from 'amqplib';
|
|
4
|
+
import { Request } from 'express';
|
|
4
5
|
import isEmpty from 'lodash/isEmpty';
|
|
5
6
|
import mapValues from 'lodash/mapValues';
|
|
6
7
|
import noop from 'lodash/noop';
|
|
7
8
|
import { defer, first, firstValueFrom, from, identity, timeout } from 'rxjs';
|
|
8
9
|
import { AmqpHelper } from './amqp-helper';
|
|
9
|
-
import {
|
|
10
|
+
import { TEvent, TGSEvent, TMetadataOrAttributes, TPayload, TPSEvent, TResponse } from './types';
|
|
10
11
|
import { ms, safeJsonParse } from './utils';
|
|
11
12
|
import Dict = NodeJS.Dict;
|
|
12
13
|
|
|
@@ -35,52 +36,26 @@ export class GcfCommon {
|
|
|
35
36
|
publishOptions: { persistent: true },
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
/**
|
|
39
|
-
*
|
|
40
|
-
* @param {!TEvent} event Event payload.
|
|
41
|
-
* @param {!TContext} context Metadata for the event.
|
|
42
|
-
* @param handler
|
|
43
|
-
* @param timeoutSec Seconds
|
|
44
|
-
*/
|
|
45
39
|
static async process<T extends TResponse, E = TEvent>(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
handler: (event: E, context: TContext) => Promise<T | E> | T | E = identity,
|
|
40
|
+
payload: TPayload<E>,
|
|
41
|
+
handler: (payload: TPayload<E>) => Promise<any> | any = identity,
|
|
49
42
|
timeoutSec = 535,
|
|
50
43
|
) {
|
|
51
|
-
const asyncHandler = async (
|
|
44
|
+
const asyncHandler = async (p: TPayload<E>) => await handler(p);
|
|
52
45
|
return firstValueFrom(
|
|
53
|
-
defer(() => from(asyncHandler(
|
|
46
|
+
defer(() => from(asyncHandler(payload))).pipe(first(), timeout({ first: ms({ s: timeoutSec }) })),
|
|
54
47
|
)
|
|
55
48
|
.then(async res => {
|
|
56
49
|
// console.log('res:', res);
|
|
57
|
-
await this.response(
|
|
50
|
+
await this.response(payload, res as T).catch(noop);
|
|
58
51
|
return res;
|
|
59
52
|
})
|
|
60
53
|
.catch(async (error: Error) => {
|
|
61
|
-
await this.response(
|
|
54
|
+
await this.response(payload, GcfCommon.buildResponse(error), { error: '1' }).catch(noop);
|
|
62
55
|
throw error;
|
|
63
56
|
});
|
|
64
57
|
}
|
|
65
58
|
|
|
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
|
-
|
|
84
59
|
static buildResponse(error: Error) {
|
|
85
60
|
return {
|
|
86
61
|
error: {
|
|
@@ -91,7 +66,7 @@ export class GcfCommon {
|
|
|
91
66
|
} as TResponse;
|
|
92
67
|
}
|
|
93
68
|
|
|
94
|
-
static async response<E = TEvent>(
|
|
69
|
+
static async response<E = TEvent>(payload: TPayload<E>, json?: TResponse, attributes?: Dict<any>) {
|
|
95
70
|
// console.time('safeGetAttributes');
|
|
96
71
|
// const { topic, exchange, queue, consumer_id, request_id, app_id, env } = await this.safeGetAttributes(
|
|
97
72
|
// event,
|
|
@@ -100,10 +75,7 @@ export class GcfCommon {
|
|
|
100
75
|
// );
|
|
101
76
|
// console.timeEnd('safeGetAttributes');
|
|
102
77
|
|
|
103
|
-
const { topic, exchange, queue, consumer_id, request_id, app_id, env } = this.getMetadataOrAttribute(
|
|
104
|
-
event,
|
|
105
|
-
context,
|
|
106
|
-
);
|
|
78
|
+
const { topic, exchange, queue, consumer_id, request_id, app_id, env } = this.getMetadataOrAttribute(payload);
|
|
107
79
|
|
|
108
80
|
//
|
|
109
81
|
|
|
@@ -168,31 +140,43 @@ export class GcfCommon {
|
|
|
168
140
|
// } as TMetadataOrAttributes;
|
|
169
141
|
// }
|
|
170
142
|
|
|
171
|
-
static async getOptions(
|
|
143
|
+
static async getOptions(payload: TPayload): Promise<Dict<any>> {
|
|
172
144
|
// const { options } = await this.safeGetAttributes(event, context, ['options']);
|
|
173
|
-
const { options } = this.getMetadataOrAttribute(
|
|
145
|
+
const { options } = this.getMetadataOrAttribute(payload);
|
|
174
146
|
return safeJsonParse(options as any, {} as any);
|
|
175
147
|
}
|
|
176
148
|
|
|
177
|
-
static getMetadataOrAttribute<E = TEvent>(
|
|
149
|
+
static getMetadataOrAttribute<E = TEvent>(payload: TPayload<E>) {
|
|
178
150
|
let metadataOrAttribute: TMetadataOrAttributes | undefined;
|
|
179
151
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
152
|
+
if (payload?.context) {
|
|
153
|
+
switch (payload?.context?.eventType) {
|
|
154
|
+
case 'google.storage.object.finalize': {
|
|
155
|
+
const gsEvent = payload?.event as TGSEvent;
|
|
156
|
+
metadataOrAttribute = gsEvent?.metadata;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case 'google.pubsub.topic.publish': {
|
|
160
|
+
const psEvent = payload?.event as TPSEvent;
|
|
161
|
+
metadataOrAttribute = psEvent?.attributes;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
190
164
|
}
|
|
191
165
|
}
|
|
192
166
|
|
|
167
|
+
if (payload?.request) {
|
|
168
|
+
metadataOrAttribute = this.getRequestMessage(payload.request)?.attributes;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log('metadataOrAttribute:', metadataOrAttribute);
|
|
172
|
+
|
|
193
173
|
return metadataOrAttribute ?? {};
|
|
194
174
|
}
|
|
195
175
|
|
|
176
|
+
static getRequestMessage(request: Request) {
|
|
177
|
+
return request.body.message as { attributes: TMetadataOrAttributes; data: string; json?: Dict<any> };
|
|
178
|
+
}
|
|
179
|
+
|
|
196
180
|
// static async getSecret(name: string, version?: string) {
|
|
197
181
|
// const projectId = await secretClient.getProjectId();
|
|
198
182
|
// const secretName = `projects/${projectId}/secrets/${name}`;
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import Dict = NodeJS.Dict;
|
|
2
|
+
import { Request, Response } from 'express';
|
|
3
|
+
|
|
4
|
+
export type TPayload<E = TEvent> = {
|
|
5
|
+
event?: E;
|
|
6
|
+
context?: TContext;
|
|
7
|
+
request?: Request;
|
|
8
|
+
response?: Response;
|
|
9
|
+
};
|
|
2
10
|
|
|
3
11
|
export type TGSEvent<M = TMetadataOrAttributes> = {
|
|
4
12
|
bucket: string;
|