@smartsoft001/trans-shell-nestjs 2.147.0 → 2.149.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/index.js DELETED
@@ -1,3147 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result) __defProp(target, key, result);
9
- return result;
10
- };
11
- var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
12
-
13
- // packages/trans/shell/nestjs/src/lib/nestjs.module.ts
14
- import { HttpModule } from "@nestjs/axios";
15
- import { Module as Module2 } from "@nestjs/common";
16
- import { JwtModule as JwtModule2 } from "@nestjs/jwt";
17
- import { PassportModule as PassportModule2 } from "@nestjs/passport";
18
-
19
- // packages/crud/shell/nestjs/src/lib/nestjs.module.ts
20
- import { Module } from "@nestjs/common";
21
- import { JwtModule } from "@nestjs/jwt";
22
- import { PassportModule } from "@nestjs/passport";
23
-
24
- // packages/crud/shell/app-services/src/lib/services/crud/crud.service.ts
25
- import { Injectable, Logger } from "@nestjs/common";
26
- import * as CombinedStream from "combined-stream";
27
- import { Guid as Guid2 } from "guid-typescript";
28
- import { Memoize } from "lodash-decorators";
29
-
30
- // packages/shared/models/src/lib/symbols.ts
31
- var SYMBOL_MODEL = /* @__PURE__ */ Symbol.for("smartsoft:model");
32
- var SYMBOL_FIELD = /* @__PURE__ */ Symbol.for("smartsoft:field");
33
-
34
- // packages/shared/models/src/lib/decorators/model/model.decorator.ts
35
- import "reflect-metadata";
36
-
37
- // packages/shared/models/src/lib/decorators/field/field.decorator.ts
38
- import "reflect-metadata";
39
-
40
- // packages/shared/utils/src/lib/services/array/array.service.ts
41
- import * as _ from "lodash";
42
-
43
- // packages/shared/utils/src/lib/services/guid/guid.service.ts
44
- import { Guid } from "guid-typescript";
45
- var GuidService = class {
46
- /***
47
- * Create guid as string
48
- */
49
- static create() {
50
- return Guid.raw();
51
- }
52
- };
53
-
54
- // packages/shared/utils/src/lib/services/object/object.service.ts
55
- import { stringify } from "flatted";
56
- var ObjectService = class {
57
- /***
58
- * Create object with data
59
- * @param data {object} - data to set
60
- * @param type {type} - new type
61
- * @return - new type object
62
- */
63
- static createByType(data, type) {
64
- if (!data) return data;
65
- try {
66
- if (data instanceof type) return data;
67
- } catch (e) {
68
- console.warn(e);
69
- }
70
- const result = new type();
71
- Object.keys(data).forEach((key) => {
72
- result[key] = data[key];
73
- });
74
- return result;
75
- }
76
- /***
77
- * Remove object type from data
78
- * @param obj {object} - object
79
- * @return - object without type
80
- */
81
- static removeTypes(obj) {
82
- if (!obj) return obj;
83
- const result = {};
84
- Object.keys(obj).forEach((key) => {
85
- if (obj[key] && obj[key].constructor && !(obj[key] instanceof Date)) {
86
- let stringValue = "";
87
- try {
88
- stringValue = JSON.stringify(obj[key]);
89
- } catch (e) {
90
- console.warn("can't stringify without circular package");
91
- stringValue = stringify(obj[key]);
92
- }
93
- result[key] = JSON.parse(stringValue);
94
- } else {
95
- result[key] = obj[key];
96
- }
97
- });
98
- return result;
99
- }
100
- };
101
-
102
- // packages/shared/utils/src/lib/services/password/password.service.ts
103
- import md5 from "md5";
104
- var PasswordService = class _PasswordService {
105
- /**
106
- * Hash password text
107
- * @param p {string} - text
108
- * @return - hashed text
109
- */
110
- static hash(p) {
111
- return Promise.resolve(md5(p));
112
- }
113
- /**
114
- * Compare password text with hashed text
115
- * @param p {string} - password text
116
- * @param h {string} - hashed text
117
- */
118
- static async compare(p, h) {
119
- const hp = await _PasswordService.hash(p);
120
- return hp === h;
121
- }
122
- };
123
-
124
- // packages/shared/models/src/lib/utils.ts
125
- function getModelFieldKeys(type) {
126
- if (!type["__fields"]) return [];
127
- return Object.keys(type["__fields"]);
128
- }
129
- function getModelFieldOptions(instance, fieldKey) {
130
- return Reflect.getMetadata(SYMBOL_FIELD, instance, fieldKey);
131
- }
132
- function getModelFieldsWithOptions(instance) {
133
- const keys = getModelFieldKeys(instance.constructor);
134
- return keys.map((item) => {
135
- return {
136
- key: item,
137
- options: getModelFieldOptions(instance, item)
138
- };
139
- });
140
- }
141
- function isModel(instance) {
142
- if (!instance || !instance.constructor) return false;
143
- return Reflect.hasMetadata(SYMBOL_MODEL, instance.constructor);
144
- }
145
- function getInvalidFields(instance, mode, permissions) {
146
- const result = [];
147
- getModelFieldsWithOptions(instance).forEach(({ key, options }) => {
148
- let required = options.required;
149
- if ((mode === "create" || mode === "update") && options[mode] && options[mode]?.constructor) {
150
- required = options[mode].required;
151
- if (required && permissions && options[mode].permissions) {
152
- required = options[mode]?.permissions?.some(
153
- (op) => permissions.some((p) => p === op)
154
- );
155
- }
156
- }
157
- if (required && (instance[key] === null || instance[key] === void 0 || instance[key] === ""))
158
- result.push(key);
159
- });
160
- return result;
161
- }
162
- function castModel(instance, mode, permissions) {
163
- if (!isModel(instance)) return;
164
- const fieldsWithOptions = getModelFieldsWithOptions(instance);
165
- Object.keys(instance).filter((key) => key !== "id").forEach((key) => {
166
- const fieldWidthOptions = fieldsWithOptions.find((f) => f.key === key);
167
- if (!fieldWidthOptions) {
168
- delete instance[key];
169
- return;
170
- }
171
- if ((mode === "create" || mode === "update") && (!fieldWidthOptions.options[mode] || permissions && fieldWidthOptions.options[mode].permissions && !fieldWidthOptions.options[mode]?.permissions?.some((op) => permissions.some((p) => op === p)))) {
172
- delete instance[key];
173
- return;
174
- } else if (mode !== "create" && mode !== "update" && (!fieldWidthOptions.options.customs || !fieldWidthOptions.options.customs.some((c) => c.mode === mode))) {
175
- delete instance[key];
176
- return;
177
- }
178
- });
179
- }
180
-
181
- // packages/shared/domain-core/src/lib/errors.ts
182
- var DomainValidationError = class _DomainValidationError extends Error {
183
- type = _DomainValidationError;
184
- constructor(msg) {
185
- super(msg);
186
- }
187
- };
188
- var DomainForbiddenError = class _DomainForbiddenError extends Error {
189
- type = _DomainForbiddenError;
190
- constructor(msg) {
191
- super(msg);
192
- }
193
- };
194
-
195
- // packages/shared/domain-core/src/lib/repositories.ts
196
- var IUnitOfWork = class {
197
- };
198
- var IItemRepository = class {
199
- };
200
- var IAttachmentRepository = class {
201
- };
202
-
203
- // packages/crud/shell/app-services/src/lib/services/crud/crud.service.ts
204
- var CrudService = class {
205
- constructor(permissionService, repository, attachmentRepository) {
206
- this.permissionService = permissionService;
207
- this.repository = repository;
208
- this.attachmentRepository = attachmentRepository;
209
- }
210
- permissionService;
211
- repository;
212
- attachmentRepository;
213
- _logger = new Logger(CrudService.name, { timestamp: true });
214
- async create(data, user) {
215
- data.id = Guid2.raw();
216
- try {
217
- this.permissionService.valid("create", user);
218
- castModel(data, "create", user.permissions);
219
- this.checkValidCreate(data, user.permissions);
220
- if (data["password"]) {
221
- data["password"] = await PasswordService.hash(data["password"]);
222
- }
223
- if (data["passwordConfirm"]) {
224
- delete data["passwordConfirm"];
225
- }
226
- await this.repository.create(data, user);
227
- return data.id;
228
- } catch (e) {
229
- this._logger.error(e);
230
- throw e;
231
- }
232
- }
233
- async createMany(data, user, options) {
234
- data.forEach((item) => {
235
- item.id = Guid2.raw();
236
- });
237
- try {
238
- this.permissionService.valid("create", user);
239
- data.forEach((item) => {
240
- castModel(item, "create", user.permissions);
241
- this.checkValidCreate(item, user.permissions);
242
- });
243
- if (options && options.mode === "replace") {
244
- await this.repository.clear(user);
245
- }
246
- for (let index = 0; index < data.length; index++) {
247
- const item = data[index];
248
- if (item["password"]) {
249
- item["password"] = await PasswordService.hash(item["password"]);
250
- }
251
- if (item["passwordConfirm"]) {
252
- delete item["passwordConfirm"];
253
- }
254
- }
255
- await this.repository.createMany(data, user);
256
- } catch (e) {
257
- this._logger.error(e);
258
- throw e;
259
- }
260
- return data;
261
- }
262
- async readById(id, user) {
263
- try {
264
- this.permissionService.valid("read", user);
265
- const result = await this.repository.getById(id);
266
- delete result["password"];
267
- return result;
268
- } catch (e) {
269
- this._logger.error(e);
270
- throw e;
271
- }
272
- }
273
- async read(criteria, options, user) {
274
- try {
275
- this.permissionService.valid("read", user);
276
- const result = await this.repository.getByCriteria(criteria, options);
277
- result.data.forEach((item) => delete item["password"]);
278
- return result;
279
- } catch (e) {
280
- this._logger.error(e);
281
- throw e;
282
- }
283
- }
284
- readBySpec(spec, options, user) {
285
- return this.read(spec.criteria, options, user);
286
- }
287
- async update(id, data, user) {
288
- try {
289
- data.id = id;
290
- this.permissionService.valid("update", user);
291
- castModel(data, "update", user.permissions);
292
- this.checkValidUpdate(data, user.permissions);
293
- if (data["password"]) {
294
- data["password"] = await PasswordService.hash(data["password"]);
295
- }
296
- if (data["passwordConfirm"]) {
297
- delete data["passwordConfirm"];
298
- }
299
- await this.repository.update(data, user);
300
- } catch (e) {
301
- this._logger.error(e);
302
- throw e;
303
- }
304
- }
305
- async updatePartial(id, data, user) {
306
- try {
307
- data.id = id;
308
- this.permissionService.valid("update", user);
309
- castModel(data, "update", user.permissions);
310
- this.checkValidUpdatePartial(data, user.permissions);
311
- if (data["password"]) {
312
- data["password"] = await PasswordService.hash(data["password"]);
313
- }
314
- if (data["passwordConfirm"]) {
315
- delete data["passwordConfirm"];
316
- }
317
- await this.repository.updatePartial(data, user);
318
- } catch (e) {
319
- this._logger.error(e);
320
- throw e;
321
- }
322
- }
323
- async delete(id, user) {
324
- try {
325
- this.permissionService.valid("delete", user);
326
- await this.repository.delete(id, user);
327
- } catch (e) {
328
- this._logger.error(e);
329
- throw e;
330
- }
331
- }
332
- async uploadAttachment(data, options) {
333
- if (!data.id) {
334
- data.id = GuidService.create();
335
- }
336
- let oldId = null;
337
- if (options?.start) {
338
- oldId = data.id;
339
- const stream = await this.attachmentRepository.getStream(data.id, {
340
- start: 0,
341
- end: options.start - 1
342
- });
343
- const combinedStream = CombinedStream.create();
344
- combinedStream.append(stream);
345
- combinedStream.append(data.stream);
346
- data.stream = combinedStream;
347
- data.id = GuidService.create();
348
- }
349
- this.attachmentRepository.upload(data, options);
350
- if (oldId) await this.attachmentRepository.delete(data.id);
351
- return data.id;
352
- }
353
- getAttachmentInfo(id) {
354
- return this.attachmentRepository.getInfo(id);
355
- }
356
- getAttachmentStream(id, options) {
357
- return this.attachmentRepository.getStream(id, options);
358
- }
359
- async deleteAttachment(id) {
360
- return this.attachmentRepository.delete(id);
361
- }
362
- changes(criteria) {
363
- return this.repository.changesByCriteria(criteria);
364
- }
365
- checkValidCreate(item, permissions) {
366
- const array = getInvalidFields(item, "create", permissions);
367
- if (array.length) {
368
- throw new DomainValidationError("Required fields: " + array.join(", "));
369
- }
370
- }
371
- checkValidUpdate(item, permissions) {
372
- const array = getInvalidFields(item, "update", permissions);
373
- if (array.length) {
374
- throw new DomainValidationError("Required fields: " + array.join(", "));
375
- }
376
- }
377
- checkValidUpdatePartial(item, permissions) {
378
- if (!isModel(item)) return;
379
- const keys = Object.keys(item);
380
- const array = getInvalidFields(item, "update", permissions)?.filter(
381
- (invalidField) => keys.some((key) => key === invalidField)
382
- );
383
- if (array.length) {
384
- throw new DomainValidationError("Required fields: " + array.join(", "));
385
- }
386
- }
387
- };
388
- __decorateClass([
389
- Memoize()
390
- ], CrudService.prototype, "getAttachmentInfo", 1);
391
- CrudService = __decorateClass([
392
- Injectable()
393
- ], CrudService);
394
-
395
- // packages/crud/shell/app-services/src/lib/services/index.ts
396
- var SERVICES = [CrudService];
397
-
398
- // packages/shared/mongo/src/lib/mongo.config.ts
399
- var MongoConfig = class {
400
- host;
401
- port;
402
- database;
403
- username;
404
- password;
405
- collection;
406
- url;
407
- type;
408
- };
409
-
410
- // packages/shared/mongo/src/lib/mongo.unitofwork.ts
411
- import { Injectable as Injectable2 } from "@nestjs/common";
412
- import { MongoClient } from "mongodb";
413
-
414
- // packages/shared/mongo/src/lib/mongo.utils.ts
415
- function getMongoUrl(config) {
416
- let url;
417
- if (config.username && config.password)
418
- url = `mongodb://${config.username}:${config.password}@${config.host}:${config.port}`;
419
- else url = `mongodb://${config.host}:${config.port}`;
420
- url = url + "?authSource=" + config.database;
421
- if (config.host.indexOf("ondigitalocean.com") > -1) {
422
- url = url.replace("mongodb://", "mongodb+srv://");
423
- url = url + "&tls=true";
424
- }
425
- return url;
426
- }
427
-
428
- // packages/shared/mongo/src/lib/mongo.unitofwork.ts
429
- var MongoUnitOfWork = class extends IUnitOfWork {
430
- constructor(config) {
431
- super();
432
- this.config = config;
433
- }
434
- config;
435
- async scope(definition) {
436
- const client = await MongoClient.connect(this.getUrl());
437
- const session = client.startSession();
438
- const transactionOptions = {
439
- readPreference: "primary",
440
- readConcern: { level: "local" },
441
- writeConcern: { w: "majority" }
442
- };
443
- let error = null;
444
- try {
445
- await session.withTransaction(async () => {
446
- await definition({
447
- session,
448
- connection: client
449
- });
450
- }, transactionOptions);
451
- } catch (e) {
452
- error = e;
453
- } finally {
454
- await session.endSession();
455
- await client.close();
456
- }
457
- if (error) throw error;
458
- }
459
- getUrl() {
460
- return getMongoUrl(this.config);
461
- }
462
- };
463
- MongoUnitOfWork = __decorateClass([
464
- Injectable2()
465
- ], MongoUnitOfWork);
466
-
467
- // packages/shared/mongo/src/lib/repositories/attachment.repository.ts
468
- import { Injectable as Injectable3 } from "@nestjs/common";
469
- import { MongoClient as MongoClient2 } from "mongodb";
470
- import * as mongo from "mongodb";
471
- var MongoAttachmentRepository = class extends IAttachmentRepository {
472
- constructor(config) {
473
- super();
474
- this.config = config;
475
- }
476
- config;
477
- async upload(data, options) {
478
- const client = await MongoClient2.connect(this.getUrl());
479
- return await new Promise((res, rej) => {
480
- const db = client.db(this.config.database);
481
- const bucket = new mongo.GridFSBucket(db, {
482
- bucketName: this.config.collection
483
- });
484
- const writeStream = bucket.openUploadStreamWithId(
485
- data.id,
486
- data.fileName,
487
- {
488
- metadata: { contentType: data.mimeType }
489
- }
490
- );
491
- if (options?.streamCallback) options.streamCallback(writeStream);
492
- data.stream.pipe(writeStream);
493
- writeStream.on("error", (error) => {
494
- rej(error);
495
- });
496
- writeStream.on("finish", () => {
497
- res();
498
- });
499
- });
500
- }
501
- async getInfo(id) {
502
- const client = await MongoClient2.connect(this.getUrl());
503
- const db = client.db(this.config.database);
504
- const bucket = new mongo.GridFSBucket(db, {
505
- bucketName: this.config.collection
506
- });
507
- const items = await bucket.find({
508
- _id: id
509
- }).toArray();
510
- if (!items || items.length === 0) return null;
511
- return {
512
- fileName: items[0].filename,
513
- // mongodb 7 removed the deprecated top-level contentType - files written
514
- // by older driver versions still carry it, so fall back to it
515
- contentType: items[0].metadata?.["contentType"] ?? items[0].contentType,
516
- length: items[0].length
517
- };
518
- }
519
- async getStream(id, options) {
520
- const client = await MongoClient2.connect(this.getUrl());
521
- const db = client.db(this.config.database);
522
- const bucket = new mongo.GridFSBucket(db, {
523
- bucketName: this.config.collection
524
- });
525
- return bucket.openDownloadStream(id, options);
526
- }
527
- async delete(id) {
528
- const client = await MongoClient2.connect(this.getUrl());
529
- const db = client.db(this.config.database);
530
- const bucket = new mongo.GridFSBucket(db, {
531
- bucketName: this.config.collection
532
- });
533
- await bucket.delete(id);
534
- await client.close();
535
- }
536
- getUrl() {
537
- return getMongoUrl(this.config);
538
- }
539
- };
540
- MongoAttachmentRepository = __decorateClass([
541
- Injectable3()
542
- ], MongoAttachmentRepository);
543
-
544
- // packages/shared/mongo/src/lib/repositories/item.repository.ts
545
- import { Injectable as Injectable4 } from "@nestjs/common";
546
- import {
547
- MongoClient as MongoClient3
548
- } from "mongodb";
549
- import { Observable } from "rxjs";
550
- import { finalize, share } from "rxjs/operators";
551
- var MongoItemRepository = class extends IItemRepository {
552
- constructor(config) {
553
- super();
554
- this.config = config;
555
- }
556
- config;
557
- async create(item, user, repoOptions) {
558
- await this.collectionContext(async (collection) => {
559
- try {
560
- await collection.insertOne(this.getModelToCreate(item, user), {
561
- session: repoOptions?.transaction?.session
562
- });
563
- this.logChange("create", item, repoOptions, user, null).then();
564
- } catch (errInsert) {
565
- this.logChange("create", item, repoOptions, user, errInsert).then();
566
- throw errInsert;
567
- }
568
- });
569
- }
570
- async clear(user, repoOptions) {
571
- await this.collectionContext(async (collection) => {
572
- try {
573
- await collection.deleteMany(
574
- {},
575
- { session: repoOptions?.transaction?.session }
576
- );
577
- this.logChange("clear", null, repoOptions, user, null).then();
578
- } catch (errClear) {
579
- this.logChange("clear", null, repoOptions, user, errClear).then();
580
- throw errClear;
581
- }
582
- });
583
- }
584
- async createMany(list, user, repoOptions) {
585
- await this.collectionContext(async (collection) => {
586
- try {
587
- await collection.insertMany(
588
- list.map((item) => this.getModelToCreate(item, user)),
589
- { session: repoOptions?.transaction?.session }
590
- );
591
- this.logChange("createMany", null, repoOptions, user, null).then();
592
- } catch (errInsert) {
593
- this.logChange("createMany", null, repoOptions, user, errInsert).then();
594
- throw errInsert;
595
- }
596
- });
597
- }
598
- async update(item, user, repoOptions) {
599
- await this.collectionContext(async (collection) => {
600
- try {
601
- const info = await this.getInfo(item.id, collection);
602
- await collection.replaceOne(
603
- { _id: item.id },
604
- this.getModelToUpdate(item, user, info),
605
- { session: repoOptions?.transaction?.session }
606
- );
607
- this.logChange("update", item, repoOptions, user, null).then();
608
- } catch (errInsert) {
609
- this.logChange("update", item, repoOptions, user, errInsert).then();
610
- throw errInsert;
611
- }
612
- });
613
- }
614
- async updatePartial(item, user, repoOptions) {
615
- await this.collectionContext(async (collection) => {
616
- try {
617
- const info = await this.getInfo(item.id, collection);
618
- await collection.updateOne(
619
- { _id: item.id },
620
- {
621
- $set: this.getModelToUpdate(item, user, info)
622
- },
623
- { session: repoOptions?.transaction?.session }
624
- );
625
- this.logChange("updatePartial", item, repoOptions, user, null).then();
626
- } catch (errUpdate) {
627
- this.logChange(
628
- "updatePartial",
629
- item,
630
- repoOptions,
631
- user,
632
- errUpdate
633
- ).then();
634
- throw errUpdate;
635
- }
636
- });
637
- }
638
- async updatePartialManyByCriteria(criteria, set, user, repoOptions) {
639
- await this.collectionContext(async (collection) => {
640
- try {
641
- this.convertIdInCriteria(criteria);
642
- await collection.updateMany(
643
- criteria,
644
- {
645
- $set: {
646
- ...set,
647
- "__info.update": {
648
- username: user?.username,
649
- date: /* @__PURE__ */ new Date()
650
- }
651
- }
652
- },
653
- { session: repoOptions?.transaction?.session }
654
- );
655
- this.logChange(
656
- "updatePartialManyByCriteria",
657
- {
658
- ...criteria,
659
- set
660
- },
661
- repoOptions,
662
- user,
663
- null
664
- ).then();
665
- } catch (errUpdate) {
666
- this.logChange(
667
- "updatePartialManyByCriteria",
668
- {
669
- ...criteria,
670
- set
671
- },
672
- repoOptions,
673
- user,
674
- errUpdate
675
- ).then();
676
- throw errUpdate;
677
- }
678
- });
679
- }
680
- updatePartialManyBySpecification(spec, set, user, repoOptions) {
681
- return this.updatePartialManyByCriteria(
682
- spec.criteria,
683
- set,
684
- user,
685
- repoOptions
686
- );
687
- }
688
- async delete(id, user, repoOptions) {
689
- await this.collectionContext(async (collection) => {
690
- try {
691
- await collection.deleteOne(
692
- { _id: id },
693
- { session: repoOptions?.transaction?.session }
694
- );
695
- this.logChange(
696
- "delete",
697
- {
698
- id
699
- },
700
- repoOptions,
701
- user,
702
- null
703
- ).then();
704
- } catch (errDelete) {
705
- this.logChange(
706
- "delete",
707
- {
708
- id
709
- },
710
- repoOptions,
711
- user,
712
- errDelete
713
- ).then();
714
- throw errDelete;
715
- }
716
- });
717
- }
718
- async getById(id, repoOptions) {
719
- return await this.collectionContext(async (collection) => {
720
- const item = await collection.findOne(
721
- { _id: id },
722
- {
723
- session: repoOptions?.transaction?.session
724
- }
725
- );
726
- return this.getModelToResult(item);
727
- });
728
- }
729
- async getByCriteria(criteria, options = {}) {
730
- return await this.collectionContext(async (collection) => {
731
- this.convertIdInCriteria(criteria);
732
- this.generateSearch(criteria);
733
- const totalCount = await this.getCount(criteria, collection);
734
- const aggregate = [];
735
- if (criteria) {
736
- aggregate.push({ $match: criteria });
737
- }
738
- if (options?.sort) {
739
- aggregate.push({ $sort: options.sort });
740
- }
741
- if (options?.skip) {
742
- aggregate.push({ $skip: options.skip });
743
- }
744
- if (options?.limit) {
745
- aggregate.push({ $limit: options.limit });
746
- }
747
- if (options?.project) {
748
- aggregate.push({ $project: options.project });
749
- }
750
- if (options?.min) {
751
- aggregate.push({ $min: options.min });
752
- }
753
- if (options?.max) {
754
- aggregate.push({ $max: options.max });
755
- }
756
- if (options?.group) {
757
- aggregate.push({ $group: options.group });
758
- }
759
- const list = await collection.aggregate(aggregate, {
760
- allowDiskUse: options?.allowDiskUse,
761
- session: options?.session
762
- }).toArray();
763
- return {
764
- data: list.map((item) => this.getModelToResult(item)),
765
- totalCount
766
- };
767
- });
768
- }
769
- getBySpecification(spec, options = {}) {
770
- return this.getByCriteria(spec.criteria, options);
771
- }
772
- async countByCriteria(criteria) {
773
- return await this.collectionContext(async (collection) => {
774
- this.convertIdInCriteria(criteria);
775
- this.generateSearch(criteria);
776
- return await this.getCount(criteria, collection);
777
- });
778
- }
779
- countBySpecification(spec) {
780
- return this.countByCriteria(spec.criteria);
781
- }
782
- changesByCriteria(criteria) {
783
- let stream;
784
- let client;
785
- return new Observable((observer) => {
786
- (async () => {
787
- try {
788
- client = await MongoClient3.connect(this.getUrl());
789
- const db = client.db(this.config.database);
790
- const collection = db.collection(this.config.collection);
791
- const pipeline = criteria.id ? [
792
- {
793
- $match: {
794
- "documentKey._id": criteria.id
795
- }
796
- }
797
- ] : [];
798
- stream = collection.watch(pipeline).on("change", (result) => {
799
- observer.next({
800
- id: result["documentKey"]["_id"],
801
- type: this.mapChangeType(result.operationType),
802
- data: result.operationType === "update" ? result["updateDescription"] : this.getModelToResult(result["fullDocument"])
803
- });
804
- });
805
- } catch (err) {
806
- observer.error(err);
807
- }
808
- })();
809
- }).pipe(
810
- finalize(async () => {
811
- console.log("Stop watch");
812
- await stream.close();
813
- await client.close();
814
- }),
815
- share()
816
- );
817
- }
818
- async getContext(handler) {
819
- const client = await MongoClient3.connect(this.getUrl());
820
- const db = client.db(this.config.database);
821
- try {
822
- const result = await handler(db);
823
- await client.close();
824
- return result;
825
- } catch (e) {
826
- await client.close();
827
- throw e;
828
- }
829
- }
830
- async getCount(criteria, collection) {
831
- this.convertIdInCriteria(criteria);
832
- return await collection.countDocuments(criteria);
833
- }
834
- async getInfo(id, collection) {
835
- const array = await collection.aggregate([{ $match: { _id: id } }, { $project: { __info: 1 } }]).toArray();
836
- return array[0] ? array[0]["__info"] : {};
837
- }
838
- getModelToCreate(item, user) {
839
- const result = ObjectService.removeTypes(item);
840
- result["_id"] = result.id;
841
- delete result.id;
842
- result["__info"] = {
843
- create: {
844
- username: user ? user.username : null,
845
- date: /* @__PURE__ */ new Date()
846
- }
847
- };
848
- return result;
849
- }
850
- mapChangeType(dbType) {
851
- const map = {
852
- insert: "create",
853
- update: "update",
854
- delete: "delete"
855
- };
856
- return map[dbType];
857
- }
858
- getModelToUpdate(item, user, info) {
859
- const result = ObjectService.removeTypes(item);
860
- result["_id"] = result.id;
861
- delete result.id;
862
- result["__info"] = {
863
- ...info,
864
- update: {
865
- username: user ? user.username : null,
866
- date: /* @__PURE__ */ new Date()
867
- }
868
- };
869
- return result;
870
- }
871
- getModelToResult(item) {
872
- if (!item) return null;
873
- const result = ObjectService.removeTypes(item);
874
- result["id"] = result._id;
875
- delete result._id;
876
- delete result["__info"];
877
- return result;
878
- }
879
- getUrl() {
880
- return getMongoUrl(this.config);
881
- }
882
- async logChange(type, item, options, user, error) {
883
- const client = await MongoClient3.connect(this.getUrl());
884
- const db = client.db(this.config.database);
885
- try {
886
- await db.collection("changes").insertOne({
887
- type,
888
- collection: this.config.collection,
889
- item,
890
- options,
891
- user,
892
- error,
893
- date: /* @__PURE__ */ new Date()
894
- });
895
- } catch (e) {
896
- console.warn(e);
897
- } finally {
898
- await client.close();
899
- }
900
- }
901
- generateSearch(criteria) {
902
- if (!criteria["$search"]) return;
903
- if (this.config.type) {
904
- const modelFields = getModelFieldsWithOptions(
905
- new this.config.type()
906
- ).filter((i) => i.options.search);
907
- if (modelFields.length) {
908
- const searchArray = [];
909
- modelFields.forEach((val) => {
910
- const res = {};
911
- res[val.key] = {
912
- $regex: this.convertRegex(criteria["$search"]),
913
- $options: "i"
914
- };
915
- searchArray.push(res);
916
- });
917
- if (!criteria["$or"]) criteria["$or"] = searchArray;
918
- else if (criteria["$or"] && !criteria["$and"]) {
919
- criteria["$and"] = [{ $or: criteria["$or"] }, { $or: searchArray }];
920
- delete criteria["$or"];
921
- } else if (criteria["$and"]) {
922
- criteria["$and"] = [...criteria["$and"], { $or: searchArray }];
923
- }
924
- delete criteria["$search"];
925
- return;
926
- }
927
- }
928
- const customCriteria = {
929
- $text: { $search: ' "' + this.convertRegex(criteria["$search"]) + '" ' }
930
- };
931
- delete criteria["$search"];
932
- Object.assign(criteria, customCriteria);
933
- }
934
- convertIdInCriteria(criteria) {
935
- if (criteria["id"]) {
936
- criteria["_id"] = criteria["id"];
937
- delete criteria["id"];
938
- }
939
- }
940
- convertRegex(val) {
941
- return val.toString().replace(/\*/g, "[*]");
942
- }
943
- async collectionContext(callback, repoOptions) {
944
- const client = repoOptions?.transaction?.connection ? repoOptions.transaction.connection : await MongoClient3.connect(this.getUrl());
945
- const db = client.db(this.config.database);
946
- let result;
947
- try {
948
- result = await callback(db.collection(this.config.collection));
949
- } finally {
950
- if (!repoOptions?.transaction)
951
- await client.close();
952
- }
953
- return result;
954
- }
955
- };
956
- MongoItemRepository = __decorateClass([
957
- Injectable4()
958
- ], MongoItemRepository);
959
-
960
- // packages/shared/mongo/src/lib/mongo.module.ts
961
- var MongoModule = class _MongoModule {
962
- static forRoot(config) {
963
- const providers = [
964
- { provide: MongoConfig, useValue: config },
965
- { provide: IItemRepository, useClass: MongoItemRepository },
966
- { provide: IAttachmentRepository, useClass: MongoAttachmentRepository },
967
- { provide: IUnitOfWork, useClass: MongoUnitOfWork }
968
- ];
969
- return {
970
- module: _MongoModule,
971
- providers,
972
- exports: providers
973
- };
974
- }
975
- };
976
-
977
- // packages/shared/nestjs/src/lib/shared.config.ts
978
- import { Injectable as Injectable5 } from "@nestjs/common";
979
- var SharedConfig = class {
980
- tokenConfig;
981
- permissions;
982
- type;
983
- };
984
- SharedConfig = __decorateClass([
985
- Injectable5()
986
- ], SharedConfig);
987
-
988
- // packages/shared/nestjs/src/lib/auth/jwt.strategy.ts
989
- import { Injectable as Injectable6 } from "@nestjs/common";
990
- import { PassportStrategy } from "@nestjs/passport";
991
- import { ExtractJwt, Strategy } from "passport-jwt";
992
- var JwtStrategy = class extends PassportStrategy(Strategy) {
993
- constructor(config) {
994
- super({
995
- jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
996
- ignoreExpiration: false,
997
- secretOrKey: config.tokenConfig?.secretOrPrivateKey
998
- });
999
- this.config = config;
1000
- }
1001
- config;
1002
- async validate(payload) {
1003
- return {
1004
- ...payload,
1005
- permissions: payload.permissions,
1006
- username: payload.sub
1007
- };
1008
- }
1009
- };
1010
- JwtStrategy = __decorateClass([
1011
- Injectable6()
1012
- ], JwtStrategy);
1013
-
1014
- // packages/shared/nestjs/src/lib/auth/permission.service.ts
1015
- import { Injectable as Injectable7 } from "@nestjs/common";
1016
- var PermissionService = class {
1017
- constructor(config) {
1018
- this.config = config;
1019
- }
1020
- config;
1021
- /**
1022
- * Validates if the user has the required permissions for a given type.
1023
- * @param {PermissionType} type - The type of permission to validate.
1024
- * @param {IUser} user - The user object containing permissions.
1025
- * @throws {DomainForbiddenError} If the user does not have the required permissions.
1026
- */
1027
- valid(type, user) {
1028
- if (!this.config.permissions) return;
1029
- const typeConfig = this.config.permissions[type];
1030
- if (!typeConfig) return;
1031
- if (!user.permissions) throw new DomainForbiddenError(`Context forbidden`);
1032
- if (!typeConfig.some((tc) => user.permissions.some((up) => tc === up)))
1033
- throw new DomainForbiddenError(`Context forbidden`);
1034
- }
1035
- };
1036
- PermissionService = __decorateClass([
1037
- Injectable7()
1038
- ], PermissionService);
1039
-
1040
- // packages/shared/nestjs/src/lib/shared.module.ts
1041
- var SharedModule = class _SharedModule {
1042
- /**
1043
- * Configures the module's core functionalities.
1044
- *
1045
- * @param {SharedConfig} config - An object containing the module's configuration.
1046
- * @returns {DynamicModule} A DynamicModule object with providers and exports.
1047
- */
1048
- static forFeature(config) {
1049
- return {
1050
- module: _SharedModule,
1051
- providers: [
1052
- { provide: SharedConfig, useValue: config },
1053
- JwtStrategy,
1054
- PermissionService
1055
- ],
1056
- exports: [
1057
- { provide: SharedConfig, useValue: config },
1058
- PermissionService,
1059
- JwtStrategy
1060
- ]
1061
- };
1062
- }
1063
- /**
1064
- * Extends the forFeature() configuration by adding database settings. Use in AppModule.
1065
- *
1066
- * @param {SharedConfig & { db: { host: string; port: number; database: string; username?: string; password?: string; }}} config - An extended SharedConfig object that includes additional database settings.
1067
- * @returns {DynamicModule} A DynamicModule object that imports and exports the forFeature() configuration.
1068
- */
1069
- static forRoot(config) {
1070
- return {
1071
- module: _SharedModule,
1072
- imports: [_SharedModule.forFeature(config)],
1073
- exports: [_SharedModule.forFeature(config)]
1074
- };
1075
- }
1076
- };
1077
-
1078
- // packages/shared/nestjs/src/lib/filters/execution/exception.filter.ts
1079
- import {
1080
- Catch,
1081
- HttpException,
1082
- HttpStatus,
1083
- Logger as Logger2
1084
- } from "@nestjs/common";
1085
- var AppExceptionFilter = class {
1086
- /**
1087
- * Method to catch and handle exceptions.
1088
- *
1089
- * @param {any} exception - The exception thrown.
1090
- * @param {ArgumentsHost} host - The arguments host.
1091
- */
1092
- catch(exception, host) {
1093
- const ctx = host.switchToHttp();
1094
- const response = ctx.getResponse();
1095
- let status = HttpStatus.INTERNAL_SERVER_ERROR;
1096
- let message = null;
1097
- if (exception instanceof HttpException) {
1098
- status = exception.getStatus();
1099
- message = exception["message"];
1100
- } else if (exception["type"] === DomainValidationError) {
1101
- status = HttpStatus.BAD_REQUEST;
1102
- message = exception["message"];
1103
- } else if (exception["type"] === DomainForbiddenError) {
1104
- status = HttpStatus.FORBIDDEN;
1105
- message = exception["message"];
1106
- } else {
1107
- status = HttpStatus.INTERNAL_SERVER_ERROR;
1108
- message = "Internal server error";
1109
- }
1110
- Logger2.error(
1111
- exception["stack"] || exception["message"] || exception,
1112
- AppExceptionFilter.name
1113
- );
1114
- const result = response.status(status);
1115
- if (message && result.json) {
1116
- result.json({
1117
- details: message
1118
- });
1119
- } else if (!message && result.json) {
1120
- result.json();
1121
- } else if (message && !result.json) {
1122
- result.send({
1123
- details: message
1124
- });
1125
- } else {
1126
- result.send();
1127
- }
1128
- }
1129
- };
1130
- AppExceptionFilter = __decorateClass([
1131
- Catch()
1132
- ], AppExceptionFilter);
1133
-
1134
- // packages/shared/nestjs/src/lib/decorators/user/user.decorator.ts
1135
- import { createParamDecorator } from "@nestjs/common";
1136
- var User = createParamDecorator((_3, context) => {
1137
- const [req] = context.getArgs();
1138
- return req.user;
1139
- });
1140
-
1141
- // packages/crud/shell/nestjs/src/lib/controllers/crud/crud.controller.ts
1142
- import {
1143
- Body,
1144
- Controller,
1145
- Delete,
1146
- Get,
1147
- HttpCode,
1148
- NotFoundException,
1149
- Param,
1150
- Patch,
1151
- Post,
1152
- Put,
1153
- Query,
1154
- Req,
1155
- Res,
1156
- UseGuards
1157
- } from "@nestjs/common";
1158
- import * as Busboy from "busboy";
1159
- import { Parser } from "json2csv";
1160
- import * as _2 from "lodash";
1161
- import moment from "moment-timezone";
1162
- import * as XLSX from "xlsx";
1163
- import { Readable } from "stream";
1164
-
1165
- // packages/crud/shell/nestjs/src/lib/controllers/crud/query-to-mongo.ts
1166
- import * as querystring from "querystring";
1167
- var iso8601 = /^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?(T([01][0-9]|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?(Z|[+-]\d{2}:\d{2}))?$/;
1168
- function fieldsToMongo(fields) {
1169
- if (!fields) return null;
1170
- const hash = {};
1171
- fields.split(",").forEach(function(field) {
1172
- hash[field.trim()] = 1;
1173
- });
1174
- return hash;
1175
- }
1176
- function convertRegex(val) {
1177
- return val.toString().replace(/\*/g, "[*]");
1178
- }
1179
- function omitFieldsToMongo(omitFields) {
1180
- if (!omitFields) return null;
1181
- const hash = {};
1182
- omitFields.split(",").forEach(function(omitField) {
1183
- hash[omitField.trim()] = 0;
1184
- });
1185
- return hash;
1186
- }
1187
- function sortToMongo(sort) {
1188
- if (!sort) return null;
1189
- const hash = {};
1190
- let c;
1191
- sort.split(",").forEach(function(field) {
1192
- c = field.charAt(0);
1193
- if (c === "-") field = field.substr(1);
1194
- hash[field.trim()] = c === "-" ? -1 : 1;
1195
- });
1196
- return hash;
1197
- }
1198
- function typedValue(value) {
1199
- if (value[0] === "!") value = value.substr(1);
1200
- const regex = value.match(/^\/(.*)\/(i?)$/);
1201
- const quotedString = value.match(/(["'])(?:\\\1|.)*?\1/);
1202
- if (regex) {
1203
- return new RegExp(regex[1], regex[2]);
1204
- } else if (quotedString) {
1205
- return quotedString[0].substr(1, quotedString[0].length - 2);
1206
- } else if (value === "true") {
1207
- return true;
1208
- } else if (value === "false") {
1209
- return false;
1210
- } else if (iso8601.test(value) && value.length !== 4 && value.length !== 10) {
1211
- return new Date(value);
1212
- } else if (!isNaN(Number(value))) {
1213
- return Number(value);
1214
- }
1215
- return value;
1216
- }
1217
- function typedValues(svalue) {
1218
- const commaSplit = /("[^"]*")|('[^']*')|(\/[^/]*\/i?)|([^,]+)/g;
1219
- const values = [];
1220
- svalue.match(commaSplit).forEach(function(value) {
1221
- values.push(typedValue(value));
1222
- });
1223
- return values;
1224
- }
1225
- function comparisonToMongo(key, value) {
1226
- const join = value === "" ? key : key.concat("=", value);
1227
- const parts = join.match(/^(!?[^><~!=:]+)(?:=?([><]=?|~?=|!?=|:.+=)(.+))?$/);
1228
- let op;
1229
- const hash = {};
1230
- if (!parts) return null;
1231
- key = parts[1];
1232
- op = parts[2];
1233
- if (!op) {
1234
- if (key[0] !== "!") value = { $exists: true };
1235
- else {
1236
- key = key.substr(1);
1237
- value = { $exists: false };
1238
- }
1239
- } else if (op === "=" && parts[3] === "!") {
1240
- value = { $exists: false };
1241
- } else if (op === "=" || op === "!=") {
1242
- if (op === "=" && parts[3][0] === "!") op = "!=";
1243
- const array = typedValues(parts[3]);
1244
- if (array.length > 1) {
1245
- value = {};
1246
- op = op === "=" ? "$in" : "$nin";
1247
- value[op] = array;
1248
- } else if (op === "!=") {
1249
- value = array[0] instanceof RegExp ? { $not: array[0] } : { $ne: array[0] };
1250
- } else if (array[0][0] === "!") {
1251
- const sValue = array[0].substr(1);
1252
- const regex = sValue.match(/^\/(.*)\/(i?)$/);
1253
- value = regex ? { $not: new RegExp(regex[1], regex[2]) } : { $ne: sValue };
1254
- } else {
1255
- value = array[0];
1256
- }
1257
- } else if (op[0] === ":" && op[op.length - 1] === "=") {
1258
- op = "$" + op.substr(1, op.length - 2);
1259
- const array = [];
1260
- parts[3].split(",").forEach(function(value2) {
1261
- array.push(typedValue(value2));
1262
- });
1263
- value = {};
1264
- value[op] = array.length === 1 ? array[0] : array;
1265
- } else {
1266
- value = typedValue(parts[3]);
1267
- if (op === ">") value = { $gt: value };
1268
- else if (op === ">=") value = { $gte: value };
1269
- else if (op === "<") value = { $lt: value };
1270
- else if (op === "<=") value = { $lte: value };
1271
- else if (op === "~=")
1272
- value = {
1273
- $regex: value ? convertRegex(value) : "",
1274
- $options: "i"
1275
- };
1276
- }
1277
- hash.key = key;
1278
- hash.value = value;
1279
- return hash;
1280
- }
1281
- function hasOrdinalKeys(obj) {
1282
- let c = 0;
1283
- for (const key in obj) {
1284
- if (Number(key) !== c++) return false;
1285
- }
1286
- return true;
1287
- }
1288
- function queryCriteriaToMongo(query, options = null) {
1289
- const hash = {};
1290
- let deep, p;
1291
- options = options || {};
1292
- for (const key in query) {
1293
- if (Object.prototype.hasOwnProperty.call(query, key) && (!options.ignore || options.ignore.indexOf(key) === -1)) {
1294
- deep = typeof query[key] === "object" && !hasOrdinalKeys(query[key]);
1295
- if (deep) {
1296
- p = {
1297
- key,
1298
- value: queryCriteriaToMongo(query[key])
1299
- };
1300
- } else {
1301
- p = comparisonToMongo(key, query[key]);
1302
- }
1303
- if (p) {
1304
- if (!hash[p.key]) {
1305
- hash[p.key] = p.value;
1306
- } else if (typeof p.value === "string") {
1307
- hash[p.key] = Object.assign(hash[p.key], {
1308
- $eq: p.value
1309
- });
1310
- } else {
1311
- hash[p.key] = Object.assign(hash[p.key], p.value);
1312
- }
1313
- }
1314
- }
1315
- }
1316
- return hash;
1317
- }
1318
- function queryOptionsToMongo(query, options) {
1319
- const hash = {}, fields = fieldsToMongo(query[options.keywords.fields]), omitFields = omitFieldsToMongo(query[options.keywords.omit]), sort = sortToMongo(query[options.keywords.sort]), maxLimit = options.maxLimit || 9007199254740992;
1320
- let limit = options.maxLimit || 0;
1321
- if (fields) hash.fields = fields;
1322
- if (omitFields) hash.fields = omitFields;
1323
- if (sort) hash.sort = sort;
1324
- if (query[options.keywords.offset])
1325
- hash.skip = Number(query[options.keywords.offset]);
1326
- if (query[options.keywords.limit])
1327
- limit = Math.min(Number(query[options.keywords.limit]), maxLimit);
1328
- if (limit) {
1329
- hash.limit = limit;
1330
- } else if (options.maxLimit) {
1331
- hash.limit = maxLimit;
1332
- }
1333
- return hash;
1334
- }
1335
- function q2m(query = null, options = null) {
1336
- query = query || {};
1337
- options = options || {};
1338
- options.keywords = options.keywords || {};
1339
- const defaultKeywords = {
1340
- fields: "fields",
1341
- omit: "omit",
1342
- sort: "sort",
1343
- offset: "offset",
1344
- limit: "limit"
1345
- };
1346
- options.keywords = Object.assign(defaultKeywords, options.keywords);
1347
- const ignoreKeywords = [
1348
- options.keywords.fields,
1349
- options.keywords.omit,
1350
- options.keywords.sort,
1351
- options.keywords.offset,
1352
- options.keywords.limit
1353
- ];
1354
- if (!options.ignore) {
1355
- options.ignore = [];
1356
- } else {
1357
- options.ignore = typeof options.ignore === "string" ? [options.ignore] : options.ignore;
1358
- }
1359
- options.ignore = options.ignore.concat(ignoreKeywords);
1360
- if (!options.parser) options.parser = querystring;
1361
- if (typeof query === "string") query = options.parser.parse(query);
1362
- return {
1363
- criteria: queryCriteriaToMongo(query, options),
1364
- options: queryOptionsToMongo(query, options),
1365
- links: function(url, totalCount) {
1366
- const offset = this.options.skip || 0;
1367
- const limit = Math.min(this.options.limit || 0, totalCount);
1368
- const links = {};
1369
- const last = {};
1370
- if (!limit) return null;
1371
- options = options || {};
1372
- if (offset > 0) {
1373
- query[options.keywords.offset] = Math.max(offset - limit, 0);
1374
- links["prev"] = url + "?" + options.parser.stringify(query);
1375
- query[options.keywords.offset] = 0;
1376
- links["first"] = url + "?" + options.parser.stringify(query);
1377
- }
1378
- if (offset + limit < totalCount) {
1379
- last.pages = Math.ceil(totalCount / limit);
1380
- last.offset = (last.pages - 1) * limit;
1381
- query[options.keywords.offset] = Math.min(offset + limit, last.offset);
1382
- links["next"] = url + "?" + options.parser.stringify(query);
1383
- query[options.keywords.offset] = last.offset;
1384
- links["last"] = url + "?" + options.parser.stringify(query);
1385
- }
1386
- return links;
1387
- }
1388
- };
1389
- }
1390
-
1391
- // packages/crud/shell/nestjs/src/lib/guards/auth/auth.guard.ts
1392
- import { Injectable as Injectable8, UnauthorizedException, Logger as Logger3 } from "@nestjs/common";
1393
- import { AuthGuard } from "@nestjs/passport";
1394
- var AuthJwtGuard = class extends AuthGuard("jwt") {
1395
- logger = new Logger3(AuthJwtGuard.name, { timestamp: true });
1396
- handleRequest(err, user, info) {
1397
- if (err || !user) {
1398
- this.logger.warn(JSON.stringify(info));
1399
- throw err || new UnauthorizedException();
1400
- }
1401
- return user;
1402
- }
1403
- };
1404
- AuthJwtGuard = __decorateClass([
1405
- Injectable8()
1406
- ], AuthJwtGuard);
1407
- var AuthOrAnonymousJwtGuard = class extends AuthGuard("jwt") {
1408
- handleRequest(err, user, info) {
1409
- return user;
1410
- }
1411
- };
1412
- AuthOrAnonymousJwtGuard = __decorateClass([
1413
- Injectable8()
1414
- ], AuthOrAnonymousJwtGuard);
1415
-
1416
- // packages/crud/shell/nestjs/src/lib/controllers/crud/crud.controller.ts
1417
- var CrudController = class {
1418
- constructor(service) {
1419
- this.service = service;
1420
- }
1421
- service;
1422
- static getLink(req) {
1423
- return req.protocol + "://" + req.headers.host + req.url;
1424
- }
1425
- async create(data, user, res) {
1426
- const id = await this.service.create(data, user);
1427
- res.set("Location", CrudController.getLink(res.req) + "/" + id);
1428
- return res.send({
1429
- id
1430
- });
1431
- }
1432
- async createMany(data, user, res, mode) {
1433
- const result = await this.service.createMany(data, user, { mode });
1434
- return res.send(result);
1435
- }
1436
- async readById(params, user) {
1437
- const result = await this.service.readById(params.id, user);
1438
- if (!result) {
1439
- throw new NotFoundException("Invalid id");
1440
- }
1441
- return result;
1442
- }
1443
- async read(user, req, res) {
1444
- const object = this.getQueryObject(req.query);
1445
- const { data, totalCount } = await this.service.read(
1446
- object.criteria,
1447
- {
1448
- ...object.options,
1449
- allowDiskUse: req.headers["content-type"] === "text/csv" || req.headers["content-type"] === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1450
- },
1451
- user
1452
- );
1453
- if (req.headers["content-type"] === "text/csv") {
1454
- res.set({
1455
- "Content-Type": "text/csv"
1456
- });
1457
- res.send(this.parseToCsv(data));
1458
- }
1459
- if (req.headers["content-type"] === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
1460
- res.set({
1461
- "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1462
- });
1463
- res.send(this.parseToXlsx(data));
1464
- }
1465
- res.send({
1466
- data,
1467
- totalCount,
1468
- links: object.links(
1469
- CrudController.getLink(req).split("?")[0],
1470
- totalCount
1471
- )
1472
- });
1473
- }
1474
- async update(params, data, user) {
1475
- await this.service.update(params.id, data, user);
1476
- }
1477
- async updatePartial(params, data, user) {
1478
- await this.service.updatePartial(params.id, data, user);
1479
- }
1480
- async delete(params, user) {
1481
- await this.service.delete(params.id, user);
1482
- }
1483
- uploadAttachment(request, response) {
1484
- const busboy = new Busboy({
1485
- headers: request.headers
1486
- });
1487
- const id = GuidService.create();
1488
- const readable = new Readable();
1489
- readable._read = () => {
1490
- };
1491
- let fileName, encoding, mimeType;
1492
- busboy.on(
1493
- "file",
1494
- (field, file, resultFileName, resultEncoding, resultMimeType) => {
1495
- fileName = resultFileName;
1496
- encoding = resultEncoding;
1497
- mimeType = resultMimeType;
1498
- this.service.uploadAttachment({
1499
- id,
1500
- stream: readable,
1501
- fileName,
1502
- encoding,
1503
- mimeType
1504
- });
1505
- file.on("data", (data) => {
1506
- readable.push(data);
1507
- });
1508
- }
1509
- );
1510
- busboy.on("finish", function() {
1511
- readable.push(null);
1512
- response.set("Location", CrudController.getLink(response.req) + "/" + id);
1513
- response.json({
1514
- id,
1515
- fileName,
1516
- contentType: mimeType,
1517
- length: readable.readableLength
1518
- });
1519
- response.end();
1520
- });
1521
- return request.pipe(busboy);
1522
- }
1523
- async downloadAttachment(id, request, response) {
1524
- const fileInfo = await this.service.getAttachmentInfo(id);
1525
- if (request.headers.range) {
1526
- const range = request.headers.range.substr(6).split("-");
1527
- const start = parseInt(range[0], 10);
1528
- const end = parseInt(range[1], 10) || null;
1529
- const readstream = await this.service.getAttachmentStream(id, {
1530
- start,
1531
- end
1532
- });
1533
- response.status(206);
1534
- response.set({
1535
- "Accept-Ranges": "bytes",
1536
- "Content-Type": fileInfo.contentType,
1537
- "Content-Range": `bytes ${start}-${end ? end : fileInfo.length - 1}/${fileInfo.length}`,
1538
- "Content-Length": (end ? end : fileInfo.length) - start,
1539
- "Content-Disposition": `attachment; filename="${encodeURI(fileInfo.fileName)}"`
1540
- });
1541
- response.on("close", () => {
1542
- readstream.destroy();
1543
- });
1544
- readstream.pipe(response);
1545
- } else {
1546
- const readstream = await this.service.getAttachmentStream(id);
1547
- response.on("close", () => {
1548
- readstream.destroy();
1549
- });
1550
- response.status(200);
1551
- response.set({
1552
- "Accept-Range": "bytes",
1553
- "Content-Type": fileInfo.contentType,
1554
- "Content-Length": fileInfo.length,
1555
- "Content-Disposition": `attachment; filename="${encodeURI(fileInfo.fileName)}"`
1556
- });
1557
- readstream.pipe(response);
1558
- }
1559
- }
1560
- async deleteAttachment(id) {
1561
- await this.service.deleteAttachment(id);
1562
- }
1563
- getQueryObject(queryObject) {
1564
- let q = "";
1565
- Object.keys(queryObject).forEach((key) => {
1566
- q += `&${key}=${queryObject[key]}`;
1567
- });
1568
- const result = q2m(q);
1569
- return result;
1570
- }
1571
- parseToXlsx(data) {
1572
- if (!data || !data.length) {
1573
- return "";
1574
- }
1575
- const { res } = this.getDataWithFields(data);
1576
- const ws = XLSX.utils.json_to_sheet(res);
1577
- const wb = XLSX.utils.book_new();
1578
- XLSX.utils.book_append_sheet(wb, ws, "data");
1579
- return XLSX.write(wb, { bookType: "xlsx", type: "buffer" });
1580
- }
1581
- parseToCsv(data) {
1582
- if (!data || !data.length) {
1583
- return "";
1584
- }
1585
- const { res, fields } = this.getDataWithFields(data);
1586
- return new Parser(fields).parse(data);
1587
- }
1588
- getDataWithFields(data) {
1589
- const fields = [];
1590
- const execute = (item, baseKey, baseItem) => {
1591
- Object.keys(item).forEach((key) => {
1592
- if (item[key] && typeof item[key] === "string") {
1593
- item[key] = item[key].replace(/<[^>]*>?/gm, "");
1594
- }
1595
- if (item[key] && item[key] instanceof Date) {
1596
- item[key] = moment(item[key]).tz("Europe/Warsaw").format("YYYY-MM-DD HH:mm:ss");
1597
- }
1598
- const val = item[key];
1599
- if (_2.isArray(val)) {
1600
- return;
1601
- } else if (_2.isObject(val) && Object.keys(val).length) {
1602
- execute(val, baseKey + key + "_", baseItem);
1603
- } else if (baseKey) {
1604
- baseItem[baseKey + key] = val;
1605
- if (!fields.some((f) => f === baseKey + key))
1606
- fields.push(baseKey + key);
1607
- } else {
1608
- if (!fields.some((f) => f === key)) fields.push(key);
1609
- }
1610
- });
1611
- };
1612
- data.forEach((item) => {
1613
- execute(item, "", item);
1614
- });
1615
- data.forEach((item) => {
1616
- Object.keys(item).forEach((key) => {
1617
- if (!fields.some((f) => f === key)) {
1618
- delete item[key];
1619
- }
1620
- });
1621
- });
1622
- return { res: data, fields };
1623
- }
1624
- };
1625
- __decorateClass([
1626
- UseGuards(AuthJwtGuard),
1627
- Post(),
1628
- HttpCode(200),
1629
- __decorateParam(0, Body()),
1630
- __decorateParam(1, User()),
1631
- __decorateParam(2, Res())
1632
- ], CrudController.prototype, "create", 1);
1633
- __decorateClass([
1634
- UseGuards(AuthJwtGuard),
1635
- Post("bulk"),
1636
- __decorateParam(0, Body()),
1637
- __decorateParam(1, User()),
1638
- __decorateParam(2, Res()),
1639
- __decorateParam(3, Query("mode"))
1640
- ], CrudController.prototype, "createMany", 1);
1641
- __decorateClass([
1642
- UseGuards(AuthOrAnonymousJwtGuard),
1643
- Get(":id"),
1644
- __decorateParam(0, Param()),
1645
- __decorateParam(1, User())
1646
- ], CrudController.prototype, "readById", 1);
1647
- __decorateClass([
1648
- UseGuards(AuthOrAnonymousJwtGuard),
1649
- Get(),
1650
- __decorateParam(0, User()),
1651
- __decorateParam(1, Req()),
1652
- __decorateParam(2, Res())
1653
- ], CrudController.prototype, "read", 1);
1654
- __decorateClass([
1655
- UseGuards(AuthJwtGuard),
1656
- Put(":id"),
1657
- __decorateParam(0, Param()),
1658
- __decorateParam(1, Body()),
1659
- __decorateParam(2, User())
1660
- ], CrudController.prototype, "update", 1);
1661
- __decorateClass([
1662
- UseGuards(AuthJwtGuard),
1663
- Patch(":id"),
1664
- __decorateParam(0, Param()),
1665
- __decorateParam(1, Body()),
1666
- __decorateParam(2, User())
1667
- ], CrudController.prototype, "updatePartial", 1);
1668
- __decorateClass([
1669
- UseGuards(AuthJwtGuard),
1670
- Delete(":id"),
1671
- __decorateParam(0, Param()),
1672
- __decorateParam(1, User())
1673
- ], CrudController.prototype, "delete", 1);
1674
- __decorateClass([
1675
- Post("attachments"),
1676
- __decorateParam(0, Req()),
1677
- __decorateParam(1, Res())
1678
- ], CrudController.prototype, "uploadAttachment", 1);
1679
- __decorateClass([
1680
- Get("attachments/:id"),
1681
- __decorateParam(0, Param("id")),
1682
- __decorateParam(1, Req()),
1683
- __decorateParam(2, Res())
1684
- ], CrudController.prototype, "downloadAttachment", 1);
1685
- __decorateClass([
1686
- Delete("attachments/:id"),
1687
- __decorateParam(0, Param("id"))
1688
- ], CrudController.prototype, "deleteAttachment", 1);
1689
- CrudController = __decorateClass([
1690
- Controller("")
1691
- ], CrudController);
1692
-
1693
- // packages/crud/shell/nestjs/src/lib/controllers/index.ts
1694
- var CONTROLLERS = [CrudController];
1695
-
1696
- // packages/crud/shell/nestjs/src/lib/gateways/crud/crud.gateway.ts
1697
- import {
1698
- ConnectedSocket,
1699
- MessageBody,
1700
- SubscribeMessage,
1701
- WebSocketGateway
1702
- } from "@nestjs/websockets";
1703
- import { Observable as Observable2 } from "rxjs";
1704
- var CrudGateway = class {
1705
- constructor(service) {
1706
- this.service = service;
1707
- }
1708
- service;
1709
- _clientsSubscriptions;
1710
- handleFilter(data, client) {
1711
- const event = "changes";
1712
- return new Observable2((observer) => {
1713
- this.clearSubscription(client);
1714
- this._clientsSubscriptions.set(
1715
- client.id,
1716
- this.service.changes(data).subscribe(
1717
- (res) => {
1718
- observer.next({ event, data: res });
1719
- },
1720
- (error) => observer.error(error)
1721
- )
1722
- );
1723
- });
1724
- }
1725
- afterInit(server) {
1726
- this._clientsSubscriptions = /* @__PURE__ */ new Map();
1727
- console.log("CrudGateway Init");
1728
- }
1729
- handleDisconnect(client) {
1730
- this.clearSubscription(client);
1731
- console.log(`Client disconnected: ${client.id}`);
1732
- }
1733
- clearSubscription(client) {
1734
- if (this._clientsSubscriptions.has(client.id)) {
1735
- this._clientsSubscriptions.get(client.id).unsubscribe();
1736
- this._clientsSubscriptions.delete(client.id);
1737
- }
1738
- }
1739
- handleConnection(client, ...args) {
1740
- console.log(`Client connected: ${client.id}`);
1741
- }
1742
- };
1743
- __decorateClass([
1744
- SubscribeMessage("changes"),
1745
- __decorateParam(0, MessageBody()),
1746
- __decorateParam(1, ConnectedSocket())
1747
- ], CrudGateway.prototype, "handleFilter", 1);
1748
- CrudGateway = __decorateClass([
1749
- WebSocketGateway({
1750
- transports: ["websocket"],
1751
- path: "/" + process.env.URL_PREFIX + "/_socket",
1752
- namespace: "/" + process.env.URL_PREFIX
1753
- })
1754
- ], CrudGateway);
1755
-
1756
- // packages/crud/shell/nestjs/src/lib/gateways/index.ts
1757
- var GATEWAYS = [CrudGateway];
1758
-
1759
- // packages/crud/shell/nestjs/src/lib/nestjs.module.ts
1760
- var CrudShellNestjsModule = class {
1761
- static forRoot(options) {
1762
- return {
1763
- module: CrudShellNestjsModule,
1764
- controllers: options.restApi ? CONTROLLERS : [],
1765
- providers: [
1766
- ...SERVICES,
1767
- ...options.socket ? GATEWAYS : [],
1768
- AuthJwtGuard
1769
- ],
1770
- imports: [
1771
- ...options.restApi && options.tokenConfig.secretOrPrivateKey ? [
1772
- PassportModule.register({
1773
- defaultStrategy: "jwt",
1774
- session: false
1775
- }),
1776
- JwtModule.register({
1777
- secret: options.tokenConfig.secretOrPrivateKey,
1778
- signOptions: {
1779
- expiresIn: options.tokenConfig.expiredIn
1780
- }
1781
- })
1782
- ] : [],
1783
- SharedModule.forFeature(options),
1784
- MongoModule.forRoot(options.db)
1785
- ],
1786
- exports: [...SERVICES, AuthJwtGuard, MongoModule.forRoot(options.db)]
1787
- };
1788
- }
1789
- };
1790
- CrudShellNestjsModule = __decorateClass([
1791
- Module({})
1792
- ], CrudShellNestjsModule);
1793
- var CrudShellNestjsCoreModule = class {
1794
- static forRoot(options) {
1795
- return {
1796
- module: CrudShellNestjsModule,
1797
- providers: [...SERVICES, ...GATEWAYS, AuthJwtGuard],
1798
- imports: [
1799
- PassportModule.register({ defaultStrategy: "jwt", session: false }),
1800
- JwtModule.register({
1801
- secret: options.tokenConfig.secretOrPrivateKey,
1802
- signOptions: {
1803
- expiresIn: options.tokenConfig.expiredIn
1804
- }
1805
- }),
1806
- SharedModule.forRoot(options),
1807
- MongoModule.forRoot(options.db)
1808
- ],
1809
- exports: []
1810
- };
1811
- }
1812
- };
1813
- CrudShellNestjsCoreModule = __decorateClass([
1814
- Module({})
1815
- ], CrudShellNestjsCoreModule);
1816
-
1817
- // packages/shared/paynow/src/lib/paynow.service.ts
1818
- import { Injectable as Injectable9, Logger as Logger4 } from "@nestjs/common";
1819
- import * as CryptoJS from "crypto-js";
1820
-
1821
- // packages/shared/paynow/src/lib/paynow.config.ts
1822
- var PaynowConfig = class {
1823
- test;
1824
- apiKey;
1825
- apiSignatureKey;
1826
- continueUrl;
1827
- };
1828
- var PAYNOW_CONFIG_PROVIDER = "PAYNOW_CONFIG_PROVIDER";
1829
-
1830
- // packages/shared/paynow/src/lib/paynow.service.ts
1831
- var PaynowService = class {
1832
- constructor(httpService, config, moduleRef) {
1833
- this.httpService = httpService;
1834
- this.config = config;
1835
- this.moduleRef = moduleRef;
1836
- }
1837
- httpService;
1838
- config;
1839
- moduleRef;
1840
- async create(obj) {
1841
- const config = await this.getConfig(obj.data);
1842
- const data = {
1843
- externalId: obj.id,
1844
- description: obj.name,
1845
- currency: "PLN",
1846
- amount: obj.amount,
1847
- continueUrl: config.continueUrl,
1848
- buyer: {
1849
- email: obj.email
1850
- }
1851
- };
1852
- if (obj.contactPhone || obj.firstName || obj.lastName) {
1853
- data["buyer"] = {
1854
- email: obj.email,
1855
- phone: obj.contactPhone,
1856
- firstName: obj.firstName,
1857
- lastName: obj.lastName
1858
- };
1859
- }
1860
- const signature = this.getSignature(data, config);
1861
- const response = await this.httpService.post(this.getBaseUrl(config) + "/v1/payments", data, {
1862
- headers: {
1863
- "Content-Type": "application/json",
1864
- "Api-Key": config.apiKey,
1865
- "Idempotency-Key": GuidService.create(),
1866
- Signature: signature
1867
- },
1868
- maxRedirects: 0
1869
- }).toPromise();
1870
- return {
1871
- redirectUrl: response.data.redirectUrl,
1872
- orderId: response.data.paymentId
1873
- };
1874
- }
1875
- async getStatus(trans) {
1876
- const orderId = this.getOrderId(trans);
1877
- const config = await this.getConfig(trans.data);
1878
- const response = await this.httpService.get(this.getBaseUrl(config) + "/v1/payments/" + orderId + "/status", {
1879
- headers: {
1880
- "Content-Type": "application/json",
1881
- "Api-Key": config.apiKey
1882
- }
1883
- }).toPromise();
1884
- return {
1885
- status: this.getStatusFromExternal(response.data.status),
1886
- data: response.data
1887
- };
1888
- }
1889
- async refund(trans, comment) {
1890
- const orderId = this.getOrderId(trans);
1891
- const config = await this.getConfig(trans.data);
1892
- const data = {
1893
- amount: trans.amount
1894
- };
1895
- const signature = this.getSignature(data, config);
1896
- const response = await this.httpService.post(
1897
- this.getBaseUrl(config) + "/v1/payments/" + orderId + "/refunds",
1898
- data,
1899
- {
1900
- headers: {
1901
- "Content-Type": "application/json",
1902
- "Api-Key": config.apiKey,
1903
- "Idempotency-Key": GuidService.create(),
1904
- Signature: signature
1905
- }
1906
- }
1907
- ).toPromise();
1908
- return response.data;
1909
- }
1910
- getOrderId(trans) {
1911
- const historyItem = trans.history.find((x) => x.status === "started");
1912
- if (!historyItem) {
1913
- console.warn("Transaction without start status");
1914
- return null;
1915
- }
1916
- return historyItem.data.orderId;
1917
- }
1918
- async getConfig(data) {
1919
- try {
1920
- const provider = this.moduleRef.get(
1921
- PAYNOW_CONFIG_PROVIDER,
1922
- { strict: false }
1923
- );
1924
- return await provider.get(data);
1925
- } catch (e) {
1926
- Logger4.warn("Paynow config provider not found", PaynowService.name);
1927
- }
1928
- return this.config;
1929
- }
1930
- getBaseUrl(config) {
1931
- if (config.test) return "https://api.sandbox.paynow.pl";
1932
- return "https://api.paynow.pl";
1933
- }
1934
- getStatusFromExternal(status) {
1935
- switch (status) {
1936
- case "CONFIRMED":
1937
- return "completed";
1938
- case "REJECTED":
1939
- return "canceled";
1940
- case "PENDING":
1941
- return "pending";
1942
- default:
1943
- return status;
1944
- }
1945
- }
1946
- getSignature(data, config) {
1947
- return CryptoJS.enc.Base64.stringify(
1948
- CryptoJS.HmacSHA256(JSON.stringify(data), config.apiSignatureKey)
1949
- );
1950
- }
1951
- };
1952
- PaynowService = __decorateClass([
1953
- Injectable9()
1954
- ], PaynowService);
1955
-
1956
- // packages/shared/paypal/src/lib/paypal.config.ts
1957
- var PaypalConfig = class {
1958
- constructor(clientId, clientSecret, currencyCode, returnUrl, apiUrl, cancelUrl, test) {
1959
- this.clientId = clientId;
1960
- this.clientSecret = clientSecret;
1961
- this.currencyCode = currencyCode;
1962
- this.returnUrl = returnUrl;
1963
- this.apiUrl = apiUrl;
1964
- this.cancelUrl = cancelUrl;
1965
- this.test = test;
1966
- }
1967
- clientId;
1968
- clientSecret;
1969
- currencyCode;
1970
- returnUrl;
1971
- apiUrl;
1972
- cancelUrl;
1973
- test;
1974
- };
1975
- var PAYPAL_CONFIG_PROVIDER = "PAYPAL_CONFIG_PROVIDER";
1976
-
1977
- // packages/shared/paypal/src/lib/paypal.service.ts
1978
- import { Injectable as Injectable10, Logger as Logger5 } from "@nestjs/common";
1979
- import * as paypal from "paypal-rest-sdk";
1980
- var PaypalService = class {
1981
- constructor(httpService, config, moduleRef) {
1982
- this.httpService = httpService;
1983
- this.config = config;
1984
- this.moduleRef = moduleRef;
1985
- }
1986
- httpService;
1987
- config;
1988
- moduleRef;
1989
- async create(obj) {
1990
- const config = await this.getConfig(obj.data);
1991
- const data = {
1992
- intent: "sale",
1993
- payer: {
1994
- payment_method: "paypal"
1995
- },
1996
- redirect_urls: {
1997
- return_url: config.apiUrl + "paypal/" + obj.id + "/confirm",
1998
- cancel_url: config.cancelUrl
1999
- },
2000
- transactions: [
2001
- {
2002
- item_list: {
2003
- items: [
2004
- {
2005
- name: obj.name,
2006
- sku: obj.id,
2007
- price: obj.amount / 100,
2008
- currency: config.currencyCode,
2009
- quantity: 1
2010
- }
2011
- ]
2012
- },
2013
- amount: {
2014
- currency: config.currencyCode,
2015
- total: obj.amount / 100
2016
- },
2017
- description: obj.name
2018
- }
2019
- ]
2020
- };
2021
- const result = await new Promise((res, rej) => {
2022
- paypal.payment.create(
2023
- data,
2024
- this.getEnv(config),
2025
- (error, payment2) => {
2026
- if (error) {
2027
- rej(error);
2028
- } else {
2029
- res(payment2);
2030
- }
2031
- }
2032
- );
2033
- });
2034
- return {
2035
- redirectUrl: result.links.find(
2036
- (l) => l.rel === "approval_url"
2037
- ).href,
2038
- orderId: result.id
2039
- };
2040
- }
2041
- async confirm(payerId, paymentId, amount, externalData) {
2042
- const config = await this.getConfig(externalData);
2043
- const data = {
2044
- payer_id: payerId,
2045
- transactions: [
2046
- {
2047
- amount: {
2048
- currency: config.currencyCode,
2049
- total: amount
2050
- }
2051
- }
2052
- ]
2053
- };
2054
- return await new Promise((res, rej) => {
2055
- paypal.payment.execute(
2056
- paymentId,
2057
- data,
2058
- this.getEnv(config),
2059
- (error, payment2) => {
2060
- if (error) {
2061
- rej(error);
2062
- } else {
2063
- res(payment2);
2064
- }
2065
- }
2066
- );
2067
- });
2068
- }
2069
- async getStatus(trans) {
2070
- const orderId = this.getOrderId(trans) ?? "";
2071
- const config = await this.getConfig(trans.data);
2072
- const payment2 = await new Promise((res, rej) => {
2073
- paypal.payment.get(
2074
- orderId,
2075
- this.getEnv(config),
2076
- (error, result) => {
2077
- if (error) {
2078
- rej(error);
2079
- } else {
2080
- res(result);
2081
- }
2082
- }
2083
- );
2084
- });
2085
- return {
2086
- status: this.getStatusFromExternal(payment2.state),
2087
- data: payment2
2088
- };
2089
- }
2090
- async refund(trans, comment) {
2091
- const orderId = this.getOrderId(trans);
2092
- const config = await this.getConfig(trans.data);
2093
- const transactionId = this.getTransactionId(trans);
2094
- if (!transactionId) {
2095
- throw new Error("Paypal transaction ID not found for refund");
2096
- }
2097
- const refundData = {
2098
- amount: {
2099
- total: (trans.amount / 100).toString(),
2100
- currency: config.currencyCode
2101
- },
2102
- description: comment
2103
- };
2104
- return new Promise((resolve, reject) => {
2105
- paypal.sale.refund(
2106
- transactionId,
2107
- refundData,
2108
- this.getEnv(config),
2109
- (error, refund) => {
2110
- if (error) {
2111
- reject(error);
2112
- } else {
2113
- resolve(refund);
2114
- }
2115
- }
2116
- );
2117
- });
2118
- }
2119
- getOrderId(trans) {
2120
- const historyItem = trans.history.find((x) => x.status === "started");
2121
- if (!historyItem) {
2122
- console.warn("Transaction without start status");
2123
- return null;
2124
- }
2125
- return historyItem.data.orderId;
2126
- }
2127
- getStatusFromExternal(status) {
2128
- status = status.toUpperCase();
2129
- switch (status) {
2130
- case "COMPLETED":
2131
- return "completed";
2132
- case "VOIDED":
2133
- return "canceled";
2134
- case "CREATED":
2135
- return "pending";
2136
- case "SAVED":
2137
- return "pending";
2138
- case "APPROVED":
2139
- return "completed";
2140
- default:
2141
- return status;
2142
- }
2143
- }
2144
- async getConfig(data) {
2145
- try {
2146
- const provider = this.moduleRef.get(
2147
- PAYPAL_CONFIG_PROVIDER,
2148
- { strict: false }
2149
- );
2150
- return await provider.get(data);
2151
- } catch (e) {
2152
- Logger5.warn("PayPal config provider not found", PaypalService.name);
2153
- }
2154
- return this.config;
2155
- }
2156
- getEnv(config) {
2157
- return {
2158
- mode: config.test ? "sandbox" : "live",
2159
- client_id: config.clientId,
2160
- client_secret: config.clientSecret
2161
- };
2162
- }
2163
- getApiUrl(config) {
2164
- return config.test ? "https://api-m.sandbox.paypal.com/" : "https://api-m.paypal.com/";
2165
- }
2166
- getTransactionId(trans) {
2167
- const historyItem = trans.history.find(
2168
- (i) => i.status === "completed" && i.data && i.data.customData && i.data.customData.transactions && i.data.customData.transactions.length && i.data.customData.transactions[0].related_resources && i.data.customData.transactions[0].related_resources.length && i.data.customData.transactions[0].related_resources[0].sale
2169
- );
2170
- return historyItem ? historyItem.data.customData.transactions[0].related_resources[0].sale.id : null;
2171
- }
2172
- };
2173
- PaypalService = __decorateClass([
2174
- Injectable10()
2175
- ], PaypalService);
2176
-
2177
- // packages/shared/payu/src/lib/payu.service.ts
2178
- import { Injectable as Injectable11, Logger as Logger6 } from "@nestjs/common";
2179
-
2180
- // packages/shared/payu/src/lib/payu.config.ts
2181
- var PayuConfig = class {
2182
- test;
2183
- clientId;
2184
- clientSecret;
2185
- notifyUrl;
2186
- continueUrl;
2187
- posId;
2188
- };
2189
- var PAYU_CONFIG_PROVIDER = "PAYU_CONFIG_PROVIDER";
2190
-
2191
- // packages/shared/payu/src/lib/payu.service.ts
2192
- var PayuService = class {
2193
- constructor(httpService, config, moduleRef) {
2194
- this.httpService = httpService;
2195
- this.config = config;
2196
- this.moduleRef = moduleRef;
2197
- }
2198
- httpService;
2199
- config;
2200
- moduleRef;
2201
- async create(obj) {
2202
- const config = await this.getConfig(obj.data);
2203
- const token = await this.getToken(config);
2204
- const data = {
2205
- customerIp: obj.clientIp,
2206
- extOrderId: obj.id,
2207
- merchantPosId: config.posId,
2208
- description: obj.name,
2209
- currencyCode: "PLN",
2210
- totalAmount: obj.amount,
2211
- notifyUrl: config.notifyUrl,
2212
- continueUrl: config.continueUrl,
2213
- products: [
2214
- {
2215
- name: obj.name,
2216
- unitPrice: obj.amount,
2217
- quantity: "1"
2218
- }
2219
- ]
2220
- };
2221
- if (obj.options && obj.options["payMethod"]) {
2222
- data["payMethods"] = {
2223
- payMethod: obj.options["payMethod"]
2224
- };
2225
- }
2226
- if (obj.contactPhone || obj.email || obj.firstName || obj.lastName) {
2227
- data["buyer"] = {
2228
- email: obj.email,
2229
- phone: obj.contactPhone,
2230
- firstName: obj.firstName,
2231
- lastName: obj.lastName
2232
- };
2233
- }
2234
- try {
2235
- await this.httpService.post(this.getBaseUrl(config) + "/api/v2_1/orders", data, {
2236
- headers: {
2237
- "Content-Type": "application/json",
2238
- Authorization: "Bearer " + token,
2239
- "X-Requested-With": "XMLHttpRequest"
2240
- },
2241
- maxRedirects: 0
2242
- }).toPromise();
2243
- return null;
2244
- } catch (e) {
2245
- if (e.response && e.response.status === 302) {
2246
- return {
2247
- redirectUrl: e.response.data.redirectUri,
2248
- orderId: e.response.data.orderId
2249
- };
2250
- }
2251
- console.error(e);
2252
- throw e;
2253
- }
2254
- }
2255
- async getStatus(trans) {
2256
- const orderId = this.getOrderId(trans);
2257
- const config = await this.getConfig(trans.data);
2258
- const token = await this.getToken(config);
2259
- const response = await this.httpService.get(this.getBaseUrl(config) + "/api/v2_1/orders/" + orderId, {
2260
- headers: {
2261
- "Content-Type": "application/json",
2262
- Authorization: "Bearer " + token,
2263
- "X-Requested-With": "XMLHttpRequest"
2264
- },
2265
- maxRedirects: 0
2266
- }).toPromise();
2267
- if (!response.data.orders) return null;
2268
- const order = response.data.orders[0];
2269
- return {
2270
- status: this.getStatusFromExternal(order.status),
2271
- data: order
2272
- };
2273
- }
2274
- async refund(trans, comment) {
2275
- const orderId = this.getOrderId(trans);
2276
- const config = await this.getConfig(trans.data);
2277
- const token = await this.getToken(config);
2278
- const response = await this.httpService.post(
2279
- this.getBaseUrl(config) + "/api/v2_1/orders/" + orderId,
2280
- {
2281
- refund: {
2282
- description: comment
2283
- }
2284
- },
2285
- {
2286
- headers: {
2287
- "Content-Type": "application/json",
2288
- Authorization: "Bearer " + token,
2289
- "X-Requested-With": "XMLHttpRequest"
2290
- },
2291
- maxRedirects: 0
2292
- }
2293
- ).toPromise();
2294
- return response.data;
2295
- }
2296
- getOrderId(trans) {
2297
- const historyItem = trans.history.find((x) => x.status === "started");
2298
- if (!historyItem) {
2299
- console.warn("Transaction without start status");
2300
- return null;
2301
- }
2302
- return historyItem.data.orderId;
2303
- }
2304
- async getToken(config) {
2305
- try {
2306
- const response = await this.httpService.post(
2307
- this.getBaseUrl(config) + "/pl/standard/user/oauth/authorize",
2308
- `grant_type=client_credentials&client_id=${config.clientId}&client_secret=${config.clientSecret}`
2309
- ).toPromise();
2310
- return response.data["access_token"];
2311
- } catch (e) {
2312
- console.error({
2313
- url: this.getBaseUrl(config) + "/pl/standard/user/oauth/authorize",
2314
- data: `grant_type=client_credentials&client_id=${config.clientId}&client_secret=${config.clientSecret}`,
2315
- ex: e
2316
- });
2317
- throw e;
2318
- }
2319
- }
2320
- async getConfig(data) {
2321
- try {
2322
- const provider = this.moduleRef.get(
2323
- PAYU_CONFIG_PROVIDER,
2324
- { strict: false }
2325
- );
2326
- return await provider.get(data);
2327
- } catch (e) {
2328
- Logger6.warn("PayPal config provider not found", PayuService.name);
2329
- }
2330
- return this.config;
2331
- }
2332
- getBaseUrl(config) {
2333
- if (config.test) return "https://secure.snd.payu.com";
2334
- return "https://secure.payu.com";
2335
- }
2336
- getStatusFromExternal(status) {
2337
- switch (status) {
2338
- case "COMPLETED":
2339
- return "completed";
2340
- case "CANCELED":
2341
- return "canceled";
2342
- case "PENDING":
2343
- return "pending";
2344
- default:
2345
- return status;
2346
- }
2347
- }
2348
- };
2349
- PayuService = __decorateClass([
2350
- Injectable11()
2351
- ], PayuService);
2352
-
2353
- // packages/shared/revolut/src/lib/revolut.config.ts
2354
- var RevolutConfig = class {
2355
- test;
2356
- token;
2357
- };
2358
- var REVOLUT_API_VERSION = "2024-09-01";
2359
- var REVOLUT_CONFIG_PROVIDER = "REVOLUT_CONFIG_PROVIDER";
2360
-
2361
- // packages/shared/revolut/src/lib/revolut.service.ts
2362
- import { Injectable as Injectable12, Logger as Logger7, Optional as Optional2 } from "@nestjs/common";
2363
- var RevolutService = class {
2364
- constructor(httpService, moduleRef, config) {
2365
- this.httpService = httpService;
2366
- this.moduleRef = moduleRef;
2367
- this.config = config;
2368
- }
2369
- httpService;
2370
- moduleRef;
2371
- config;
2372
- async create(obj) {
2373
- const config = await this.getConfig(obj.data);
2374
- const data = {
2375
- amount: obj.amount,
2376
- currency: "PLN",
2377
- description: obj.name,
2378
- capture_mode: "automatic",
2379
- merchant_order_ext_ref: obj.id
2380
- };
2381
- const hasCustomer = !!obj.email || !!obj.firstName || !!obj.lastName || !!obj.contactPhone;
2382
- if (hasCustomer) {
2383
- const fullName = [obj.firstName, obj.lastName].filter(Boolean).join(" ");
2384
- data.customer = {
2385
- email: obj.email,
2386
- full_name: fullName || void 0,
2387
- phone: obj.contactPhone
2388
- };
2389
- }
2390
- const response = await this.httpService.post(this.getBaseUrl(config) + "/api/orders", data, {
2391
- headers: this.getHeaders(config),
2392
- maxRedirects: 0
2393
- }).toPromise();
2394
- return {
2395
- responseData: response.data,
2396
- orderId: response.data.token
2397
- };
2398
- }
2399
- async getStatus(trans) {
2400
- const config = await this.getConfig(trans.data);
2401
- const historyItem = trans.history.find((h) => h.status === "started");
2402
- const response = await this.httpService.get(
2403
- this.getBaseUrl(config) + "/api/orders/" + historyItem.data.responseData.id,
2404
- {
2405
- headers: this.getHeaders(config),
2406
- maxRedirects: 0
2407
- }
2408
- ).toPromise();
2409
- return {
2410
- data: response.data,
2411
- status: this.getStatusFromExternal(response.data["state"])
2412
- };
2413
- }
2414
- refund(trans, comment) {
2415
- return Promise.reject("Revolut does not support refund");
2416
- }
2417
- getBaseUrl(config) {
2418
- if (config.test) return "https://sandbox-merchant.revolut.com";
2419
- return "https://merchant.revolut.com";
2420
- }
2421
- getHeaders(config) {
2422
- return {
2423
- "Content-Type": "application/json",
2424
- Accept: "application/json",
2425
- Authorization: "Bearer " + config.token,
2426
- "Revolut-Api-Version": REVOLUT_API_VERSION
2427
- };
2428
- }
2429
- async getConfig(data) {
2430
- try {
2431
- const provider = this.moduleRef.get(
2432
- REVOLUT_CONFIG_PROVIDER,
2433
- { strict: false }
2434
- );
2435
- return await provider.get(data);
2436
- } catch (e) {
2437
- Logger7.warn("Revolut config provider not found", RevolutService.name);
2438
- }
2439
- return this.config;
2440
- }
2441
- getStatusFromExternal(status) {
2442
- switch (status) {
2443
- case "pending":
2444
- return "pending";
2445
- case "processing":
2446
- return "pending";
2447
- case "authorised":
2448
- return "completed";
2449
- case "completed":
2450
- return "completed";
2451
- case "cancelled":
2452
- return "canceled";
2453
- case "failed":
2454
- return "canceled";
2455
- default:
2456
- return status;
2457
- }
2458
- }
2459
- };
2460
- RevolutService = __decorateClass([
2461
- Injectable12(),
2462
- __decorateParam(2, Optional2())
2463
- ], RevolutService);
2464
-
2465
- // packages/trans/domain/src/lib/feature-create-trans/creator.service.ts
2466
- import { Injectable as Injectable13 } from "@nestjs/common";
2467
- import { Guid as Guid3 } from "guid-typescript";
2468
-
2469
- // packages/trans/domain/src/lib/entities/trans.entity.ts
2470
- import { Column, Entity, ObjectIdColumn } from "typeorm";
2471
- var Trans = class {
2472
- id;
2473
- externalId;
2474
- name;
2475
- amount;
2476
- firstName;
2477
- lastName;
2478
- email;
2479
- contactPhone;
2480
- data;
2481
- system;
2482
- options;
2483
- status;
2484
- modifyDate;
2485
- history;
2486
- clientIp;
2487
- };
2488
- __decorateClass([
2489
- ObjectIdColumn({ generated: false })
2490
- ], Trans.prototype, "id", 2);
2491
- __decorateClass([
2492
- Column()
2493
- ], Trans.prototype, "externalId", 2);
2494
- __decorateClass([
2495
- Column()
2496
- ], Trans.prototype, "name", 2);
2497
- __decorateClass([
2498
- Column()
2499
- ], Trans.prototype, "amount", 2);
2500
- __decorateClass([
2501
- Column()
2502
- ], Trans.prototype, "firstName", 2);
2503
- __decorateClass([
2504
- Column()
2505
- ], Trans.prototype, "lastName", 2);
2506
- __decorateClass([
2507
- Column()
2508
- ], Trans.prototype, "email", 2);
2509
- __decorateClass([
2510
- Column()
2511
- ], Trans.prototype, "contactPhone", 2);
2512
- __decorateClass([
2513
- Column()
2514
- ], Trans.prototype, "data", 2);
2515
- __decorateClass([
2516
- Column()
2517
- ], Trans.prototype, "system", 2);
2518
- __decorateClass([
2519
- Column()
2520
- ], Trans.prototype, "options", 2);
2521
- __decorateClass([
2522
- Column()
2523
- ], Trans.prototype, "status", 2);
2524
- __decorateClass([
2525
- Column()
2526
- ], Trans.prototype, "modifyDate", 2);
2527
- __decorateClass([
2528
- Column(() => TransHistory)
2529
- ], Trans.prototype, "history", 2);
2530
- __decorateClass([
2531
- Column()
2532
- ], Trans.prototype, "clientIp", 2);
2533
- Trans = __decorateClass([
2534
- Entity("trans")
2535
- ], Trans);
2536
- var TransHistory = class {
2537
- amount;
2538
- data;
2539
- system;
2540
- status;
2541
- modifyDate;
2542
- };
2543
- __decorateClass([
2544
- Column()
2545
- ], TransHistory.prototype, "amount", 2);
2546
- __decorateClass([
2547
- Column()
2548
- ], TransHistory.prototype, "data", 2);
2549
- __decorateClass([
2550
- Column()
2551
- ], TransHistory.prototype, "system", 2);
2552
- __decorateClass([
2553
- Column()
2554
- ], TransHistory.prototype, "status", 2);
2555
- __decorateClass([
2556
- Column()
2557
- ], TransHistory.prototype, "modifyDate", 2);
2558
- var TRANS_SYSTEMS = ["payu", "paypal", "revolut", "paynow"];
2559
-
2560
- // packages/trans/domain/src/lib/trans.service.ts
2561
- var TransBaseService = class {
2562
- constructor(repository) {
2563
- this.repository = repository;
2564
- }
2565
- repository;
2566
- addHistory(trans, data) {
2567
- const historyItem = new TransHistory();
2568
- historyItem.amount = trans.amount;
2569
- historyItem.modifyDate = trans.modifyDate;
2570
- historyItem.data = ObjectService.removeTypes(data);
2571
- historyItem.system = trans.system;
2572
- historyItem.status = trans.status;
2573
- if (!trans.history) trans.history = [];
2574
- trans.history.push(historyItem);
2575
- }
2576
- async setError(trans, error) {
2577
- trans.modifyDate = /* @__PURE__ */ new Date();
2578
- trans.status = "error";
2579
- this.addHistory(trans, error);
2580
- await this.repository.update(trans, null);
2581
- }
2582
- };
2583
-
2584
- // packages/trans/domain/src/lib/feature-create-trans/creator.service.ts
2585
- var CreatorService = class extends TransBaseService {
2586
- constructor(repository) {
2587
- super(repository);
2588
- }
2589
- create(config, internalService, paymentService) {
2590
- this.valid(config);
2591
- let trans = null;
2592
- return this.prepare(config).then((r) => {
2593
- trans = r;
2594
- return this.setAsNew(trans, internalService);
2595
- }).then(() => {
2596
- return this.setAsStarted(trans, paymentService);
2597
- }).catch((e) => {
2598
- if (trans) {
2599
- this.setError(trans, e);
2600
- }
2601
- console.error(e);
2602
- throw e;
2603
- });
2604
- }
2605
- async setAsStarted(trans, paymentService) {
2606
- const paymentResult = await paymentService[trans.system].create({
2607
- id: trans.id,
2608
- name: trans.name,
2609
- amount: trans.amount,
2610
- firstName: trans.firstName,
2611
- lastName: trans.lastName,
2612
- email: trans.email,
2613
- contactPhone: trans.contactPhone,
2614
- clientIp: trans.clientIp,
2615
- data: trans.data,
2616
- options: trans.options
2617
- });
2618
- trans.status = "started";
2619
- trans.modifyDate = /* @__PURE__ */ new Date();
2620
- trans.externalId = paymentResult.orderId;
2621
- this.addHistory(trans, paymentResult);
2622
- await this.repository.update(trans, null);
2623
- return paymentResult;
2624
- }
2625
- async setAsNew(trans, internalService) {
2626
- const internalResult = await internalService.create(trans);
2627
- if (internalResult.amount) {
2628
- trans.amount = internalResult.amount;
2629
- }
2630
- trans.status = "new";
2631
- trans.modifyDate = /* @__PURE__ */ new Date();
2632
- this.addHistory(trans, internalResult);
2633
- await this.repository.update(trans, null);
2634
- }
2635
- async prepare(config) {
2636
- const trans = new Trans();
2637
- Object.keys(config).forEach((key) => {
2638
- trans[key] = config[key];
2639
- });
2640
- trans.id = Guid3.raw();
2641
- trans.modifyDate = /* @__PURE__ */ new Date();
2642
- trans.status = "prepare";
2643
- this.addHistory(trans, trans.data);
2644
- await this.repository.create(trans, null);
2645
- return trans;
2646
- }
2647
- valid(req) {
2648
- if (!req) throw new DomainValidationError("config is empty");
2649
- if (!req.name) throw new DomainValidationError("name is empty");
2650
- if (!req.clientIp) throw new DomainValidationError("client ip is empty");
2651
- if (!req.amount || req.amount < 1)
2652
- throw new DomainValidationError("amount is empty");
2653
- if (!req.data) throw new DomainValidationError("data is empty");
2654
- if (!req.system || !TRANS_SYSTEMS.some((s) => s === req.system))
2655
- throw new DomainValidationError("system is empty");
2656
- }
2657
- };
2658
- CreatorService = __decorateClass([
2659
- Injectable13()
2660
- ], CreatorService);
2661
-
2662
- // packages/trans/domain/src/lib/feature-refresh-trans/refresher.service.ts
2663
- import { Injectable as Injectable14, NotFoundException as NotFoundException2 } from "@nestjs/common";
2664
- var RefresherService = class extends TransBaseService {
2665
- constructor(repository) {
2666
- super(repository);
2667
- }
2668
- async refresh(transId, internalService, paymentService, customData = {}) {
2669
- const trans = (await this.repository.getByCriteria({
2670
- externalId: transId
2671
- })).data[0];
2672
- if (!trans) {
2673
- throw new NotFoundException2("Transaction not found: " + transId);
2674
- }
2675
- try {
2676
- const { status, data } = await paymentService[trans.system].getStatus(trans);
2677
- if (status === trans.status) return;
2678
- trans.modifyDate = /* @__PURE__ */ new Date();
2679
- trans.status = status;
2680
- data["customData"] = customData;
2681
- this.addHistory(trans, data);
2682
- const internalRes = await internalService.refresh(trans);
2683
- if (!internalRes) return;
2684
- this.addHistory(trans, internalRes);
2685
- await this.repository.updatePartial(
2686
- {
2687
- id: trans.id,
2688
- modifyDate: trans.modifyDate,
2689
- status: trans.status,
2690
- history: trans.history
2691
- },
2692
- null
2693
- );
2694
- } catch (err) {
2695
- console.error(err);
2696
- await this.setError(trans, err);
2697
- throw err;
2698
- }
2699
- }
2700
- };
2701
- RefresherService = __decorateClass([
2702
- Injectable14()
2703
- ], RefresherService);
2704
-
2705
- // packages/trans/domain/src/lib/feature-refund-trans/refund.service.ts
2706
- import { Injectable as Injectable15, NotFoundException as NotFoundException3 } from "@nestjs/common";
2707
- var RefundService = class extends TransBaseService {
2708
- constructor(repository) {
2709
- super(repository);
2710
- }
2711
- async refund(transId, internalService, paymentService, comment = "Refund") {
2712
- const trans = await this.repository.getById(transId);
2713
- if (!trans) {
2714
- throw new NotFoundException3("Transaction not found: " + transId);
2715
- }
2716
- if (trans.status !== "completed") {
2717
- throw new NotFoundException3(
2718
- "Transaction is not completed/error: " + transId
2719
- );
2720
- }
2721
- try {
2722
- const data = await paymentService[trans.system].refund(trans, comment);
2723
- trans.modifyDate = /* @__PURE__ */ new Date();
2724
- trans.status = "refund";
2725
- data["customData"] = {
2726
- comment
2727
- };
2728
- this.addHistory(trans, data);
2729
- await this.repository.update(trans, null);
2730
- } catch (err) {
2731
- console.error(err);
2732
- await this.setError(trans, err);
2733
- throw err;
2734
- }
2735
- }
2736
- };
2737
- RefundService = __decorateClass([
2738
- Injectable15()
2739
- ], RefundService);
2740
-
2741
- // packages/trans/domain/src/lib/trans.config.ts
2742
- var TransConfig = class {
2743
- constructor(internalApiUrl, tokenConfig) {
2744
- this.internalApiUrl = internalApiUrl;
2745
- this.tokenConfig = tokenConfig;
2746
- }
2747
- internalApiUrl;
2748
- tokenConfig;
2749
- };
2750
-
2751
- // packages/trans/domain/src/index.ts
2752
- var DOMAIN_SERVICES = [
2753
- CreatorService,
2754
- RefresherService,
2755
- RefundService
2756
- ];
2757
-
2758
- // packages/trans/shell/app-services/src/lib/services/trans/trans.service.ts
2759
- import { Injectable as Injectable16, Optional as Optional3 } from "@nestjs/common";
2760
-
2761
- // packages/trans/shell/app-services/src/lib/services/internal/internal.service.ts
2762
- var TRANS_TOKEN_INTERNAL_SERVICE = "TRANS_TOKEN_INTERNAL_SERVICE";
2763
-
2764
- // packages/trans/shell/app-services/src/lib/services/trans/trans.service.ts
2765
- var TransService = class {
2766
- constructor(moduleRef, creatorService, refresherService, refundService, httpService, config, repository, payuService, paynowService, paypalService, revolutService) {
2767
- this.moduleRef = moduleRef;
2768
- this.creatorService = creatorService;
2769
- this.refresherService = refresherService;
2770
- this.refundService = refundService;
2771
- this.httpService = httpService;
2772
- this.config = config;
2773
- this.repository = repository;
2774
- this.payuService = payuService;
2775
- this.paynowService = paynowService;
2776
- this.paypalService = paypalService;
2777
- this.revolutService = revolutService;
2778
- }
2779
- moduleRef;
2780
- creatorService;
2781
- refresherService;
2782
- refundService;
2783
- httpService;
2784
- config;
2785
- repository;
2786
- payuService;
2787
- paynowService;
2788
- paypalService;
2789
- revolutService;
2790
- get _paymentService() {
2791
- return {
2792
- payu: this.payuService,
2793
- paypal: this.paypalService,
2794
- paynow: this.paynowService,
2795
- revolut: this.revolutService
2796
- };
2797
- }
2798
- _internalService = {
2799
- create: (trans) => {
2800
- if (!this.config.internalApiUrl)
2801
- return Promise.resolve({
2802
- date: /* @__PURE__ */ new Date(),
2803
- req: trans
2804
- });
2805
- return this.httpService.post(this.config.internalApiUrl, trans).toPromise().then((res) => res.data);
2806
- },
2807
- refresh: (trans) => {
2808
- if (!this.config.internalApiUrl)
2809
- return Promise.resolve({
2810
- date: /* @__PURE__ */ new Date(),
2811
- req: trans,
2812
- id: trans.id
2813
- });
2814
- return this.httpService.put(this.config.internalApiUrl + "/" + trans.id, trans).toPromise().then((res) => res.data);
2815
- }
2816
- };
2817
- create(ops) {
2818
- return this.creatorService.create(
2819
- ops,
2820
- this.getInternalService(),
2821
- this._paymentService
2822
- );
2823
- }
2824
- async refresh(transId, data = {}) {
2825
- await this.refresherService.refresh(
2826
- transId,
2827
- this.getInternalService(),
2828
- this._paymentService,
2829
- data
2830
- );
2831
- }
2832
- async refund(transId, comment = "Refund") {
2833
- await this.refundService.refund(
2834
- transId,
2835
- this.getInternalService(),
2836
- this._paymentService,
2837
- comment
2838
- );
2839
- }
2840
- async getById(id) {
2841
- return await this.repository.getById(id);
2842
- }
2843
- getInternalService() {
2844
- try {
2845
- return this.moduleRef.get(TRANS_TOKEN_INTERNAL_SERVICE, {
2846
- strict: false
2847
- });
2848
- } catch (e) {
2849
- return this._internalService;
2850
- }
2851
- }
2852
- };
2853
- TransService = __decorateClass([
2854
- Injectable16(),
2855
- __decorateParam(7, Optional3()),
2856
- __decorateParam(8, Optional3()),
2857
- __decorateParam(9, Optional3()),
2858
- __decorateParam(10, Optional3())
2859
- ], TransService);
2860
-
2861
- // packages/trans/shell/app-services/src/lib/services/index.ts
2862
- var SERVICES2 = [TransService];
2863
-
2864
- // packages/trans/shell/nestjs/src/lib/controllers/paynow/paynow.controller.ts
2865
- import { Body as Body2, Controller as Controller2, HttpCode as HttpCode2, Post as Post2 } from "@nestjs/common";
2866
- var PaynowController = class {
2867
- constructor(service) {
2868
- this.service = service;
2869
- }
2870
- service;
2871
- async refreshStatus(obj) {
2872
- try {
2873
- await this.service.refresh(obj.paymentId, obj);
2874
- return "ok";
2875
- } catch (e) {
2876
- console.error(e);
2877
- throw e;
2878
- }
2879
- }
2880
- };
2881
- __decorateClass([
2882
- Post2(),
2883
- HttpCode2(200),
2884
- __decorateParam(0, Body2())
2885
- ], PaynowController.prototype, "refreshStatus", 1);
2886
- PaynowController = __decorateClass([
2887
- Controller2("paynow")
2888
- ], PaynowController);
2889
-
2890
- // packages/trans/shell/nestjs/src/lib/controllers/paypal/paypal.controller.ts
2891
- import {
2892
- Body as Body3,
2893
- Controller as Controller3,
2894
- HttpCode as HttpCode3,
2895
- Post as Post3,
2896
- Get as Get2,
2897
- Param as Param2,
2898
- Query as Query2,
2899
- Res as Res2,
2900
- HttpStatus as HttpStatus2,
2901
- Optional as Optional4
2902
- } from "@nestjs/common";
2903
- var PaypalController = class {
2904
- constructor(service, config, paypalService) {
2905
- this.service = service;
2906
- this.config = config;
2907
- this.paypalService = paypalService;
2908
- }
2909
- service;
2910
- config;
2911
- paypalService;
2912
- async refreshStatus(obj) {
2913
- try {
2914
- const trans = await this.service.getById(obj.item_number1);
2915
- await this.service.refresh(trans.externalId, obj);
2916
- return "ok";
2917
- } catch (e) {
2918
- console.error("ERROR ---> ", obj);
2919
- console.error(e);
2920
- throw e;
2921
- }
2922
- }
2923
- async confirm(id, payerId, paymentId, res) {
2924
- try {
2925
- const trans = await this.service.getById(id);
2926
- if (trans.externalId !== paymentId) {
2927
- throw new Error("Invalid externaId");
2928
- }
2929
- const payment2 = await this.paypalService.confirm(
2930
- payerId,
2931
- paymentId,
2932
- trans.amount / 100,
2933
- trans.data
2934
- );
2935
- await this.service.refresh(paymentId, payment2);
2936
- return res.redirect(HttpStatus2.MOVED_PERMANENTLY, this.config.returnUrl);
2937
- } catch (e) {
2938
- console.log(e);
2939
- return res.redirect(HttpStatus2.MOVED_PERMANENTLY, this.config.cancelUrl);
2940
- }
2941
- }
2942
- };
2943
- __decorateClass([
2944
- Post3(),
2945
- HttpCode3(200),
2946
- __decorateParam(0, Body3())
2947
- ], PaypalController.prototype, "refreshStatus", 1);
2948
- __decorateClass([
2949
- Get2(":id/confirm"),
2950
- __decorateParam(0, Param2("id")),
2951
- __decorateParam(1, Query2("PayerID")),
2952
- __decorateParam(2, Query2("paymentId")),
2953
- __decorateParam(3, Res2())
2954
- ], PaypalController.prototype, "confirm", 1);
2955
- PaypalController = __decorateClass([
2956
- Controller3("paypal"),
2957
- __decorateParam(1, Optional4()),
2958
- __decorateParam(2, Optional4())
2959
- ], PaypalController);
2960
-
2961
- // packages/trans/shell/nestjs/src/lib/controllers/payu/payu.controller.ts
2962
- import { Body as Body4, Controller as Controller4, HttpCode as HttpCode4, Post as Post4 } from "@nestjs/common";
2963
- var PayUController = class {
2964
- constructor(service) {
2965
- this.service = service;
2966
- }
2967
- service;
2968
- async refreshStatus(obj) {
2969
- try {
2970
- await this.service.refresh(obj.order.orderId, obj);
2971
- return "ok";
2972
- } catch (e) {
2973
- console.error(e);
2974
- throw e;
2975
- }
2976
- }
2977
- };
2978
- __decorateClass([
2979
- Post4(),
2980
- HttpCode4(200),
2981
- __decorateParam(0, Body4())
2982
- ], PayUController.prototype, "refreshStatus", 1);
2983
- PayUController = __decorateClass([
2984
- Controller4("payu")
2985
- ], PayUController);
2986
-
2987
- // packages/trans/shell/nestjs/src/lib/controllers/trans/trans.controller.ts
2988
- import { Body as Body5, Controller as Controller5, Param as Param3, Post as Post5, Req as Req2 } from "@nestjs/common";
2989
- var TransController = class {
2990
- constructor(service) {
2991
- this.service = service;
2992
- }
2993
- service;
2994
- async create(obj, req) {
2995
- obj.clientIp = req.connection.remoteAddress.indexOf("::") === 0 ? "10.0.0.1" : req.connection.remoteAddress;
2996
- const { redirectUrl, orderId } = await this.service.create(obj);
2997
- return {
2998
- url: redirectUrl,
2999
- orderId
3000
- };
3001
- }
3002
- async refresh(orderId, obj) {
3003
- await this.service.refresh(orderId, {});
3004
- }
3005
- };
3006
- __decorateClass([
3007
- Post5(),
3008
- __decorateParam(0, Body5()),
3009
- __decorateParam(1, Req2())
3010
- ], TransController.prototype, "create", 1);
3011
- __decorateClass([
3012
- Post5(":id/refresh"),
3013
- __decorateParam(0, Param3("id")),
3014
- __decorateParam(1, Body5())
3015
- ], TransController.prototype, "refresh", 1);
3016
- TransController = __decorateClass([
3017
- Controller5("")
3018
- ], TransController);
3019
-
3020
- // packages/trans/shell/nestjs/src/lib/controllers/index.ts
3021
- var CONTROLLERS2 = [
3022
- TransController,
3023
- PayUController,
3024
- PaypalController,
3025
- PaynowController
3026
- ];
3027
-
3028
- // packages/trans/shell/nestjs/src/lib/nestjs.module.ts
3029
- var TransShellNestjsModule = class {
3030
- static forRoot(config) {
3031
- return {
3032
- module: TransShellNestjsModule,
3033
- controllers: CONTROLLERS2,
3034
- providers: [
3035
- ...SERVICES2,
3036
- ...DOMAIN_SERVICES,
3037
- { provide: TransConfig, useValue: config },
3038
- ...config.payuConfig ? [{ provide: PayuConfig, useValue: config.payuConfig }, PayuService] : [],
3039
- ...config.paypalConfig ? [
3040
- { provide: PaypalConfig, useValue: config.paypalConfig },
3041
- PaypalService
3042
- ] : [],
3043
- ...config.revolutConfig ? [
3044
- { provide: RevolutConfig, useValue: config.revolutConfig },
3045
- RevolutService
3046
- ] : [],
3047
- ...config.paynowConfig ? [
3048
- { provide: PaynowConfig, useValue: config.paynowConfig },
3049
- PaynowService
3050
- ] : []
3051
- ],
3052
- imports: [
3053
- HttpModule,
3054
- CrudShellNestjsModule.forRoot({
3055
- ...config,
3056
- db: {
3057
- ...config.db,
3058
- collection: "trans"
3059
- },
3060
- restApi: false,
3061
- socket: false
3062
- }),
3063
- PassportModule2.register({ defaultStrategy: "jwt", session: false }),
3064
- JwtModule2.register({
3065
- secret: config.tokenConfig.secretOrPrivateKey,
3066
- signOptions: {
3067
- expiresIn: config.tokenConfig.expiredIn
3068
- }
3069
- })
3070
- ],
3071
- exports: [
3072
- ...SERVICES2,
3073
- TransConfig,
3074
- ...config.payuConfig ? [PayuConfig, PayuService] : [],
3075
- ...config.paypalConfig ? [PaypalConfig, PaypalService] : [],
3076
- ...config.revolutConfig ? [RevolutConfig, RevolutService] : []
3077
- ]
3078
- };
3079
- }
3080
- };
3081
- TransShellNestjsModule = __decorateClass([
3082
- Module2({
3083
- imports: [HttpModule]
3084
- })
3085
- ], TransShellNestjsModule);
3086
- var TransShellNestjsCoreModule = class {
3087
- static forRoot(config) {
3088
- return {
3089
- module: TransShellNestjsCoreModule,
3090
- providers: [
3091
- ...SERVICES2,
3092
- ...DOMAIN_SERVICES,
3093
- { provide: TransConfig, useValue: config },
3094
- ...config.payuConfig ? [{ provide: PayuConfig, useValue: config.payuConfig }, PayuService] : [],
3095
- ...config.paypalConfig ? [
3096
- { provide: PaypalConfig, useValue: config.paypalConfig },
3097
- PaypalService
3098
- ] : [],
3099
- ...config.paynowConfig ? [
3100
- { provide: PaynowConfig, useValue: config.paynowConfig },
3101
- PaynowService
3102
- ] : []
3103
- ],
3104
- imports: [
3105
- HttpModule,
3106
- CrudShellNestjsModule.forRoot({
3107
- ...config,
3108
- db: {
3109
- ...config.db,
3110
- collection: "trans"
3111
- },
3112
- restApi: false,
3113
- socket: false
3114
- }),
3115
- PassportModule2.register({ defaultStrategy: "jwt", session: false }),
3116
- JwtModule2.register({
3117
- secret: config.tokenConfig.secretOrPrivateKey,
3118
- signOptions: {
3119
- expiresIn: config.tokenConfig.expiredIn
3120
- }
3121
- })
3122
- ],
3123
- exports: [
3124
- ...SERVICES2,
3125
- TransConfig,
3126
- ...config.payuConfig ? [PayuConfig, PayuService] : [],
3127
- ...config.paypalConfig ? [PaypalConfig, PaypalService] : [],
3128
- ...config.revolutConfig ? [RevolutConfig, RevolutService] : [],
3129
- ...config.paynowConfig ? [PaynowConfig, PaynowService] : []
3130
- ]
3131
- };
3132
- }
3133
- };
3134
- TransShellNestjsCoreModule = __decorateClass([
3135
- Module2({
3136
- imports: [HttpModule]
3137
- })
3138
- ], TransShellNestjsCoreModule);
3139
- export {
3140
- CONTROLLERS2 as CONTROLLERS,
3141
- PayUController,
3142
- PaynowController,
3143
- PaypalController,
3144
- TransController,
3145
- TransShellNestjsCoreModule,
3146
- TransShellNestjsModule
3147
- };