@anchan828/nest-cloud-run-queue-worker 1.0.10 → 1.0.13

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ALL_WORKERS_QUEUE_WORKER_NAME as ALL_QUEUE_WORKERS, UNHANDLED_QUEUE_WORKER_NAME as UNHANDLED_QUEUE_WORKER, } from "./constants";
2
2
  export { QueueWorker, QueueWorkerProcess } from "./decorators";
3
- export { QueueWorkerModuleAsyncOptions, QueueWorkerModuleOptions, QueueWorkerModuleOptionsFactory, QueueWorkerProcessor, QueueWorkerProcessorStatus, QueueWorkerExtraConfig, QueueWorkerRawMessage, QueueWorkerControllerInterface, QueueWorkerControllerMetadata, QueueWorkerReceivedMessage, } from "./interfaces";
3
+ export { QueueWorkerModuleAsyncOptions, QueueWorkerModuleOptions, QueueWorkerModuleOptionsFactory, QueueWorkerProcessor, QueueWorkerProcessorStatus, QueueWorkerExtraConfig, QueueWorkerRawMessage, QueueWorkerControllerInterface, QueueWorkerControllerMetadata, QueueWorkerReceivedMessage, QueueWorkerDecodedMessage, } from "./interfaces";
4
4
  export { QueueWorkerModule } from "./worker.module";
5
5
  export { QueueWorkerService } from "./worker.service";
@@ -1,5 +1,4 @@
1
- /// <reference types="node" />
2
- import { QueueWorkerName, ModuleAsyncOptions, ModuleOptions, ModuleOptionsFactory } from "@anchan828/nest-cloud-run-queue-common";
1
+ import { QueueWorkerName, ModuleAsyncOptions, ModuleOptions, ModuleOptionsFactory, Message } from "@anchan828/nest-cloud-run-queue-common";
3
2
  import { RequestMappingMetadata } from "@nestjs/common";
4
3
  import { Injectable } from "@nestjs/common/interfaces";
