@treatwell/moleculer-essentials 1.0.0
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/context-factory-BWO3xPWE.d.cts +520 -0
- package/dist/context-factory-BWO3xPWE.d.mts +520 -0
- package/dist/index-82e1CXJX.cjs +11 -0
- package/dist/index-BV1ZqQrU.mjs +351 -0
- package/dist/index-DNJWwcZu.mjs +8 -0
- package/dist/index-rZl77S1z.cjs +375 -0
- package/dist/index.cjs +1570 -0
- package/dist/index.d.cts +373 -0
- package/dist/index.d.mts +373 -0
- package/dist/index.mjs +1535 -0
- package/dist/mixins/database.mixin.cjs +1673 -0
- package/dist/mixins/database.mixin.d.cts +958 -0
- package/dist/mixins/database.mixin.d.mts +958 -0
- package/dist/mixins/database.mixin.mjs +1645 -0
- package/dist/mixins/encryptor.mixin.cjs +84 -0
- package/dist/mixins/encryptor.mixin.d.cts +31 -0
- package/dist/mixins/encryptor.mixin.d.mts +31 -0
- package/dist/mixins/encryptor.mixin.mjs +81 -0
- package/dist/mixins/global-store.mixin.cjs +56 -0
- package/dist/mixins/global-store.mixin.d.cts +39 -0
- package/dist/mixins/global-store.mixin.d.mts +39 -0
- package/dist/mixins/global-store.mixin.mjs +54 -0
- package/dist/mixins/jwt.mixin.cjs +118 -0
- package/dist/mixins/jwt.mixin.d.cts +43 -0
- package/dist/mixins/jwt.mixin.d.mts +43 -0
- package/dist/mixins/jwt.mixin.mjs +115 -0
- package/dist/mixins/queue.mixin.cjs +420 -0
- package/dist/mixins/queue.mixin.d.cts +150 -0
- package/dist/mixins/queue.mixin.d.mts +150 -0
- package/dist/mixins/queue.mixin.mjs +414 -0
- package/dist/mixins/redis.mixin.cjs +50 -0
- package/dist/mixins/redis.mixin.d.cts +27 -0
- package/dist/mixins/redis.mixin.d.mts +27 -0
- package/dist/mixins/redis.mixin.mjs +48 -0
- package/dist/mixins/redlock.mixin.cjs +76 -0
- package/dist/mixins/redlock.mixin.d.cts +30 -0
- package/dist/mixins/redlock.mixin.d.mts +30 -0
- package/dist/mixins/redlock.mixin.mjs +74 -0
- package/package.json +181 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { omit, pick } from 'lodash';
|
|
2
|
+
import { z as z$1 } from 'zod/v4';
|
|
3
|
+
import { ObjectId } from 'bson';
|
|
4
|
+
import { parseISO } from 'date-fns';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
const COERCE_ARRAY_ATTRIBUTE = "x-coerce-array";
|
|
8
|
+
const SCHEMA_REF_NAME = "$id";
|
|
9
|
+
const EMPTY_OBJECT_SCHEMA = {
|
|
10
|
+
type: "object",
|
|
11
|
+
additionalProperties: true,
|
|
12
|
+
required: [],
|
|
13
|
+
properties: {}
|
|
14
|
+
};
|
|
15
|
+
const DATE_TYPE = {
|
|
16
|
+
type: "string",
|
|
17
|
+
format: "date-time"
|
|
18
|
+
};
|
|
19
|
+
const OBJECTID_TYPE = {
|
|
20
|
+
type: "string",
|
|
21
|
+
pattern: "^[0-9A-Fa-f]{24}$",
|
|
22
|
+
format: "object-id",
|
|
23
|
+
description: "ObjectId"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function omitFields(schema, fields, refName) {
|
|
27
|
+
if (schema.anyOf || schema.allOf || schema.oneOf) {
|
|
28
|
+
return {
|
|
29
|
+
...schema,
|
|
30
|
+
[SCHEMA_REF_NAME]: refName,
|
|
31
|
+
anyOf: schema.anyOf?.map(
|
|
32
|
+
(s) => omitFields(s, fields)
|
|
33
|
+
),
|
|
34
|
+
allOf: schema.allOf?.map(
|
|
35
|
+
(s) => omitFields(s, fields)
|
|
36
|
+
),
|
|
37
|
+
oneOf: schema.oneOf?.map(
|
|
38
|
+
(s) => omitFields(s, fields)
|
|
39
|
+
)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
...schema,
|
|
44
|
+
[SCHEMA_REF_NAME]: refName,
|
|
45
|
+
required: schema.required.filter((f) => !fields.includes(f)),
|
|
46
|
+
properties: omit(schema.properties, fields)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function pickFields(schema, fields, refName) {
|
|
50
|
+
if (schema.anyOf || schema.allOf || schema.oneOf) {
|
|
51
|
+
return {
|
|
52
|
+
...schema,
|
|
53
|
+
[SCHEMA_REF_NAME]: refName,
|
|
54
|
+
anyOf: schema.anyOf?.map(
|
|
55
|
+
(s) => pickFields(s, fields)
|
|
56
|
+
),
|
|
57
|
+
allOf: schema.allOf?.map(
|
|
58
|
+
(s) => pickFields(s, fields)
|
|
59
|
+
),
|
|
60
|
+
oneOf: schema.oneOf?.map(
|
|
61
|
+
(s) => pickFields(s, fields)
|
|
62
|
+
)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
...schema,
|
|
67
|
+
[SCHEMA_REF_NAME]: refName,
|
|
68
|
+
required: schema.required.filter((f) => fields.includes(f)),
|
|
69
|
+
properties: pick(schema.properties, fields)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function optionalExceptFields(schema, fields, refName) {
|
|
73
|
+
if (schema.anyOf || schema.allOf || schema.oneOf) {
|
|
74
|
+
return {
|
|
75
|
+
...schema,
|
|
76
|
+
[SCHEMA_REF_NAME]: refName,
|
|
77
|
+
anyOf: schema.anyOf?.map(
|
|
78
|
+
(s) => optionalExceptFields(s, fields)
|
|
79
|
+
),
|
|
80
|
+
allOf: schema.allOf?.map(
|
|
81
|
+
(s) => optionalExceptFields(s, fields)
|
|
82
|
+
),
|
|
83
|
+
oneOf: schema.oneOf?.map(
|
|
84
|
+
(s) => optionalExceptFields(s, fields)
|
|
85
|
+
)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
...schema,
|
|
90
|
+
[SCHEMA_REF_NAME]: refName,
|
|
91
|
+
required: schema.required.filter((f) => fields.includes(f))
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function optionalFields(schema, fields, refName) {
|
|
95
|
+
if (schema.anyOf || schema.allOf || schema.oneOf) {
|
|
96
|
+
return {
|
|
97
|
+
...schema,
|
|
98
|
+
[SCHEMA_REF_NAME]: refName,
|
|
99
|
+
anyOf: schema.anyOf?.map(
|
|
100
|
+
(s) => optionalFields(s, fields)
|
|
101
|
+
),
|
|
102
|
+
allOf: schema.allOf?.map(
|
|
103
|
+
(s) => optionalFields(s, fields)
|
|
104
|
+
),
|
|
105
|
+
oneOf: schema.oneOf?.map(
|
|
106
|
+
(s) => optionalFields(s, fields)
|
|
107
|
+
)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
...schema,
|
|
112
|
+
[SCHEMA_REF_NAME]: refName,
|
|
113
|
+
required: schema.required.filter((f) => !fields.includes(f))
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function toPartialSchema(schema, refName) {
|
|
117
|
+
if (schema.anyOf || schema.allOf || schema.oneOf) {
|
|
118
|
+
return {
|
|
119
|
+
...schema,
|
|
120
|
+
[SCHEMA_REF_NAME]: refName,
|
|
121
|
+
anyOf: schema.anyOf?.map(
|
|
122
|
+
(s) => toPartialSchema(s)
|
|
123
|
+
),
|
|
124
|
+
allOf: schema.allOf?.map(
|
|
125
|
+
(s) => toPartialSchema(s)
|
|
126
|
+
),
|
|
127
|
+
oneOf: schema.oneOf?.map(
|
|
128
|
+
(s) => toPartialSchema(s)
|
|
129
|
+
)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
...schema,
|
|
134
|
+
[SCHEMA_REF_NAME]: refName,
|
|
135
|
+
required: []
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function addFieldsToSchema(schema, newFields, refName) {
|
|
139
|
+
return {
|
|
140
|
+
...schema,
|
|
141
|
+
[SCHEMA_REF_NAME]: refName,
|
|
142
|
+
properties: { ...schema.properties, ...newFields }
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function composeSchemas(schemaRefName, ...schemas) {
|
|
146
|
+
return {
|
|
147
|
+
[SCHEMA_REF_NAME]: schemaRefName ?? void 0,
|
|
148
|
+
type: "object",
|
|
149
|
+
required: [],
|
|
150
|
+
unevaluatedProperties: false,
|
|
151
|
+
allOf: schemas
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function deepRefReplacer(obj, extractor, currentId = "") {
|
|
156
|
+
if (!obj || typeof obj !== "object") {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if ("$ref" in obj && typeof obj.$ref === "string") {
|
|
160
|
+
let id;
|
|
161
|
+
if (obj.$ref === "#") {
|
|
162
|
+
if (!currentId) {
|
|
163
|
+
throw new Error("Got a recursive ref (#) without a parent id.");
|
|
164
|
+
}
|
|
165
|
+
id = currentId;
|
|
166
|
+
} else if (obj.$ref.startsWith("#/$defs/")) {
|
|
167
|
+
id = obj.$ref.replace("#/$defs/", "");
|
|
168
|
+
}
|
|
169
|
+
if (id) {
|
|
170
|
+
obj.$ref = extractor.refReplacer(id);
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
for (const val of Object.values(obj)) {
|
|
174
|
+
deepRefReplacer(val, extractor, currentId);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function zodToOpenAPISchema(schema, extractor) {
|
|
179
|
+
const res = z.toJSONSchema(schema, {
|
|
180
|
+
io: "input",
|
|
181
|
+
unrepresentable: "any",
|
|
182
|
+
override: ({ zodSchema, jsonSchema }) => {
|
|
183
|
+
const { def } = zodSchema._zod;
|
|
184
|
+
if (def.type === "date") {
|
|
185
|
+
jsonSchema.type = "string";
|
|
186
|
+
jsonSchema.format = "date-time";
|
|
187
|
+
}
|
|
188
|
+
if (def.type === "custom" && def.fn === isObjectId) {
|
|
189
|
+
jsonSchema.type = "string";
|
|
190
|
+
jsonSchema.format = "object-id";
|
|
191
|
+
jsonSchema.pattern = "^[0-9A-Fa-f]{24}$";
|
|
192
|
+
}
|
|
193
|
+
if (Object.keys(jsonSchema).length === 0) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`Zod schema ${def.type} is not representable in OpenAPI.`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
if (jsonSchema.id) {
|
|
199
|
+
jsonSchema.$id = jsonSchema.id;
|
|
200
|
+
delete jsonSchema.id;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
deepRefReplacer(res, extractor, res.$id);
|
|
205
|
+
if (res.$defs) {
|
|
206
|
+
for (const [key, val] of Object.entries(res.$defs)) {
|
|
207
|
+
deepRefReplacer(val, extractor, key);
|
|
208
|
+
extractor.onNewRef(key, val);
|
|
209
|
+
}
|
|
210
|
+
delete res.$defs;
|
|
211
|
+
}
|
|
212
|
+
delete res.$schema;
|
|
213
|
+
if (res.$id) {
|
|
214
|
+
extractor.onNewRef(res.$id, res);
|
|
215
|
+
return { $ref: extractor.refReplacer(res.$id) };
|
|
216
|
+
}
|
|
217
|
+
return res;
|
|
218
|
+
}
|
|
219
|
+
const zodDate = z.transform((val) => {
|
|
220
|
+
if (typeof val === "string") {
|
|
221
|
+
const date = parseISO(val);
|
|
222
|
+
if (!Number.isNaN(date.getTime())) {
|
|
223
|
+
return date;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return val;
|
|
227
|
+
}).pipe(z.date());
|
|
228
|
+
const OBJECT_ID_PATTERN = /^[a-f\d]{24}$/i;
|
|
229
|
+
function isObjectId(val) {
|
|
230
|
+
return val instanceof ObjectId;
|
|
231
|
+
}
|
|
232
|
+
const zodObjectId = z.transform((val) => {
|
|
233
|
+
if (typeof val === "string" && OBJECT_ID_PATTERN.test(val)) {
|
|
234
|
+
return new ObjectId(val);
|
|
235
|
+
}
|
|
236
|
+
return val;
|
|
237
|
+
}).pipe(z.custom(isObjectId, { abort: true })).meta({ id: "ObjectId" });
|
|
238
|
+
function zodCoerceArray(element, params) {
|
|
239
|
+
return z.transform((val) => !Array.isArray(val) && val !== void 0 ? [val] : val).pipe(z.array(element, params));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const ServerErrorSchema = {
|
|
243
|
+
type: "object",
|
|
244
|
+
additionalProperties: false,
|
|
245
|
+
required: [],
|
|
246
|
+
properties: {
|
|
247
|
+
name: { type: "string" },
|
|
248
|
+
stack: { type: "string", nullable: true },
|
|
249
|
+
type: { type: "string" },
|
|
250
|
+
data: { type: "object", nullable: true },
|
|
251
|
+
message: { type: "string" },
|
|
252
|
+
code: { type: "integer" },
|
|
253
|
+
retryable: { type: "boolean" }
|
|
254
|
+
},
|
|
255
|
+
example: {
|
|
256
|
+
name: "MoleculerServerError",
|
|
257
|
+
message: "Internal Server Error",
|
|
258
|
+
code: 500
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
const UnauthorizedErrorSchema = {
|
|
262
|
+
type: "object",
|
|
263
|
+
additionalProperties: false,
|
|
264
|
+
required: [],
|
|
265
|
+
properties: {},
|
|
266
|
+
example: {
|
|
267
|
+
name: "UnAuthorizedError",
|
|
268
|
+
message: "Unauthorized",
|
|
269
|
+
code: 401,
|
|
270
|
+
type: "NO_TOKEN",
|
|
271
|
+
data: null
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
const FileNotExistSchema = {
|
|
275
|
+
type: "object",
|
|
276
|
+
additionalProperties: false,
|
|
277
|
+
required: [],
|
|
278
|
+
properties: {},
|
|
279
|
+
example: {
|
|
280
|
+
name: "MoleculerClientError",
|
|
281
|
+
message: "File missing in the request",
|
|
282
|
+
code: 400
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const FileTooBigSchema = {
|
|
286
|
+
type: "object",
|
|
287
|
+
additionalProperties: false,
|
|
288
|
+
required: [],
|
|
289
|
+
properties: {},
|
|
290
|
+
example: {
|
|
291
|
+
name: "PayloadTooLarge",
|
|
292
|
+
message: "Payload too large",
|
|
293
|
+
code: 413,
|
|
294
|
+
type: "PAYLOAD_TOO_LARGE",
|
|
295
|
+
data: {
|
|
296
|
+
fieldname: "file",
|
|
297
|
+
filename: "4b2005c0b8.png",
|
|
298
|
+
encoding: "7bit",
|
|
299
|
+
mimetype: "image/png"
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
const ValidationErrorSchema = {
|
|
304
|
+
type: "object",
|
|
305
|
+
additionalProperties: false,
|
|
306
|
+
required: [],
|
|
307
|
+
properties: ServerErrorSchema.properties,
|
|
308
|
+
example: {
|
|
309
|
+
code: 422,
|
|
310
|
+
type: "VALIDATION_ERROR",
|
|
311
|
+
data: [
|
|
312
|
+
{
|
|
313
|
+
keyword: "additionalProperties",
|
|
314
|
+
dataPath: "",
|
|
315
|
+
schemaPath: "#/additionalProperties",
|
|
316
|
+
params: {
|
|
317
|
+
additionalProperty: "originalDate"
|
|
318
|
+
},
|
|
319
|
+
message: "should NOT have additional properties"
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
const GetOpenApiParamsSchema = {
|
|
325
|
+
type: "object",
|
|
326
|
+
additionalProperties: false,
|
|
327
|
+
required: [],
|
|
328
|
+
properties: { kind: { type: "string" } }
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
function createOpenAPIResponses(model, description = "") {
|
|
332
|
+
const isZodType = model instanceof z$1.ZodType;
|
|
333
|
+
return {
|
|
334
|
+
responses: {
|
|
335
|
+
"200": {
|
|
336
|
+
description,
|
|
337
|
+
content: {
|
|
338
|
+
"application/json": {
|
|
339
|
+
// @ts-expect-error Moleculer will clone this object using lodash,
|
|
340
|
+
// losing the zod class instance. By using a function, we ensure
|
|
341
|
+
// that clone doesn't break the zod instance
|
|
342
|
+
zodInstance: isZodType ? () => model : void 0,
|
|
343
|
+
schema: isZodType ? void 0 : model
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export { COERCE_ARRAY_ATTRIBUTE as C, DATE_TYPE as D, EMPTY_OBJECT_SCHEMA as E, FileTooBigSchema as F, GetOpenApiParamsSchema as G, OBJECTID_TYPE as O, SCHEMA_REF_NAME as S, UnauthorizedErrorSchema as U, ValidationErrorSchema as V, FileNotExistSchema as a, ServerErrorSchema as b, addFieldsToSchema as c, optionalFields as d, optionalExceptFields as e, composeSchemas as f, zodDate as g, zodObjectId as h, zodCoerceArray as i, createOpenAPIResponses as j, omitFields as o, pickFields as p, toPartialSchema as t, zodToOpenAPISchema as z };
|