gcf-common-lib 0.24.35 → 0.25.36

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.24.35",
4
+ "version": "0.25.36",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "branches": [
package/src/index.js CHANGED
@@ -88,12 +88,16 @@ class GcfCommon {
88
88
  }
89
89
  static publish(event, context, json, attributes) {
90
90
  return __awaiter(this, void 0, void 0, function* () {
91
- const { topic, queue, appId, env, requestId } = yield this.getTopicAndQueue(event, context);
91
+ const { topic, exchange, queue, appId, env, requestId } = yield this.safeGetAttributes(event, context, [
92
+ 'topic',
93
+ 'exchange',
94
+ 'queue',
95
+ ]);
92
96
  if (topic && !(0, isEmpty_1.default)(topic)) {
93
97
  console.log('publish:', topic, appId, env, json, attributes);
94
98
  return exports.pubSub.topic(topic).publishMessage({
95
99
  json: json !== null && json !== void 0 ? json : {},
96
- 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 : '',
100
+ 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
101
  //
98
102
  type: 'response', response: '1' }),
99
103
  });
@@ -102,100 +106,55 @@ class GcfCommon {
102
106
  console.log('send:', queue, appId, env, json, attributes);
103
107
  return (0, utils_1.withAmqpCh)((ch) => __awaiter(this, void 0, void 0, function* () {
104
108
  yield ch.assertQueue(queue, this.amqpOptions.assertOptions);
105
- // const payload = Buffer.from(JSON.stringify(json ?? {}));
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);
109
+ yield (0, utils_1.publishAmqp)(ch, undefined, queue, json !== null && json !== void 0 ? json : {}, this.amqpOptions.publishOptions);
108
110
  }), this.amqpOptions.url);
109
111
  }
110
- });
111
- }
112
- static getTopicAndQueue(event, context) {
113
- var _a, _b, _c, _d;
114
- return __awaiter(this, void 0, void 0, function* () {
115
- let _meta = this.getMetadata(event, context);
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
- }
112
+ if (exchange && !(0, isEmpty_1.default)(exchange)) {
113
+ console.log('send:', exchange, queue, appId, env, json, attributes);
114
+ return (0, utils_1.withAmqpCh)((ch) => __awaiter(this, void 0, void 0, function* () {
115
+ yield ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
116
+ yield (0, utils_1.publishAmqp)(ch, exchange, queue !== null && queue !== void 0 ? queue : '', json !== null && json !== void 0 ? json : {}, this.amqpOptions.publishOptions);
117
+ }), this.amqpOptions.url);
142
118
  }
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
119
  });
150
120
  }
151
- static getTopic(event, context) {
121
+ static safeGetAttributes(event, context, props) {
152
122
  var _a, _b, _c, _d;
153
123
  return __awaiter(this, void 0, void 0, function* () {
154
- let _meta = this.getMetadata(event, context);
155
- if (!_meta.topic && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
124
+ let metaOrAttr = this.getMetadataOrAttribute(event, context);
125
+ const everyPropIsNil = props.map(prop => (0, lodash_1.get)(metaOrAttr, prop)).every(v => (0, lodash_1.isNil)(v));
126
+ // if no prop then check file metadata
127
+ if (everyPropIsNil && ((_a = context === null || context === void 0 ? void 0 : context.resource) === null || _a === void 0 ? void 0 : _a.type) === 'storage#object') {
156
128
  if ((context === null || context === void 0 ? void 0 : context.eventType) === 'google.storage.object.finalize') {
157
129
  const gsEvent = event;
158
130
  const [meta] = yield exports.storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
159
- (_meta = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {});
131
+ metaOrAttr = (_b = meta === null || meta === void 0 ? void 0 : meta.metadata) !== null && _b !== void 0 ? _b : {};
160
132
  }
161
133
  }
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
- };
134
+ 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
135
  });
169
136
  }
170
137
  static getOptions(event, context) {
171
- var _a;
172
138
  return __awaiter(this, void 0, void 0, function* () {
173
- let { options } = this.getMetadata(event, context);
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
- }
139
+ const { options } = yield this.safeGetAttributes(event, context, ['options']);
181
140
  return JSON.parse(options !== null && options !== void 0 ? options : '{}');
182
141
  });
183
142
  }