5
4
  export interface QueueWorkerModuleOptions extends ModuleOptions {
@@ -35,7 +34,7 @@ export interface QueueWorkerModuleOptions extends ModuleOptions {
35
34
  }
36
35
  export declare type QueueWorkerModuleAsyncOptions = ModuleAsyncOptions<Omit<QueueWorkerModuleOptions, "workerController">> & Pick<QueueWorkerModuleOptions, "workerController">;
37
36
  export declare type QueueWorkerModuleOptionsFactory = ModuleOptionsFactory<Omit<QueueWorkerModuleOptions, "workerController">> & Pick<QueueWorkerModuleOptions, "workerController">;
38
- export declare type QueueWorkerProcessor = <T>(message: T, rawMessage: QueueWorkerRawMessage) => Promise<void> | void;
37
+ export declare type QueueWorkerProcessor = <T>(message: T, raw: QueueWorkerRawMessage) => Promise<void> | void;
39
38
  export interface QueueWorkerMetadata {
40
39
  instance: Injectable;
41
40
  processors: QueueWorkerProcessorMetadata[];
@@ -72,10 +71,15 @@ export interface QueueWorkerProcessDecoratorArgs {
72
71
  */
73
72
  priority: number;
74
73
  }
75
- export declare type QueueWorkerRawMessage<T = Record<string, any>> = {
76
- readonly data?: string | Uint8Array | Buffer | null;
74
+ export declare type QueueWorkerRawMessage<T = any> = {
75
+ readonly data?: string | null | Message<T>;
77
76
  readonly headers?: Record<string, string>;
78
- } & T;
77
+ } & Record<string, any>;
78
+ export declare type QueueWorkerDecodedMessage<T = any> = {
79
+ readonly data: Message<T>;
80
+ readonly headers?: Record<string, string>;
81
+ readonly raw: QueueWorkerRawMessage;
82
+ };
79
83
  export declare type QueueWorkerReceivedMessage = {
80
84
  readonly message: QueueWorkerRawMessage;
81
85
  };
package/dist/util.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Message } from "@anchan828/nest-cloud-run-queue-common";
1
2
  /**
2
3
  * parse json string to javascript object.
3
4
  * JSON.parse has receiver for Date.parse.
@@ -15,3 +16,11 @@ export declare const parseJSON: <T>(json: string) => T;
15
16
  export declare function sortByPriority<T extends {
16
17
  priority: number;
17
18
  }>(items: T[]): T[];
19
+ /**
20
+ * Check if a string is base64 encoded.
21
+ *
22
+ * @export
23
+ * @param {string} value
24
+ * @return {*} {boolean}
25
+ */
26
+ export declare function isBase64(value?: string | null | Message): value is string;
package/dist/util.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sortByPriority = exports.parseJSON = void 0;
3
+ exports.isBase64 = exports.sortByPriority = exports.parseJSON = void 0;
4
4
  const dateRegExp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
5
5
  /**
6
6
  * parse json string to javascript object.
@@ -31,3 +31,29 @@ function sortByPriority(items) {
31
31
  return items.sort((x, y) => x.priority - y.priority);
32
32
  }
33
33
  exports.sortByPriority = sortByPriority;
34
+ const customBase64Strs = ["e30"];
35
+ /**
36
+ * Check if a string is base64 encoded.
37
+ *
38
+ * @export
39
+ * @param {string} value
40
+ * @return {*} {boolean}
41
+ */
42
+ function isBase64(value) {
43
+ if (!value) {
44
+ return false;
45
+ }
46
+ if (typeof value !== "string") {
47
+ return false;
48
+ }
49
+ const len = value.length;
50
+ if (len <= 4 && customBase64Strs.some((base64Str) => value.startsWith(base64Str))) {
51
+ return true;
52
+ }
53
+ if ((len === 4 && ![2, 3].every((n) => value[n] === "=")) || !len || len % 4 !== 0 || /[^A-Z0-9+\/=]/i.test(value)) {
54
+ return false;
55
+ }
56
+ const firstPaddingChar = value.indexOf("=");
57
+ return (firstPaddingChar === -1 || firstPaddingChar === len - 1 || (firstPaddingChar === len - 2 && value[len - 1] === "="));
58
+ }
59
+ exports.isBase64 = isBase64;
@@ -1,5 +1,5 @@
1
1
  import { Logger } from "@nestjs/common";
2
- import { QueueWorkerModuleOptions } from "./interfaces";
2
+ import { QueueWorkerDecodedMessage, QueueWorkerModuleOptions } from "./interfaces";
3
3
  import { QueueWorkerExplorerService } from "./explorer.service";
4
4
  import { QueueWorkerRawMessage } from "./interfaces";
5
5
  export declare class QueueWorkerService {
@@ -8,7 +8,10 @@ export declare class QueueWorkerService {
8
8
  private readonly logger;
9
9
  private readonly explorerService;
10
10
  constructor(options: QueueWorkerModuleOptions, logger: Logger, explorerService: QueueWorkerExplorerService);
11
- execute(message: QueueWorkerRawMessage): Promise<void>;
12
- private execProcessor;
11
+ execute(rawMessage: QueueWorkerRawMessage | QueueWorkerDecodedMessage): Promise<void>;
12
+ decodeMessage<T = any>(message: QueueWorkerRawMessage): QueueWorkerDecodedMessage<T>;
13
+ private runWorkers;
14
+ private isDecodedMessage;
13
15
  private decodeData;
16
+ private execProcessor;
14
17
  }
@@ -31,11 +31,10 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
31
31
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
32
32
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
33
33
  };
34
- var _QueueWorkerService_allWorkers;
34
+ var _QueueWorkerService_instances, _QueueWorkerService__allWorkers, _QueueWorkerService_allWorkers_get, _QueueWorkerService_spetialWorkers_get;
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.QueueWorkerService = void 0;
37
37
  const common_1 = require("@nestjs/common");
38
- const class_validator_1 = require("class-validator");
39
38
  const constants_1 = require("./constants");
40
39
  const explorer_service_1 = require("./explorer.service");
41
40
  const interfaces_1 = require("./interfaces");
@@ -45,70 +44,67 @@ let QueueWorkerService = class QueueWorkerService {
45
44
  this.options = options;
46
45
  this.logger = logger;
47
46
  this.explorerService = explorerService;
48
- _QueueWorkerService_allWorkers.set(this, void 0);
47
+ _QueueWorkerService_instances.add(this);
48
+ _QueueWorkerService__allWorkers.set(this, void 0);
49
49
  }
50
50
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
51
- execute(message) {
51
+ execute(rawMessage) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ yield this.runWorkers(this.isDecodedMessage(rawMessage) ? rawMessage : this.decodeMessage(rawMessage));
54
+ });
55
+ }
56
+ decodeMessage(message) {
57
+ let data;
58
+ if ((0, util_1.isBase64)(message.data)) {
59
+ // pubsub
60
+ data = this.decodeData(message.data);
61
+ }
62
+ else {
63
+ // tasks / http
64
+ data = message;
65
+ }
66
+ if (!data.name) {
67
+ throw new common_1.BadRequestException(constants_1.ERROR_QUEUE_WORKER_NAME_NOT_FOUND);
68
+ }
69
+ return {
70
+ data,
71
+ headers: message.headers,
72
+ raw: message,
73
+ };
74
+ }
75
+ runWorkers(decodedMessage) {
52
76
  var _a, _b, _c, _d, _e, _f;
53
77
  return __awaiter(this, void 0, void 0, function* () {
54
- if (!__classPrivateFieldGet(this, _QueueWorkerService_allWorkers, "f")) {
55
- __classPrivateFieldSet(this, _QueueWorkerService_allWorkers, this.explorerService.explore(), "f");
56
- }
57
78
  const maxRetryAttempts = (_a = this.options.maxRetryAttempts) !== null && _a !== void 0 ? _a : 1;
58
79
  const workers = [];
59
- const spetialWorkers = [];
60
- let data = { name: "" };
61
- try {
62
- data = this.decodeData(message.data);
63
- if (!data.name) {
64
- throw new Error(constants_1.ERROR_QUEUE_WORKER_NAME_NOT_FOUND);
65
- }
66
- workers.push(...__classPrivateFieldGet(this, _QueueWorkerService_allWorkers, "f").filter((worker) => data.name === worker.name));
67
- spetialWorkers.push(...__classPrivateFieldGet(this, _QueueWorkerService_allWorkers, "f").filter((worker) => [constants_1.ALL_WORKERS_QUEUE_WORKER_NAME, constants_1.UNHANDLED_QUEUE_WORKER_NAME].includes(worker.name)));
68
- if (workers.length === 0) {
69
- throw new Error((0, constants_1.ERROR_WORKER_NOT_FOUND)(data.name));
70
- }
71
- }
72
- catch (error) {
73
- this.logger.error(error.message);
74
- if (((_b = this.options) === null || _b === void 0 ? void 0 : _b.throwModuleError) && spetialWorkers.length === 0) {
75
- throw new common_1.BadRequestException(error.message);
76
- }
80
+ workers.push(...__classPrivateFieldGet(this, _QueueWorkerService_instances, "a", _QueueWorkerService_allWorkers_get).filter((worker) => decodedMessage.data.name === worker.name));
81
+ if (((_b = this.options) === null || _b === void 0 ? void 0 : _b.throwModuleError) && workers.length === 0 && __classPrivateFieldGet(this, _QueueWorkerService_instances, "a", _QueueWorkerService_spetialWorkers_get).length === 0) {
82
+ throw new common_1.BadRequestException((0, constants_1.ERROR_WORKER_NOT_FOUND)(decodedMessage.data.name));
77
83
  }
78
84
  const processors = (0, util_1.sortByPriority)(workers)
79
85
  .map((w) => (0, util_1.sortByPriority)(w.processors))
80
86
  .flat();
81
- const spetialProcessors = (0, util_1.sortByPriority)(spetialWorkers)
87
+ const spetialProcessors = (0, util_1.sortByPriority)(__classPrivateFieldGet(this, _QueueWorkerService_instances, "a", _QueueWorkerService_spetialWorkers_get))
82
88
  .map((w) => (0, util_1.sortByPriority)(w.processors))
83
89
  .flat();
84
- const processorStatus = yield ((_d = (_c = this.options.extraConfig) === null || _c === void 0 ? void 0 : _c.preProcessor) === null || _d === void 0 ? void 0 : _d.call(_c, data.name, data.data, message));
90
+ const processorStatus = yield ((_d = (_c = this.options.extraConfig) === null || _c === void 0 ? void 0 : _c.preProcessor) === null || _d === void 0 ? void 0 : _d.call(_c, decodedMessage.data.name, decodedMessage.data.data, decodedMessage.raw));
85
91
  if (processorStatus !== interfaces_1.QueueWorkerProcessorStatus.SKIP) {
86
92
  for (const processor of processors) {
87
- yield this.execProcessor(processor.processor, maxRetryAttempts, data.data, message);
93
+ yield this.execProcessor(processor.processor, maxRetryAttempts, decodedMessage.data.data, decodedMessage.raw);
88
94
  }
89
95
  for (const processor of spetialProcessors) {
90
- yield this.execProcessor(processor.processor, maxRetryAttempts, data, message);
96
+ yield this.execProcessor(processor.processor, maxRetryAttempts, decodedMessage.data, decodedMessage.raw);
91
97
  }
92
98
  }
93
- yield ((_f = (_e = this.options.extraConfig) === null || _e === void 0 ? void 0 : _e.postProcessor) === null || _f === void 0 ? void 0 : _f.call(_e, data.name, data.data, message));
99
+ yield ((_f = (_e = this.options.extraConfig) === null || _e === void 0 ? void 0 : _e.postProcessor) === null || _f === void 0 ? void 0 : _f.call(_e, decodedMessage.data.name, decodedMessage.data.data, decodedMessage.raw));
94
100
  });
95
101
  }
96
- execProcessor(processor, maxRetryAttempts, data, rawMessage) {
97
- return __awaiter(this, void 0, void 0, function* () {
98
- for (let i = 0; i < maxRetryAttempts; i++) {
99
- try {
100
- yield processor(data, rawMessage);
101
- i = maxRetryAttempts;
102
- }
103
- catch (error) {
104
- this.logger.error(error.message);
105
- }
106
- }
107
- });
102
+ isDecodedMessage(message) {
103
+ return !!message.raw;
108
104
  }
109
105
  decodeData(data) {
110
106
  if (!data) {
111
- throw new Error(constants_1.ERROR_INVALID_MESSAGE_FORMAT);
107
+ throw new common_1.BadRequestException(constants_1.ERROR_INVALID_MESSAGE_FORMAT);
112
108
  }
113
109
  if (Buffer.isBuffer(data)) {
114
110
  data = data.toString();
@@ -116,7 +112,7 @@ let QueueWorkerService = class QueueWorkerService {
116
112
  if (data instanceof Uint8Array) {
117
113
  data = new TextDecoder("utf8").decode(data);
118
114
  }
119
- if ((0, class_validator_1.isBase64)(data)) {
115
+ if ((0, util_1.isBase64)(data)) {
120
116
  data = Buffer.from(data, "base64").toString();
121
117
  }
122
118
  try {
@@ -126,11 +122,31 @@ let QueueWorkerService = class QueueWorkerService {
126
122
  return data;
127
123
  }
128
124
  catch (_a) {
129
- throw new Error(constants_1.ERROR_INVALID_MESSAGE_FORMAT);
125
+ throw new common_1.BadRequestException(constants_1.ERROR_INVALID_MESSAGE_FORMAT);
130
126
  }
131
127
  }
128
+ execProcessor(processor, maxRetryAttempts, data, raw) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ for (let i = 0; i < maxRetryAttempts; i++) {
131
+ try {
132
+ yield processor(data, raw);
133
+ i = maxRetryAttempts;
134
+ }
135
+ catch (error) {
136
+ this.logger.error(error.message);
137
+ }
138
+ }
139
+ });
140
+ }
141
+ };
142
+ _QueueWorkerService__allWorkers = new WeakMap(), _QueueWorkerService_instances = new WeakSet(), _QueueWorkerService_allWorkers_get = function _QueueWorkerService_allWorkers_get() {
143
+ if (!__classPrivateFieldGet(this, _QueueWorkerService__allWorkers, "f")) {
144
+ __classPrivateFieldSet(this, _QueueWorkerService__allWorkers, this.explorerService.explore(), "f");
145
+ }
146
+ return __classPrivateFieldGet(this, _QueueWorkerService__allWorkers, "f");
147
+ }, _QueueWorkerService_spetialWorkers_get = function _QueueWorkerService_spetialWorkers_get() {
148
+ return (__classPrivateFieldGet(this, _QueueWorkerService__allWorkers, "f") || []).filter((worker) => [constants_1.ALL_WORKERS_QUEUE_WORKER_NAME, constants_1.UNHANDLED_QUEUE_WORKER_NAME].includes(worker.name));
132
149
  };
133
- _QueueWorkerService_allWorkers = new WeakMap();
134
150
  QueueWorkerService = __decorate([
135
151
  (0, common_1.Injectable)(),
136
152
  __param(0, (0, common_1.Inject)(constants_1.QUEUE_WORKER_MODULE_OPTIONS)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anchan828/nest-cloud-run-queue-worker",
3
- "version": "1.0.10",
3
+ "version": "1.0.13",
4
4
  "description": "> TODO: description",
5
5
  "homepage": "https://github.com/anchan828/nest-cloud-run-queue/tree/master/packages/worker#readme",
6
6
  "bugs": {
@@ -33,8 +33,7 @@
33
33
  "watch": "tsc -w"
34
34
  },
35
35
  "dependencies": {
36
- "@anchan828/nest-cloud-run-queue-common": "^1.0.10",
37
- "class-validator": "0.13.2"
36
+ "@anchan828/nest-cloud-run-queue-common": "^1.0.13"
38
37
  },
39
38
  "devDependencies": {
40
39
  "@nestjs/common": "8.4.5",
@@ -46,5 +45,5 @@
46
45
  "publishConfig": {
47
46
  "access": "public"
48
47
  },
49
- "gitHead": "6d7b6c1abb9408cffa16aea7c4eb07f4f381a4fa"
48
+ "gitHead": "54936c9f95780c7c389cbacb4d824f4dedcb6678"
50
49
  }