gcf-common-lib 0.24.36 → 0.25.37
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 +1 -1
- package/src/index.js +39 -78
- package/src/index.ts +47 -81
- package/src/types.ts +5 -3
- package/src/utils.js +10 -30
- package/src/utils.ts +7 -24
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -66,34 +66,39 @@ class GcfCommon {
|
|
|
66
66
|
*/
|
|
67
67
|
static process(event, context, handler, timeout = 535) {
|
|
68
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
-
return Promise.race([(0, utils_1.timeoutAfter)(timeout), handler(event, context)])
|
|
69
|
+
return Promise.race([(0, utils_1.timeoutAfter)(timeout), (handler !== null && handler !== void 0 ? handler : (() => Promise.resolve(undefined)))(event, context)])
|
|
70
70
|
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
71
71
|
// console.log('res:', res);
|
|
72
72
|
yield this.publish(event, context, res);
|
|
73
73
|
}))
|
|
74
74
|
.catch((err) => __awaiter(this, void 0, void 0, function* () {
|
|
75
|
-
|
|
76
|
-
const fname = (_b = (_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.K_SERVICE) !== null && _b !== void 0 ? _b : 'UNKNOWN';
|
|
77
|
-
const response = {
|
|
78
|
-
error: {
|
|
79
|
-
name: err.name,
|
|
80
|
-
message: `GCF [${fname}]: ${err.message}`,
|
|
81
|
-
stack: err.stack,
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
yield this.publish(event, context, response, { error: '1' }).catch(noop_1.default);
|
|
75
|
+
yield this.publish(event, context, GcfCommon.buildResponse(err), { error: '1' }).catch(noop_1.default);
|
|
85
76
|
throw err;
|
|
86
77
|
}));
|
|
87
78
|
});
|
|
88
79
|
}
|
|
80
|
+
static buildResponse(error) {
|
|
81
|
+
var _a, _b;
|
|
82
|
+
return {
|
|
83
|
+
error: {
|
|
84
|
+
name: error.name,
|
|
85
|
+
message: `GCF [${(_b = (_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.K_SERVICE) !== null && _b !== void 0 ? _b : 'UNKNOWN'}]: ${error.message}`,
|
|
86
|
+
stack: error.stack,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
89
90
|
static publish(event, context, json, attributes) {
|
|
90
91
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
const { topic, queue, appId, env, requestId } = yield this.
|
|
92
|
+
const { topic, exchange, queue, appId, env, requestId } = yield this.safeGetAttributes(event, context, [
|
|
93
|
+
'topic',
|
|
94
|
+
'exchange',
|
|
95
|
+
'queue',
|
|
96
|
+
]);
|
|
92
97
|
if (topic && !(0, isEmpty_1.default)(topic)) {
|
|
93
98
|
console.log('publish:', topic, appId, env, json, attributes);
|
|
94
99
|
return exports.pubSub.topic(topic).publishMessage({
|
|
95
100
|
json: json !== null && json !== void 0 ? json : {},
|
|
96
|
-
attributes: Object.assign(Object.assign({}, (0, lodash_1.mapValues)(attributes !== null && attributes !== void 0 ? attributes : {},
|
|
101
|
+
attributes: Object.assign(Object.assign({}, (0, lodash_1.mapValues)(attributes !== null && attributes !== void 0 ? attributes : {}, v => '' + v)), { appId: appId !== null && appId !== void 0 ? appId : '', env: env !== null && env !== void 0 ? env : '', requestId: requestId !== null && requestId !== void 0 ? requestId : '',
|
|
97
102
|
//
|
|
98
103
|
type: 'response', response: '1' }),
|
|
99
104
|
});
|
|
@@ -102,100 +107,55 @@ class GcfCommon {
|
|
|
102
107
|
console.log('send:', queue, appId, env, json, attributes);
|
|
103
108
|
return (0, utils_1.withAmqpCh)((ch) => __awaiter(this, void 0, void 0, function* () {
|
|
104
109
|
yield ch.assertQueue(queue, this.amqpOptions.assertOptions);
|
|
105
|
-
|
|
106
|
-
// ch.sendToQueue(queue, payload, this.amqpOptions.publishOptions);
|
|
107
|
-
yield (0, utils_1.sendToQueueAsync)(ch, queue, json !== null && json !== void 0 ? json : {}, this.amqpOptions.publishOptions);
|
|
110
|
+
yield (0, utils_1.publishAmqp)(ch, undefined, queue, json !== null && json !== void 0 ? json : {}, this.amqpOptions.publishOptions);
|
|
108
111
|
}), this.amqpOptions.url);
|
|
109
112
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (!_meta.topic && !_meta.queue && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
|
|
117
|
-
if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
|
|
118
|
-
const gsEvent = event;
|
|
119
|
-
const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
120
|
-
(_meta = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
topic: _meta.topic,
|
|
125
|
-
queue: _meta.queue,
|
|
126
|
-
env: _meta.env,
|
|
127
|
-
appId: (_c = _meta.appId) !== null && _c !== void 0 ? _c : _meta['app-id'],
|
|
128
|
-
requestId: (_d = _meta.requestId) !== null && _d !== void 0 ? _d : _meta['request-id'],
|
|
129
|
-
};
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
static getQueue(event, context) {
|
|
133
|
-
var _a, _b, _c, _d;
|
|
134
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
let _meta = this.getMetadata(event, context);
|
|
136
|
-
if (!_meta.queue && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
|
|
137
|
-
if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
|
|
138
|
-
const gsEvent = event;
|
|
139
|
-
const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
140
|
-
(_meta = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {});
|
|
141
|
-
}
|
|
113
|
+
if (exchange && !(0, isEmpty_1.default)(exchange)) {
|
|
114
|
+
console.log('send:', exchange, queue, appId, env, json, attributes);
|
|
115
|
+
return (0, utils_1.withAmqpCh)((ch) => __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
yield ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
|
|
117
|
+
yield (0, utils_1.publishAmqp)(ch, exchange, queue !== null && queue !== void 0 ? queue : '', json !== null && json !== void 0 ? json : {}, this.amqpOptions.publishOptions);
|
|
118
|
+
}), this.amqpOptions.url);
|
|
142
119
|
}
|
|
143
|
-
return {
|
|
144
|
-
queue: _meta.queue,
|
|
145
|
-
env: _meta.env,
|
|
146
|
-
appId: (_c = _meta.appId) !== null && _c !== void 0 ? _c : _meta['app-id'],
|
|
147
|
-
requestId: (_d = _meta.requestId) !== null && _d !== void 0 ? _d : _meta['request-id'],
|
|
148
|
-
};
|
|
149
120
|
});
|
|
150
121
|
}
|
|
151
|
-
static
|
|
122
|
+
static safeGetAttributes(event, context, props) {
|
|
152
123
|
var _a, _b, _c, _d;
|
|
153
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
-
let
|
|
155
|
-
|
|
125
|
+
let metaOrAttr = this.getMetadataOrAttribute(event, context);
|
|
126
|
+
const everyPropIsNil = props.map(prop => (0, lodash_1.get)(metaOrAttr, prop)).every(v => (0, lodash_1.isNil)(v));
|
|
127
|
+
// if no prop then check file metadata
|
|
128
|
+
if (everyPropIsNil && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
|
|
156
129
|
if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
|
|
157
130
|
const gsEvent = event;
|
|
158
131
|
const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
159
|
-
|
|
132
|
+
metaOrAttr = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {};
|
|
160
133
|
}
|
|
161
134
|
}
|
|
162
|
-
return {
|
|
163
|
-
topic: _meta.topic,
|
|
164
|
-
env: _meta.env,
|
|
165
|
-
appId: (_c = _meta.appId) !== null && _c !== void 0 ? _c : _meta['app-id'],
|
|
166
|
-
requestId: (_d = _meta.requestId) !== null && _d !== void 0 ? _d : _meta['request-id'],
|
|
167
|
-
};
|
|
135
|
+
return Object.assign(Object.assign({}, metaOrAttr), { appId: (_c = metaOrAttr.appId) !== null && _c !== void 0 ? _c : metaOrAttr['app-id'], requestId: (_d = metaOrAttr.requestId) !== null && _d !== void 0 ? _d : metaOrAttr['request-id'] });
|
|
168
136
|
});
|
|
169
137
|
}
|
|
170
138
|
static getOptions(event, context) {
|
|
171
|
-
var _a;
|
|
172
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
-
|
|
174
|
-
if (!options) {
|
|
175
|
-
if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
|
|
176
|
-
const gsEvent = event;
|
|
177
|
-
const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
178
|
-
options = (_a = meta === null || meta === void 0 ? void 0 : meta.metadata) === null || _a === void 0 ? void 0 : _a.options;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
140
|
+
const { options } = yield this.safeGetAttributes(event, context, ['options']);
|
|
181
141
|
return JSON.parse(options !== null && options !== void 0 ? options : '{}');
|
|
182
142
|
});
|
|
183
143
|
}
|
|
184
|
-
static
|
|
185
|
-
let
|
|
144
|
+
static getMetadataOrAttribute(event, context) {
|
|
145
|
+
let metadataOrAttribute;
|
|
186
146
|
switch (context === null || context === void 0 ? void 0 : context.eventType) {
|
|
187
147
|
case 'google.storage.object.finalize': {
|
|
188
148
|
const gsEvent = event;
|
|
189
|
-
|
|
149
|
+
metadataOrAttribute = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata;
|
|
190
150
|
break;
|
|
191
151
|
}
|
|
192
152
|
case 'google.pubsub.topic.publish': {
|
|
193
153
|
const psEvent = event;
|
|
194
|
-
|
|
154
|
+
metadataOrAttribute = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes;
|
|
195
155
|
break;
|
|
196
156
|
}
|
|
197
157
|
}
|
|
198
|
-
return
|
|
158
|
+
return metadataOrAttribute !== null && metadataOrAttribute !== void 0 ? metadataOrAttribute : {};
|
|
199
159
|
}
|
|
200
160
|
static getSecret(name, version) {
|
|
201
161
|
var _a, _b;
|
|
@@ -215,6 +175,7 @@ class GcfCommon {
|
|
|
215
175
|
}
|
|
216
176
|
exports.GcfCommon = GcfCommon;
|
|
217
177
|
GcfCommon.amqpOptions = {
|
|
178
|
+
assertExchange: { durable: true, autoDelete: false },
|
|
218
179
|
assertOptions: { durable: true, autoDelete: true, expires: (0, utils_1.ms)({ d: 1 }) },
|
|
219
180
|
publishOptions: { persistent: true },
|
|
220
181
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PubSub } from '@google-cloud/pubsub';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
3
|
import noop from 'lodash/noop';
|
|
4
|
-
import { ms,
|
|
4
|
+
import { ms, publishAmqp, timeoutAfter, withAmqpCh } from './utils';
|
|
5
5
|
import { Storage } from '@google-cloud/storage';
|
|
6
6
|
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
|
|
7
|
-
import { TContext, TEvent, TGSEvent,
|
|
8
|
-
import { mapValues } from 'lodash';
|
|
7
|
+
import { TContext, TEvent, TGSEvent, TMetadataOrAttributes, TPSEvent, TResponse } from './types';
|
|
8
|
+
import { get, isNil, mapValues } from 'lodash';
|
|
9
9
|
import { Options } from 'amqplib';
|
|
10
10
|
import Dict = NodeJS.Dict;
|
|
11
11
|
|
|
@@ -24,9 +24,11 @@ export const secretClient = new SecretManagerServiceClient();
|
|
|
24
24
|
export class GcfCommon {
|
|
25
25
|
static amqpOptions: {
|
|
26
26
|
url?: string;
|
|
27
|
+
assertExchange?: Options.AssertExchange;
|
|
27
28
|
assertOptions?: Options.AssertQueue;
|
|
28
29
|
publishOptions?: Options.Publish;
|
|
29
30
|
} = {
|
|
31
|
+
assertExchange: { durable: true, autoDelete: false },
|
|
30
32
|
assertOptions: { durable: true, autoDelete: true, expires: ms({ d: 1 }) },
|
|
31
33
|
publishOptions: { persistent: true },
|
|
32
34
|
};
|
|
@@ -41,37 +43,43 @@ export class GcfCommon {
|
|
|
41
43
|
static async process<T extends TResponse>(
|
|
42
44
|
event: TEvent,
|
|
43
45
|
context: TContext,
|
|
44
|
-
handler
|
|
46
|
+
handler?: (event: TEvent, context: TContext) => Promise<T>,
|
|
45
47
|
timeout = 535,
|
|
46
48
|
) {
|
|
47
|
-
return Promise.race([timeoutAfter(timeout), handler(event, context)])
|
|
49
|
+
return Promise.race([timeoutAfter(timeout), (handler ?? (() => Promise.resolve(undefined)))(event, context)])
|
|
48
50
|
.then(async (res: T | undefined) => {
|
|
49
51
|
// console.log('res:', res);
|
|
50
52
|
await this.publish(event, context, res);
|
|
51
53
|
})
|
|
52
54
|
.catch(async (err: Error) => {
|
|
53
|
-
|
|
54
|
-
const response: TResponse = {
|
|
55
|
-
error: {
|
|
56
|
-
name: err.name,
|
|
57
|
-
message: `GCF [${fname}]: ${err.message}`,
|
|
58
|
-
stack: err.stack,
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
await this.publish(event, context, response, { error: '1' }).catch(noop);
|
|
55
|
+
await this.publish(event, context, GcfCommon.buildResponse(err), { error: '1' }).catch(noop);
|
|
62
56
|
throw err;
|
|
63
57
|
});
|
|
64
58
|
}
|
|
65
59
|
|
|
60
|
+
static buildResponse(error: Error) {
|
|
61
|
+
return {
|
|
62
|
+
error: {
|
|
63
|
+
name: error.name,
|
|
64
|
+
message: `GCF [${process?.env?.K_SERVICE ?? 'UNKNOWN'}]: ${error.message}`,
|
|
65
|
+
stack: error.stack,
|
|
66
|
+
},
|
|
67
|
+
} as TResponse;
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
static async publish(event: TEvent, context: TContext, json?: TResponse, attributes?: Dict<any>) {
|
|
67
|
-
const { topic, queue, appId, env, requestId } = await this.
|
|
71
|
+
const { topic, exchange, queue, appId, env, requestId } = await this.safeGetAttributes(event, context, [
|
|
72
|
+
'topic',
|
|
73
|
+
'exchange',
|
|
74
|
+
'queue',
|
|
75
|
+
]);
|
|
68
76
|
|
|
69
77
|
if (topic && !isEmpty(topic)) {
|
|
70
78
|
console.log('publish:', topic, appId, env, json, attributes);
|
|
71
79
|
return pubSub.topic(topic).publishMessage({
|
|
72
80
|
json: json ?? {},
|
|
73
81
|
attributes: {
|
|
74
|
-
...mapValues(attributes ?? {},
|
|
82
|
+
...mapValues(attributes ?? {}, v => '' + v),
|
|
75
83
|
appId: appId ?? '',
|
|
76
84
|
env: env ?? '',
|
|
77
85
|
requestId: requestId ?? '',
|
|
@@ -86,103 +94,61 @@ export class GcfCommon {
|
|
|
86
94
|
console.log('send:', queue, appId, env, json, attributes);
|
|
87
95
|
return withAmqpCh(async ch => {
|
|
88
96
|
await ch.assertQueue(queue, this.amqpOptions.assertOptions);
|
|
89
|
-
|
|
90
|
-
// ch.sendToQueue(queue, payload, this.amqpOptions.publishOptions);
|
|
91
|
-
await sendToQueueAsync(ch, queue, json ?? {}, this.amqpOptions.publishOptions);
|
|
97
|
+
await publishAmqp(ch, undefined, queue, json ?? {}, this.amqpOptions.publishOptions);
|
|
92
98
|
}, this.amqpOptions.url as string);
|
|
93
99
|
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
static async getTopicAndQueue(event: TEvent, context: TContext) {
|
|
98
|
-
let _meta = this.getMetadata(event, context);
|
|
99
|
-
|
|
100
|
-
if (!_meta.topic && !_meta.queue && context?.resource?.type === 'storage#object') {
|
|
101
|
-
if (context?.eventType === 'google.storage.object.finalize') {
|
|
102
|
-
const gsEvent = event as TGSEvent;
|
|
103
|
-
const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
104
|
-
(_meta = meta?.metadata ?? {});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
topic: _meta.topic,
|
|
110
|
-
queue: _meta.queue,
|
|
111
|
-
env: _meta.env,
|
|
112
|
-
appId: _meta.appId ?? _meta['app-id'],
|
|
113
|
-
requestId: _meta.requestId ?? _meta['request-id'],
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
static async getQueue(event: TEvent, context: TContext) {
|
|
118
|
-
let _meta = this.getMetadata(event, context);
|
|
119
100
|
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
(
|
|
125
|
-
}
|
|
101
|
+
if (exchange && !isEmpty(exchange)) {
|
|
102
|
+
console.log('send:', exchange, queue, appId, env, json, attributes);
|
|
103
|
+
return withAmqpCh(async ch => {
|
|
104
|
+
await ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
|
|
105
|
+
await publishAmqp(ch, exchange, queue ?? '', json ?? {}, this.amqpOptions.publishOptions);
|
|
106
|
+
}, this.amqpOptions.url as string);
|
|
126
107
|
}
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
queue: _meta.queue,
|
|
130
|
-
env: _meta.env,
|
|
131
|
-
appId: _meta.appId ?? _meta['app-id'],
|
|
132
|
-
requestId: _meta.requestId ?? _meta['request-id'],
|
|
133
|
-
};
|
|
134
108
|
}
|
|
135
109
|
|
|
136
|
-
static async
|
|
137
|
-
let
|
|
110
|
+
static async safeGetAttributes(event: TEvent, context: TContext, props: string[]) {
|
|
111
|
+
let metaOrAttr = this.getMetadataOrAttribute(event, context);
|
|
112
|
+
const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
|
|
138
113
|
|
|
139
|
-
if
|
|
114
|
+
// if no prop then check file metadata
|
|
115
|
+
if (everyPropIsNil && context?.resource?.type === 'storage#object') {
|
|
140
116
|
if (context?.eventType === 'google.storage.object.finalize') {
|
|
141
117
|
const gsEvent = event as TGSEvent;
|
|
142
118
|
const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
143
|
-
|
|
119
|
+
metaOrAttr = meta?.metadata ?? {};
|
|
144
120
|
}
|
|
145
121
|
}
|
|
146
122
|
|
|
147
123
|
return {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
};
|
|
124
|
+
...metaOrAttr,
|
|
125
|
+
appId: metaOrAttr.appId ?? metaOrAttr['app-id'],
|
|
126
|
+
requestId: metaOrAttr.requestId ?? metaOrAttr['request-id'],
|
|
127
|
+
} as TMetadataOrAttributes;
|
|
153
128
|
}
|
|
154
129
|
|
|
155
130
|
static async getOptions(event: TEvent, context: TContext): Promise<Dict<any>> {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (!options) {
|
|
159
|
-
if (context?.eventType === 'google.storage.object.finalize') {
|
|
160
|
-
const gsEvent = event as TGSEvent;
|
|
161
|
-
const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
|
|
162
|
-
options = meta?.metadata?.options;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
131
|
+
const { options } = await this.safeGetAttributes(event, context, ['options']);
|
|
166
132
|
return JSON.parse(options ?? '{}');
|
|
167
133
|
}
|
|
168
134
|
|
|
169
|
-
static
|
|
170
|
-
let
|
|
135
|
+
static getMetadataOrAttribute(event: TEvent, context: TContext) {
|
|
136
|
+
let metadataOrAttribute: TMetadataOrAttributes | undefined;
|
|
171
137
|
|
|
172
138
|
switch (context?.eventType) {
|
|
173
139
|
case 'google.storage.object.finalize': {
|
|
174
140
|
const gsEvent = event as TGSEvent;
|
|
175
|
-
|
|
141
|
+
metadataOrAttribute = gsEvent?.metadata;
|
|
176
142
|
break;
|
|
177
143
|
}
|
|
178
144
|
case 'google.pubsub.topic.publish': {
|
|
179
145
|
const psEvent = event as TPSEvent;
|
|
180
|
-
|
|
146
|
+
metadataOrAttribute = psEvent?.attributes;
|
|
181
147
|
break;
|
|
182
148
|
}
|
|
183
149
|
}
|
|
184
150
|
|
|
185
|
-
return
|
|
151
|
+
return metadataOrAttribute ?? {};
|
|
186
152
|
}
|
|
187
153
|
|
|
188
154
|
static async getSecret(name: string, version?: string) {
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import Dict = NodeJS.Dict;
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type TMetadataOrAttributes = {
|
|
4
4
|
topic?: string; // response PubSub topic [t_{GUID}__{YYYY-MM-DD}]
|
|
5
|
+
exchange?: string; // response amqp exchange
|
|
5
6
|
queue?: string; // response amqp queue
|
|
7
|
+
//
|
|
6
8
|
env?: string; // app environment
|
|
7
9
|
appId?: string; // app id
|
|
8
10
|
'app-id'?: string; // app id
|
|
@@ -21,7 +23,7 @@ export type TGSEvent = {
|
|
|
21
23
|
kind: string; // 'storage#object'
|
|
22
24
|
md5Hash: string;
|
|
23
25
|
mediaLink: string;
|
|
24
|
-
metadata:
|
|
26
|
+
metadata: TMetadataOrAttributes;
|
|
25
27
|
metageneration: string;
|
|
26
28
|
name: string;
|
|
27
29
|
selfLink: string;
|
|
@@ -34,7 +36,7 @@ export type TGSEvent = {
|
|
|
34
36
|
|
|
35
37
|
export type TPSEvent = {
|
|
36
38
|
'@type': string; // 'type.googleapis.com/google.pubsub.v1.PubsubMessage'
|
|
37
|
-
attributes?:
|
|
39
|
+
attributes?: TMetadataOrAttributes;
|
|
38
40
|
data?: string | Dict<any>;
|
|
39
41
|
};
|
|
40
42
|
|
package/src/utils.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.sendToQueueConfAmqp = exports.publishAmqp = exports.withAmqpCh = exports.withAmqpConn = exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.sec = exports.ms = exports.delay = exports.timeoutAfter = void 0;
|
|
16
16
|
const amqplib_1 = require("amqplib");
|
|
17
17
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
18
18
|
const lodash_1 = require("lodash");
|
|
@@ -109,12 +109,12 @@ function withAmqpConn(fn, url) {
|
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
exports.withAmqpConn = withAmqpConn;
|
|
112
|
-
function withAmqpCh(fn, url) {
|
|
112
|
+
function withAmqpCh(fn, url, useConfirmChannel = false) {
|
|
113
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
114
114
|
return withAmqpConn((conn) => __awaiter(this, void 0, void 0, function* () {
|
|
115
115
|
function withDisposer() {
|
|
116
116
|
return bluebird_1.default.method(() => __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
return conn.createChannel();
|
|
117
|
+
return (useConfirmChannel ? conn.createConfirmChannel() : conn.createChannel());
|
|
118
118
|
}))().disposer((ch, promise) => ch.close());
|
|
119
119
|
}
|
|
120
120
|
return bluebird_1.default.using(withDisposer(), (ch) => fn(ch));
|
|
@@ -122,39 +122,19 @@ function withAmqpCh(fn, url) {
|
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
124
|
exports.withAmqpCh = withAmqpCh;
|
|
125
|
-
function
|
|
126
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
-
return withAmqpConn((conn) => __awaiter(this, void 0, void 0, function* () {
|
|
128
|
-
function withDisposer() {
|
|
129
|
-
return bluebird_1.default.method(() => __awaiter(this, void 0, void 0, function* () {
|
|
130
|
-
return conn.createConfirmChannel();
|
|
131
|
-
}))().disposer((ch, promise) => ch.close());
|
|
132
|
-
}
|
|
133
|
-
return bluebird_1.default.using(withDisposer(), (ch) => fn(ch));
|
|
134
|
-
}), url);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
exports.withAmqpConfCh = withAmqpConfCh;
|
|
138
|
-
function sendToQueueAsync(ch, queue, json, options) {
|
|
125
|
+
function publishAmqp(ch, exchange, routingKey, json, options) {
|
|
139
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
127
|
const payload = Buffer.from(JSON.stringify(json));
|
|
141
|
-
const keepSending = ch.sendToQueue(
|
|
128
|
+
const keepSending = exchange ? ch.publish(exchange, routingKey, payload, options) : ch.sendToQueue(routingKey, payload, options);
|
|
142
129
|
if (!keepSending)
|
|
143
|
-
yield new Promise(resolve => ch.once('drain', () => resolve));
|
|
130
|
+
yield new Promise(resolve => ch.once('drain', () => resolve(undefined)));
|
|
144
131
|
});
|
|
145
132
|
}
|
|
146
|
-
exports.
|
|
147
|
-
function
|
|
133
|
+
exports.publishAmqp = publishAmqp;
|
|
134
|
+
function sendToQueueConfAmqp(ch, queue, json, options) {
|
|
148
135
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
136
|
const payload = Buffer.from(JSON.stringify(json));
|
|
150
|
-
yield new Promise((resolve, reject) =>
|
|
151
|
-
ch.sendToQueue(queue, payload, options, (err, ok) => {
|
|
152
|
-
if (err)
|
|
153
|
-
reject(err);
|
|
154
|
-
else
|
|
155
|
-
resolve(ok);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
137
|
+
yield new Promise((resolve, reject) => ch.sendToQueue(queue, payload, options, (err, ok) => err ? reject(err) : resolve(ok)));
|
|
158
138
|
});
|
|
159
139
|
}
|
|
160
|
-
exports.
|
|
140
|
+
exports.sendToQueueConfAmqp = sendToQueueConfAmqp;
|
package/src/utils.ts
CHANGED
|
@@ -97,11 +97,11 @@ export async function withAmqpConn(fn: (conn: Connection) => Promise<any>, url:
|
|
|
97
97
|
return Bluebird.using(withDisposer(), (conn) => fn(conn));
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export async function withAmqpCh(fn: (ch: Channel) => Promise<any>, url: string) {
|
|
100
|
+
export async function withAmqpCh(fn: (ch: Channel) => Promise<any>, url: string, useConfirmChannel = false) {
|
|
101
101
|
return withAmqpConn(async conn => {
|
|
102
102
|
function withDisposer() {
|
|
103
103
|
return Bluebird.method(async () => {
|
|
104
|
-
return conn.createChannel();
|
|
104
|
+
return (useConfirmChannel ? conn.createConfirmChannel() : conn.createChannel());
|
|
105
105
|
})().disposer((ch, promise) => ch.close());
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -110,30 +110,13 @@ export async function withAmqpCh(fn: (ch: Channel) => Promise<any>, url: string)
|
|
|
110
110
|
}, url);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
export async function
|
|
114
|
-
return withAmqpConn(async conn => {
|
|
115
|
-
function withDisposer() {
|
|
116
|
-
return Bluebird.method(async () => {
|
|
117
|
-
return conn.createConfirmChannel();
|
|
118
|
-
})().disposer((ch, promise) => ch.close());
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return Bluebird.using(withDisposer(), (ch) => fn(ch));
|
|
122
|
-
|
|
123
|
-
}, url);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export async function sendToQueueAsync(ch: Channel, queue: string, json: Dictionary<any>, options?: Options.Publish) {
|
|
113
|
+
export async function publishAmqp(ch: Channel, exchange: string | undefined, routingKey: string, json: Dictionary<any>, options?: Options.Publish) {
|
|
127
114
|
const payload = Buffer.from(JSON.stringify(json));
|
|
128
|
-
const keepSending = ch.sendToQueue(
|
|
129
|
-
if (!keepSending) await new Promise(resolve => ch.once('drain', () => resolve));
|
|
115
|
+
const keepSending = exchange ? ch.publish(exchange, routingKey, payload, options) : ch.sendToQueue(routingKey, payload, options);
|
|
116
|
+
if (!keepSending) await new Promise(resolve => ch.once('drain', () => resolve(undefined)));
|
|
130
117
|
}
|
|
131
118
|
|
|
132
|
-
export async function
|
|
119
|
+
export async function sendToQueueConfAmqp(ch: ConfirmChannel, queue: string, json: Dictionary<any>, options?: Options.Publish) {
|
|
133
120
|
const payload = Buffer.from(JSON.stringify(json));
|
|
134
|
-
await new Promise((resolve, reject) =>
|
|
135
|
-
ch.sendToQueue(queue, payload, options, (err, ok) => {
|
|
136
|
-
if (err) reject(err); else resolve(ok);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
121
|
+
await new Promise((resolve, reject) => ch.sendToQueue(queue, payload, options, (err, ok) => err ? reject(err) : resolve(ok)));
|
|
139
122
|
}
|