184
- static getMetadata(event, context) {
185
- let metadata;
143
+ static getMetadataOrAttribute(event, context) {
144
+ let metadataOrAttribute;
186
145
  switch (context === null || context === void 0 ? void 0 : context.eventType) {
187
146
  case 'google.storage.object.finalize': {
188
147
  const gsEvent = event;
189
- metadata = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata;
148
+ metadataOrAttribute = gsEvent === null || gsEvent === void 0 ? void 0 : gsEvent.metadata;
190
149
  break;
191
150
  }
192
151
  case 'google.pubsub.topic.publish': {
193
152
  const psEvent = event;
194
- metadata = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes;
153
+ metadataOrAttribute = psEvent === null || psEvent === void 0 ? void 0 : psEvent.attributes;
195
154
  break;
196
155
  }
197
156
  }
198
- return metadata !== null && metadata !== void 0 ? metadata : {};
157
+ return metadataOrAttribute !== null && metadataOrAttribute !== void 0 ? metadataOrAttribute : {};
199
158
  }
200
159
  static getSecret(name, version) {
201
160
  var _a, _b;
@@ -215,6 +174,7 @@ class GcfCommon {
215
174
  }
216
175
  exports.GcfCommon = GcfCommon;
217
176
  GcfCommon.amqpOptions = {
177
+ assertExchange: { durable: true, autoDelete: false },
218
178
  assertOptions: { durable: true, autoDelete: true, expires: (0, utils_1.ms)({ d: 1 }) },
219
179
  publishOptions: { persistent: true },
220
180
  };
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, sendToQueueAsync, timeoutAfter, withAmqpCh } from './utils';
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, TMetadata, TPSEvent, TResponse } from './types';
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
  };
@@ -64,14 +66,18 @@ export class GcfCommon {
64
66
  }
65
67
 
66
68
  static async publish(event: TEvent, context: TContext, json?: TResponse, attributes?: Dict<any>) {
67
- const { topic, queue, appId, env, requestId } = await this.getTopicAndQueue(event, context);
69
+ const { topic, exchange, queue, appId, env, requestId } = await this.safeGetAttributes(event, context, [
70
+ 'topic',
71
+ 'exchange',
72
+ 'queue',
73
+ ]);
68
74
 
69
75
  if (topic && !isEmpty(topic)) {
70
76
  console.log('publish:', topic, appId, env, json, attributes);
71
77
  return pubSub.topic(topic).publishMessage({
72
78
  json: json ?? {},
73
79
  attributes: {
74
- ...mapValues(attributes ?? {}, (v) => '' + v),
80
+ ...mapValues(attributes ?? {}, v => '' + v),
75
81
  appId: appId ?? '',
76
82
  env: env ?? '',
77
83
  requestId: requestId ?? '',
@@ -86,103 +92,61 @@ export class GcfCommon {
86
92
  console.log('send:', queue, appId, env, json, attributes);
87
93
  return withAmqpCh(async ch => {
88
94
  await ch.assertQueue(queue, this.amqpOptions.assertOptions);
89
- // const payload = Buffer.from(JSON.stringify(json ?? {}));
90
- // ch.sendToQueue(queue, payload, this.amqpOptions.publishOptions);
91
- await sendToQueueAsync(ch, queue, json ?? {}, this.amqpOptions.publishOptions);
95
+ await publishAmqp(ch, undefined, queue, json ?? {}, this.amqpOptions.publishOptions);
92
96
  }, this.amqpOptions.url as string);
93
97
  }
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
98
 
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
-
120
- if (!_meta.queue && context?.resource?.type === 'storage#object') {
121
- if (context?.eventType === 'google.storage.object.finalize') {
122
- const gsEvent = event as TGSEvent;
123
- const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
124
- (_meta = meta?.metadata ?? {});
125
- }
99
+ if (exchange && !isEmpty(exchange)) {
100
+ console.log('send:', exchange, queue, appId, env, json, attributes);
101
+ return withAmqpCh(async ch => {
102
+ await ch.assertExchange(exchange, 'direct', this.amqpOptions.assertExchange);
103
+ await publishAmqp(ch, exchange, queue ?? '', json ?? {}, this.amqpOptions.publishOptions);
104
+ }, this.amqpOptions.url as string);
126
105
  }
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
106
  }
135
107
 
136
- static async getTopic(event: TEvent, context: TContext) {
137
- let _meta = this.getMetadata(event, context);
108
+ static async safeGetAttributes(event: TEvent, context: TContext, props: string[]) {
109
+ let metaOrAttr = this.getMetadataOrAttribute(event, context);
110
+ const everyPropIsNil = props.map(prop => get(metaOrAttr, prop)).every(v => isNil(v));
138
111
 
139
- if (!_meta.topic && context?.resource?.type === 'storage#object') {
112
+ // if no prop then check file metadata
113
+ if (everyPropIsNil && context?.resource?.type === 'storage#object') {
140
114
  if (context?.eventType === 'google.storage.object.finalize') {
141
115
  const gsEvent = event as TGSEvent;
142
116
  const [meta] = await storage.bucket(gsEvent.bucket).file(gsEvent.name).getMetadata();
143
- (_meta = meta?.metadata ?? {});
117
+ metaOrAttr = meta?.metadata ?? {};
144
118
  }
145
119
  }
146
120
 
147
121
  return {
148
- topic: _meta.topic,
149
- env: _meta.env,
150
- appId: _meta.appId ?? _meta['app-id'],
151
- requestId: _meta.requestId ?? _meta['request-id'],
152
- };
122
+ ...metaOrAttr,
123
+ appId: metaOrAttr.appId ?? metaOrAttr['app-id'],
124
+ requestId: metaOrAttr.requestId ?? metaOrAttr['request-id'],
125
+ } as TMetadataOrAttributes;
153
126
  }
154
127
 
155
128
  static async getOptions(event: TEvent, context: TContext): Promise<Dict<any>> {
156
- let { options } = this.getMetadata(event, context);
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
-
129
+ const { options } = await this.safeGetAttributes(event, context, ['options']);
166
130
  return JSON.parse(options ?? '{}');
167
131
  }
168
132
 
169
- static getMetadata(event: TEvent, context: TContext) {
170
- let metadata: TMetadata | undefined;
133
+ static getMetadataOrAttribute(event: TEvent, context: TContext) {
134
+ let metadataOrAttribute: TMetadataOrAttributes | undefined;
171
135
 
172
136
  switch (context?.eventType) {
173
137
  case 'google.storage.object.finalize': {
174
138
  const gsEvent = event as TGSEvent;
175
- metadata = gsEvent?.metadata;
139
+ metadataOrAttribute = gsEvent?.metadata;
176
140
  break;
177
141
  }
178
142
  case 'google.pubsub.topic.publish': {
179
143
  const psEvent = event as TPSEvent;
180
- metadata = psEvent?.attributes;
144
+ metadataOrAttribute = psEvent?.attributes;
181
145
  break;
182
146
  }
183
147
  }
184
148
 
185
- return metadata ?? {};
149
+ return metadataOrAttribute ?? {};
186
150
  }
187
151
 
188
152
  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 TMetadata = {
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: TMetadata;
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?: TMetadata;
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.sendToQueueConfAsync = exports.sendToQueueAsync = exports.withAmqpConfCh = exports.withAmqpCh = exports.withAmqpConn = exports.A1ToColNum = exports.colNumToA1 = exports.A1ToIndex = exports.indexToA1 = exports.sec = exports.ms = exports.delay = exports.timeoutAfter = void 0;
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 withAmqpConfCh(fn, url) {
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(queue, payload, options);
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.sendToQueueAsync = sendToQueueAsync;
147
- function sendToQueueConfAsync(ch, queue, json, options) {
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.sendToQueueConfAsync = sendToQueueConfAsync;
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 withAmqpConfCh(fn: (ch: ConfirmChannel) => Promise<any>, url: string) {
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(queue, payload, options);
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 sendToQueueConfAsync(ch: ConfirmChannel, queue: string, json: Dictionary<any>, options?: Options.Publish) {
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
  }