@coopenomics/extension-kit 2026.9.22 → 2026.9.24-3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +308 -89
- package/dist/index.d.cts +172 -14
- package/dist/index.d.mts +172 -14
- package/dist/index.d.ts +172 -14
- package/dist/index.mjs +295 -89
- package/dist/sync/index.cjs +3 -2
- package/dist/sync/index.d.cts +8 -0
- package/dist/sync/index.d.mts +8 -0
- package/dist/sync/index.d.ts +8 -0
- package/dist/sync/index.mjs +3 -2
- package/package.json +6 -4
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpException, HttpStatus, BadGatewayException, ServiceUnavailableException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, UnprocessableEntityException, InternalServerErrorException, createParamDecorator, SetMetadata, applyDecorators, Injectable, Inject } from '@nestjs/common';
|
|
2
2
|
import { GqlExecutionContext, Directive, Field, InputType, registerEnumType, Int, IntersectionType, OmitType, ObjectType } from '@nestjs/graphql';
|
|
3
|
+
import { te, t } from '@coopenomics/i18n/server';
|
|
3
4
|
import { Reflector } from '@nestjs/core';
|
|
4
5
|
import { AuthGuard } from '@nestjs/passport';
|
|
5
6
|
import { timingSafeEqual } from 'node:crypto';
|
|
@@ -10,11 +11,155 @@ import { GraphQLJSON } from 'graphql-type-json';
|
|
|
10
11
|
import { Classes } from '@coopenomics/sdk';
|
|
11
12
|
import { Name } from '@wharfkit/antelope';
|
|
12
13
|
import moment from 'moment';
|
|
14
|
+
import crypto, { createHash } from 'crypto';
|
|
13
15
|
import moment$1 from 'moment-timezone';
|
|
14
16
|
import 'moment/locale/ru';
|
|
15
|
-
import crypto from 'crypto';
|
|
16
17
|
import { _Common } from 'cooptypes';
|
|
17
18
|
|
|
19
|
+
const DOMAIN_ERROR = Symbol.for("@coopenomics/extension-kit/DomainError");
|
|
20
|
+
function domainErrorMessage(code, params = {}) {
|
|
21
|
+
const key = `errors.${code}`;
|
|
22
|
+
if (!te(key) && typeof params.message === "string")
|
|
23
|
+
return params.message;
|
|
24
|
+
return t(key, params);
|
|
25
|
+
}
|
|
26
|
+
function body(code, params, status) {
|
|
27
|
+
return { statusCode: status, code, params, message: domainErrorMessage(code, params) };
|
|
28
|
+
}
|
|
29
|
+
function brand(target, code, params) {
|
|
30
|
+
target.code = code;
|
|
31
|
+
target.params = params;
|
|
32
|
+
target[DOMAIN_ERROR] = true;
|
|
33
|
+
target.name = "DomainError";
|
|
34
|
+
}
|
|
35
|
+
class DomainError extends HttpException {
|
|
36
|
+
static [Symbol.hasInstance](value) {
|
|
37
|
+
return !!value && value[DOMAIN_ERROR] === true;
|
|
38
|
+
}
|
|
39
|
+
constructor(code, params = {}, status = HttpStatus.BAD_REQUEST) {
|
|
40
|
+
super(body(code, params, status), status);
|
|
41
|
+
brand(this, code, params);
|
|
42
|
+
}
|
|
43
|
+
/** Ключ сообщения в словаре. */
|
|
44
|
+
get messageKey() {
|
|
45
|
+
return `errors.${this.code}`;
|
|
46
|
+
}
|
|
47
|
+
static badRequest(code, params = {}) {
|
|
48
|
+
return new DomainBadRequest(code, params);
|
|
49
|
+
}
|
|
50
|
+
static unauthorized(code, params = {}) {
|
|
51
|
+
return new DomainUnauthorized(code, params);
|
|
52
|
+
}
|
|
53
|
+
static forbidden(code, params = {}) {
|
|
54
|
+
return new DomainForbidden(code, params);
|
|
55
|
+
}
|
|
56
|
+
static notFound(code, params = {}) {
|
|
57
|
+
return new DomainNotFound(code, params);
|
|
58
|
+
}
|
|
59
|
+
static conflict(code, params = {}) {
|
|
60
|
+
return new DomainConflict(code, params);
|
|
61
|
+
}
|
|
62
|
+
static unprocessable(code, params = {}) {
|
|
63
|
+
return new DomainUnprocessable(code, params);
|
|
64
|
+
}
|
|
65
|
+
static tooManyRequests(code, params = {}) {
|
|
66
|
+
return new DomainError(code, params, HttpStatus.TOO_MANY_REQUESTS);
|
|
67
|
+
}
|
|
68
|
+
static internal(code, params = {}) {
|
|
69
|
+
return new DomainInternal(code, params);
|
|
70
|
+
}
|
|
71
|
+
static badGateway(code, params = {}) {
|
|
72
|
+
return new DomainBadGateway(code, params);
|
|
73
|
+
}
|
|
74
|
+
static serviceUnavailable(code, params = {}) {
|
|
75
|
+
return new DomainServiceUnavailable(code, params);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
class DomainBadGateway extends BadGatewayException {
|
|
79
|
+
constructor(code, params) {
|
|
80
|
+
super(body(code, params, HttpStatus.BAD_GATEWAY));
|
|
81
|
+
brand(this, code, params);
|
|
82
|
+
}
|
|
83
|
+
get messageKey() {
|
|
84
|
+
return `errors.${this.code}`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class DomainServiceUnavailable extends ServiceUnavailableException {
|
|
88
|
+
constructor(code, params) {
|
|
89
|
+
super(body(code, params, HttpStatus.SERVICE_UNAVAILABLE));
|
|
90
|
+
brand(this, code, params);
|
|
91
|
+
}
|
|
92
|
+
get messageKey() {
|
|
93
|
+
return `errors.${this.code}`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class DomainBadRequest extends BadRequestException {
|
|
97
|
+
constructor(code, params) {
|
|
98
|
+
super(body(code, params, HttpStatus.BAD_REQUEST));
|
|
99
|
+
brand(this, code, params);
|
|
100
|
+
}
|
|
101
|
+
get messageKey() {
|
|
102
|
+
return `errors.${this.code}`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
class DomainUnauthorized extends UnauthorizedException {
|
|
106
|
+
constructor(code, params) {
|
|
107
|
+
super(body(code, params, HttpStatus.UNAUTHORIZED));
|
|
108
|
+
brand(this, code, params);
|
|
109
|
+
}
|
|
110
|
+
get messageKey() {
|
|
111
|
+
return `errors.${this.code}`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
class DomainForbidden extends ForbiddenException {
|
|
115
|
+
constructor(code, params) {
|
|
116
|
+
super(body(code, params, HttpStatus.FORBIDDEN));
|
|
117
|
+
brand(this, code, params);
|
|
118
|
+
}
|
|
119
|
+
get messageKey() {
|
|
120
|
+
return `errors.${this.code}`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
class DomainNotFound extends NotFoundException {
|
|
124
|
+
constructor(code, params) {
|
|
125
|
+
super(body(code, params, HttpStatus.NOT_FOUND));
|
|
126
|
+
brand(this, code, params);
|
|
127
|
+
}
|
|
128
|
+
get messageKey() {
|
|
129
|
+
return `errors.${this.code}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
class DomainConflict extends ConflictException {
|
|
133
|
+
constructor(code, params) {
|
|
134
|
+
super(body(code, params, HttpStatus.CONFLICT));
|
|
135
|
+
brand(this, code, params);
|
|
136
|
+
}
|
|
137
|
+
get messageKey() {
|
|
138
|
+
return `errors.${this.code}`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
class DomainUnprocessable extends UnprocessableEntityException {
|
|
142
|
+
constructor(code, params) {
|
|
143
|
+
super(body(code, params, HttpStatus.UNPROCESSABLE_ENTITY));
|
|
144
|
+
brand(this, code, params);
|
|
145
|
+
}
|
|
146
|
+
get messageKey() {
|
|
147
|
+
return `errors.${this.code}`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
class DomainInternal extends InternalServerErrorException {
|
|
151
|
+
constructor(code, params) {
|
|
152
|
+
super(body(code, params, HttpStatus.INTERNAL_SERVER_ERROR));
|
|
153
|
+
brand(this, code, params);
|
|
154
|
+
}
|
|
155
|
+
get messageKey() {
|
|
156
|
+
return `errors.${this.code}`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function validationMessage(key, params = {}) {
|
|
160
|
+
return (args) => t(key, { property: args.property, value: String(args.value ?? ""), ...params });
|
|
161
|
+
}
|
|
162
|
+
|
|
18
163
|
const ROLES_DENY_SELF_KEY = "roles_deny_self";
|
|
19
164
|
const ROLES_ANY_STATUS_KEY = "roles_any_status";
|
|
20
165
|
function AuthRoles(roles, options = {}) {
|
|
@@ -31,7 +176,7 @@ const CurrentUser = createParamDecorator((data, context) => {
|
|
|
31
176
|
const ctx = GqlExecutionContext.create(context);
|
|
32
177
|
const request = ctx.getContext().req;
|
|
33
178
|
if (!request?.user) {
|
|
34
|
-
throw
|
|
179
|
+
throw DomainError.unauthorized("KIT_USER_NOT_AUTHORIZED");
|
|
35
180
|
}
|
|
36
181
|
return request?.user;
|
|
37
182
|
});
|
|
@@ -114,7 +259,7 @@ let OptionalGqlJwtAuthGuard = class extends AuthGuard("jwt") {
|
|
|
114
259
|
if (err instanceof Error) {
|
|
115
260
|
throw err;
|
|
116
261
|
}
|
|
117
|
-
throw
|
|
262
|
+
throw DomainError.unauthorized("KIT_SESSION_ENDED");
|
|
118
263
|
}
|
|
119
264
|
};
|
|
120
265
|
OptionalGqlJwtAuthGuard = __decorateClass$g([
|
|
@@ -164,11 +309,11 @@ let RolesGuard = class {
|
|
|
164
309
|
if (allowedRoles.includes(user.role)) {
|
|
165
310
|
const anyStatus = this.reflector.get(ROLES_ANY_STATUS_KEY, context.getHandler()) === true;
|
|
166
311
|
if (user.role === PARTICIPANT_ROLE && !anyStatus && user.status !== ACTIVE_USER_STATUS) {
|
|
167
|
-
throw
|
|
312
|
+
throw DomainError.forbidden("KIT_MEMBERS_ONLY");
|
|
168
313
|
}
|
|
169
314
|
return true;
|
|
170
315
|
}
|
|
171
|
-
throw
|
|
316
|
+
throw DomainError.unauthorized("KIT_INSUFFICIENT_RIGHTS");
|
|
172
317
|
}
|
|
173
318
|
};
|
|
174
319
|
RolesGuard = __decorateClass$g([
|
|
@@ -184,12 +329,10 @@ let ActiveUserStatusGuard = class {
|
|
|
184
329
|
}
|
|
185
330
|
const user = request.user;
|
|
186
331
|
if (!user?.status) {
|
|
187
|
-
throw
|
|
332
|
+
throw DomainError.forbidden("KIT_AUTHORIZED_USER_REQUIRED");
|
|
188
333
|
}
|
|
189
334
|
if (user.status !== ACTIVE_USER_STATUS) {
|
|
190
|
-
throw
|
|
191
|
-
"\u0414\u043E\u0441\u0442\u0443\u043F \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u043F\u0430\u0439\u0449\u0438\u043A\u043E\u0432 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 \xABactive\xBB"
|
|
192
|
-
);
|
|
335
|
+
throw DomainError.forbidden("KIT_ACTIVE_MEMBERS_ONLY");
|
|
193
336
|
}
|
|
194
337
|
return true;
|
|
195
338
|
}
|
|
@@ -254,6 +397,7 @@ const BucketRegistry = {
|
|
|
254
397
|
const existing = REGISTERED.get(cls);
|
|
255
398
|
if (existing && existing.name !== spec.name) {
|
|
256
399
|
throw new Error(
|
|
400
|
+
// i18n-ignore: ошибка регистрации бакета при старте, до пайщика не доходит
|
|
257
401
|
`BucketRegistry: \u043A\u043B\u0430\u0441\u0441 ${cls.name} \u0443\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D \u043F\u043E\u0434 \u0431\u0430\u043A\u0435\u0442\u043E\u043C '${existing.name}', \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u0430\u044F \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u043F\u043E\u0434 '${spec.name}' \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u0430`
|
|
258
402
|
);
|
|
259
403
|
}
|
|
@@ -290,6 +434,7 @@ function bucketProvidersFor(fileStoragePortToken, consumers) {
|
|
|
290
434
|
const spec = BucketRegistry.get(cls);
|
|
291
435
|
if (!spec) {
|
|
292
436
|
throw new Error(
|
|
437
|
+
// i18n-ignore: ошибка объявления хранилища при старте, до пайщика не доходит
|
|
293
438
|
`bucketProvidersFor: \u043A\u043B\u0430\u0441\u0441 ${cls.name} \u043D\u0435 \u043F\u043E\u043C\u0435\u0447\u0435\u043D @UseBucket \u2014 \u043E\u0431\u044A\u044F\u0432\u0438\u0442\u0435 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u0440\u044F\u0434\u043E\u043C \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043E\u043C`
|
|
294
439
|
);
|
|
295
440
|
}
|
|
@@ -647,7 +792,7 @@ __decorateClass$a([
|
|
|
647
792
|
Field(() => String, { description: "\u0421\u0440\u043E\u043A \u0438\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F (\xAB\u0432 \u0441\u0440\u043E\u043A \u0434\u043E\xBB), \u0444\u043E\u0440\u043C\u0430\u0442 DD.MM.YYYY" }),
|
|
648
793
|
IsString(),
|
|
649
794
|
Matches(/^\d{2}\.\d{2}\.\d{4}$/, {
|
|
650
|
-
message: "
|
|
795
|
+
message: validationMessage("kit.expenseStatement.dueDateFormat")
|
|
651
796
|
})
|
|
652
797
|
], ExpenseProposalHeaderInputDTO.prototype, "deadline", 2);
|
|
653
798
|
__decorateClass$a([
|
|
@@ -874,6 +1019,7 @@ let entities;
|
|
|
874
1019
|
function registerExtensionEntities(list) {
|
|
875
1020
|
if (entities) {
|
|
876
1021
|
throw new Error(
|
|
1022
|
+
// i18n-ignore: ошибка сборки приложения при старте, до пайщика не доходит
|
|
877
1023
|
"\u0421\u043E\u0441\u0442\u0430\u0432 \u0442\u0430\u0431\u043B\u0438\u0446 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439 \u0443\u0436\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D: registerExtensionEntities() \u0432\u044B\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043E\u0434\u0438\u043D \u0440\u0430\u0437 \u043F\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435"
|
|
878
1024
|
);
|
|
879
1025
|
}
|
|
@@ -886,6 +1032,23 @@ function resetExtensionEntities() {
|
|
|
886
1032
|
entities = void 0;
|
|
887
1033
|
}
|
|
888
1034
|
|
|
1035
|
+
let migrations;
|
|
1036
|
+
function registerExtensionDatabaseMigrations(list) {
|
|
1037
|
+
if (migrations) {
|
|
1038
|
+
throw new Error(
|
|
1039
|
+
// i18n-ignore: ошибка сборки composition root для разработчика, до пайщика не доходит
|
|
1040
|
+
"\u041C\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0442\u0430\u0431\u043B\u0438\u0446 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439 \u0443\u0436\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u044B: registerExtensionDatabaseMigrations() \u0432\u044B\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043E\u0434\u0438\u043D \u0440\u0430\u0437 \u043F\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435"
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
migrations = [...list];
|
|
1044
|
+
}
|
|
1045
|
+
function extensionDatabaseMigrations() {
|
|
1046
|
+
return migrations ?? [];
|
|
1047
|
+
}
|
|
1048
|
+
function resetExtensionDatabaseMigrations() {
|
|
1049
|
+
migrations = void 0;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
889
1052
|
var __defProp$7 = Object.defineProperty;
|
|
890
1053
|
var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
|
|
891
1054
|
var __decorateClass$7 = (decorators, target, key, kind) => {
|
|
@@ -897,6 +1060,7 @@ var __decorateClass$7 = (decorators, target, key, kind) => {
|
|
|
897
1060
|
__defProp$7(target, key, result);
|
|
898
1061
|
return result;
|
|
899
1062
|
};
|
|
1063
|
+
const SORT_FIELD_PATTERN = /^([A-Za-z_][A-Za-z0-9_]*(:(asc|desc))?)?$/i;
|
|
900
1064
|
let PaginationInputDTO = class {
|
|
901
1065
|
};
|
|
902
1066
|
__decorateClass$7([
|
|
@@ -906,7 +1070,9 @@ __decorateClass$7([
|
|
|
906
1070
|
Field(() => Int, { description: "\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435", defaultValue: 10 })
|
|
907
1071
|
], PaginationInputDTO.prototype, "limit", 2);
|
|
908
1072
|
__decorateClass$7([
|
|
909
|
-
Field(() => String, { nullable: true, description: '\u041A\u043B\u044E\u0447 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438 (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, "name")' })
|
|
1073
|
+
Field(() => String, { nullable: true, description: '\u041A\u043B\u044E\u0447 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438 (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, "name")' }),
|
|
1074
|
+
IsOptional(),
|
|
1075
|
+
Matches(SORT_FIELD_PATTERN, { message: validationMessage("kit.pagination.invalidSortField") })
|
|
910
1076
|
], PaginationInputDTO.prototype, "sortBy", 2);
|
|
911
1077
|
__decorateClass$7([
|
|
912
1078
|
Field(() => String, {
|
|
@@ -980,13 +1146,16 @@ class PaginationUtils {
|
|
|
980
1146
|
static validatePaginationOptions(options) {
|
|
981
1147
|
const { page = 1, limit = 10, sortBy, sortOrder = "ASC" } = options;
|
|
982
1148
|
if (page < 1) {
|
|
983
|
-
throw
|
|
1149
|
+
throw DomainError.internal("KIT_PAGE_NUMBER_INVALID");
|
|
984
1150
|
}
|
|
985
1151
|
if (limit < 1 || limit > 1e3) {
|
|
986
|
-
throw
|
|
1152
|
+
throw DomainError.internal("KIT_PAGE_LIMIT_INVALID");
|
|
987
1153
|
}
|
|
988
1154
|
if (sortOrder !== "ASC" && sortOrder !== "DESC") {
|
|
989
|
-
throw
|
|
1155
|
+
throw DomainError.internal("KIT_SORT_ORDER_INVALID");
|
|
1156
|
+
}
|
|
1157
|
+
if (sortBy !== void 0 && sortBy !== null && !SORT_FIELD_PATTERN.test(sortBy)) {
|
|
1158
|
+
throw DomainError.internal("KIT_SORT_FIELD_INVALID");
|
|
990
1159
|
}
|
|
991
1160
|
return {
|
|
992
1161
|
page,
|
|
@@ -1116,6 +1285,7 @@ function configurePlatformSettings(value) {
|
|
|
1116
1285
|
function platformSettings() {
|
|
1117
1286
|
if (!settings) {
|
|
1118
1287
|
throw new Error(
|
|
1288
|
+
// i18n-ignore: ошибка сборки приложения при старте, до пайщика не доходит
|
|
1119
1289
|
"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043A\u043E\u043D\u0442\u0443\u0440\u0430 \u043D\u0435 \u0437\u0430\u0434\u0430\u043D\u044B: composition root \u043E\u0431\u044F\u0437\u0430\u043D \u0432\u044B\u0437\u0432\u0430\u0442\u044C configurePlatformSettings() \u043F\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435"
|
|
1120
1290
|
);
|
|
1121
1291
|
}
|
|
@@ -1333,19 +1503,6 @@ DocumentAggregateDTO = __decorateClass$1([
|
|
|
1333
1503
|
ObjectType("DocumentAggregate")
|
|
1334
1504
|
], DocumentAggregateDTO);
|
|
1335
1505
|
|
|
1336
|
-
class HttpApiError extends HttpException {
|
|
1337
|
-
constructor(statusCode, message, isOperational = true, stack, subcode) {
|
|
1338
|
-
super(message, statusCode);
|
|
1339
|
-
this.isOperational = isOperational;
|
|
1340
|
-
this.subcode = subcode;
|
|
1341
|
-
if (stack) {
|
|
1342
|
-
this.stack = stack;
|
|
1343
|
-
} else {
|
|
1344
|
-
Error.captureStackTrace(this, this.constructor);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
1506
|
class CurrencyValidationUtil {
|
|
1350
1507
|
/**
|
|
1351
1508
|
* Проверяет, что сумма содержит правильный символ валюты
|
|
@@ -1365,10 +1522,10 @@ class CurrencyValidationUtil {
|
|
|
1365
1522
|
* @param fieldName Название поля для сообщения об ошибке (по умолчанию "сумма")
|
|
1366
1523
|
* @throws Error если символ валюты неправильный
|
|
1367
1524
|
*/
|
|
1368
|
-
static validateCurrencySymbol(amount, fieldName = "
|
|
1525
|
+
static validateCurrencySymbol(amount, fieldName = t("kit.currency.defaultFieldName")) {
|
|
1369
1526
|
if (!this.hasValidCurrencySymbol(amount)) {
|
|
1370
1527
|
const expectedSymbol = platformSettings().blockchain.rootGovernSymbol;
|
|
1371
|
-
throw
|
|
1528
|
+
throw DomainError.internal("KIT_CURRENCY_SYMBOL_INVALID", { fieldName, expectedSymbol });
|
|
1372
1529
|
}
|
|
1373
1530
|
}
|
|
1374
1531
|
/**
|
|
@@ -1399,12 +1556,13 @@ class CurrencyValidationUtil {
|
|
|
1399
1556
|
/**
|
|
1400
1557
|
* Форматирует сумму с правильным символом валюты
|
|
1401
1558
|
* @param value Числовое значение
|
|
1402
|
-
* @param precision Количество знаков после запятой (по умолчанию из
|
|
1559
|
+
* @param precision Количество знаков после запятой (по умолчанию из настроек платформы)
|
|
1403
1560
|
* @returns string - отформатированная сумма
|
|
1404
1561
|
*/
|
|
1405
1562
|
static formatAmount(value, precision) {
|
|
1406
|
-
const
|
|
1407
|
-
const
|
|
1563
|
+
const { rootGovernPrecision, rootGovernSymbol } = platformSettings().blockchain;
|
|
1564
|
+
const actualPrecision = precision ?? rootGovernPrecision;
|
|
1565
|
+
const symbol = rootGovernSymbol;
|
|
1408
1566
|
return `${value.toFixed(actualPrecision)} ${symbol}`;
|
|
1409
1567
|
}
|
|
1410
1568
|
}
|
|
@@ -1412,18 +1570,12 @@ class CurrencyValidationUtil {
|
|
|
1412
1570
|
async function verifySignedDocumentAgainstStoredDraft(loadGeneratedByDocHash, signed, metaVerifications) {
|
|
1413
1571
|
const generated = await loadGeneratedByDocHash(signed.doc_hash);
|
|
1414
1572
|
if (!generated) {
|
|
1415
|
-
throw
|
|
1416
|
-
HttpStatus.BAD_REQUEST,
|
|
1417
|
-
`\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0441 \u0445\u0435\u0448\u0435\u043C ${signed.doc_hash} \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D. \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u0443\u0439\u0442\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442.`
|
|
1418
|
-
);
|
|
1573
|
+
throw DomainError.badRequest("KIT_GENERATED_DOCUMENT_NOT_FOUND", { docHash: signed.doc_hash });
|
|
1419
1574
|
}
|
|
1420
1575
|
const comparison = await Classes.Document.compareDocuments(signed, generated);
|
|
1421
1576
|
if (!comparison.isValid) {
|
|
1422
|
-
const differences = Object.entries(comparison.differences).map(([field, values]) =>
|
|
1423
|
-
throw
|
|
1424
|
-
HttpStatus.BAD_REQUEST,
|
|
1425
|
-
`\u0421\u0432\u0435\u0440\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u0430\u043D\u043D\u043E\u0433\u043E \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0441 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u043E\u043C \u043D\u0435 \u043F\u0440\u043E\u0448\u043B\u0430: ${differences}. \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u0430 \u043F\u043E\u0434\u043C\u0435\u043D\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430.`
|
|
1426
|
-
);
|
|
1577
|
+
const differences = Object.entries(comparison.differences).map(([field, values]) => t("kit.documentVerification.fieldDifference", { field, expected: values.expected, actual: values.actual })).join("; ");
|
|
1578
|
+
throw DomainError.badRequest("KIT_DOCUMENT_DRAFT_MISMATCH", { differences });
|
|
1427
1579
|
}
|
|
1428
1580
|
if (!metaVerifications || metaVerifications.length === 0) {
|
|
1429
1581
|
return;
|
|
@@ -1433,10 +1585,7 @@ async function verifySignedDocumentAgainstStoredDraft(loadGeneratedByDocHash, si
|
|
|
1433
1585
|
const raw = meta[field];
|
|
1434
1586
|
const actualStr = typeof raw === "string" ? raw.trim() : raw !== void 0 && raw !== null ? String(raw).trim() : "";
|
|
1435
1587
|
if (!actualStr) {
|
|
1436
|
-
throw
|
|
1437
|
-
HttpStatus.BAD_REQUEST,
|
|
1438
|
-
`\u0412 \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043F\u043E\u043B\u0435 \xAB${field}\xBB, \u0442\u0440\u0435\u0431\u0443\u0435\u043C\u043E\u0435 \u0434\u043B\u044F \u0441\u0432\u0435\u0440\u043A\u0438.`
|
|
1439
|
-
);
|
|
1588
|
+
throw DomainError.badRequest("KIT_DOCUMENT_META_FIELD_MISSING", { field });
|
|
1440
1589
|
}
|
|
1441
1590
|
const expectedTrimmed = expected.trim();
|
|
1442
1591
|
switch (mode) {
|
|
@@ -1444,39 +1593,27 @@ async function verifySignedDocumentAgainstStoredDraft(loadGeneratedByDocHash, si
|
|
|
1444
1593
|
const parsedExpected = CurrencyValidationUtil.extractAmountValue(expectedTrimmed);
|
|
1445
1594
|
const parsedActual = CurrencyValidationUtil.extractAmountValue(actualStr);
|
|
1446
1595
|
if (Number.isNaN(parsedExpected) || Number.isNaN(parsedActual)) {
|
|
1447
|
-
throw
|
|
1448
|
-
HttpStatus.BAD_REQUEST,
|
|
1449
|
-
`\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0441\u0443\u043C\u043C\u044B \u0432 \u043F\u043E\u043B\u0435 \xAB${field}\xBB \u0438\u043B\u0438 \u0432 \u043E\u0436\u0438\u0434\u0430\u0435\u043C\u043E\u043C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0438.`
|
|
1450
|
-
);
|
|
1596
|
+
throw DomainError.badRequest("KIT_DOCUMENT_AMOUNT_FORMAT_INVALID", { field });
|
|
1451
1597
|
}
|
|
1452
1598
|
if (CurrencyValidationUtil.formatAmount(parsedExpected) !== CurrencyValidationUtil.formatAmount(parsedActual)) {
|
|
1453
|
-
throw
|
|
1454
|
-
HttpStatus.BAD_REQUEST,
|
|
1455
|
-
`\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044F \xAB${field}\xBB \u0432 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0435 (${actualStr}) \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u0435\u0442 \u0441 \u043E\u0436\u0438\u0434\u0430\u0435\u043C\u044B\u043C (${expectedTrimmed}). \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u0430 \u043F\u043E\u0434\u043C\u0435\u043D\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430.`
|
|
1456
|
-
);
|
|
1599
|
+
throw DomainError.badRequest("KIT_DOCUMENT_FIELD_MISMATCH", { field, actual: actualStr, expected: expectedTrimmed });
|
|
1457
1600
|
}
|
|
1458
1601
|
break;
|
|
1459
1602
|
}
|
|
1460
1603
|
case "string_trim": {
|
|
1461
1604
|
if (actualStr !== expectedTrimmed) {
|
|
1462
|
-
throw
|
|
1463
|
-
HttpStatus.BAD_REQUEST,
|
|
1464
|
-
`\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044F \xAB${field}\xBB \u0432 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0435 (${actualStr}) \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u0435\u0442 \u0441 \u043E\u0436\u0438\u0434\u0430\u0435\u043C\u044B\u043C (${expectedTrimmed}). \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u0430 \u043F\u043E\u0434\u043C\u0435\u043D\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430.`
|
|
1465
|
-
);
|
|
1605
|
+
throw DomainError.badRequest("KIT_DOCUMENT_FIELD_MISMATCH", { field, actual: actualStr, expected: expectedTrimmed });
|
|
1466
1606
|
}
|
|
1467
1607
|
break;
|
|
1468
1608
|
}
|
|
1469
1609
|
case "hex_case_insensitive": {
|
|
1470
1610
|
if (actualStr.toLowerCase() !== expectedTrimmed.toLowerCase()) {
|
|
1471
|
-
throw
|
|
1472
|
-
HttpStatus.BAD_REQUEST,
|
|
1473
|
-
`\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044F \xAB${field}\xBB \u0432 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0435 (${actualStr}) \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u0435\u0442 \u0441 \u043E\u0436\u0438\u0434\u0430\u0435\u043C\u044B\u043C (${expectedTrimmed}). \u0412\u043E\u0437\u043C\u043E\u0436\u043D\u0430 \u043F\u043E\u0434\u043C\u0435\u043D\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430.`
|
|
1474
|
-
);
|
|
1611
|
+
throw DomainError.badRequest("KIT_DOCUMENT_FIELD_MISMATCH", { field, actual: actualStr, expected: expectedTrimmed });
|
|
1475
1612
|
}
|
|
1476
1613
|
break;
|
|
1477
1614
|
}
|
|
1478
1615
|
default:
|
|
1479
|
-
throw
|
|
1616
|
+
throw DomainError.internal("KIT_DOCUMENT_COMPARE_MODE_UNKNOWN", { mode: String(mode) });
|
|
1480
1617
|
}
|
|
1481
1618
|
}
|
|
1482
1619
|
}
|
|
@@ -1533,12 +1670,12 @@ let DomainToBlockchainUtils = class {
|
|
|
1533
1670
|
formatQuantityWithPrecision(quantity) {
|
|
1534
1671
|
const parts = quantity.split(" ");
|
|
1535
1672
|
if (parts.length !== 2) {
|
|
1536
|
-
throw
|
|
1673
|
+
throw DomainError.internal("KIT_QUANTITY_FORMAT_INVALID", { quantity });
|
|
1537
1674
|
}
|
|
1538
1675
|
const [amount, symbol] = parts;
|
|
1539
1676
|
const numericAmount = parseFloat(amount);
|
|
1540
1677
|
if (isNaN(numericAmount)) {
|
|
1541
|
-
throw
|
|
1678
|
+
throw DomainError.internal("KIT_QUANTITY_AMOUNT_INVALID", { amount });
|
|
1542
1679
|
}
|
|
1543
1680
|
const { rootSymbol, rootPrecision, rootGovernSymbol, rootGovernPrecision } = platformSettings().blockchain;
|
|
1544
1681
|
let precision;
|
|
@@ -1547,7 +1684,7 @@ let DomainToBlockchainUtils = class {
|
|
|
1547
1684
|
} else if (symbol === rootGovernSymbol) {
|
|
1548
1685
|
precision = rootGovernPrecision;
|
|
1549
1686
|
} else {
|
|
1550
|
-
throw
|
|
1687
|
+
throw DomainError.internal("KIT_SYMBOL_UNSUPPORTED", { symbol, rootSymbol, rootGovernSymbol });
|
|
1551
1688
|
}
|
|
1552
1689
|
return `${numericAmount.toFixed(precision)} ${symbol}`;
|
|
1553
1690
|
}
|
|
@@ -1555,10 +1692,10 @@ let DomainToBlockchainUtils = class {
|
|
|
1555
1692
|
formatNumericStringToAssetString(numericString, precision, symbol) {
|
|
1556
1693
|
const numericValue = parseFloat(numericString);
|
|
1557
1694
|
if (isNaN(numericValue)) {
|
|
1558
|
-
throw
|
|
1695
|
+
throw DomainError.internal("KIT_NUMBER_INVALID", { value: numericString });
|
|
1559
1696
|
}
|
|
1560
1697
|
if (numericValue < 0) {
|
|
1561
|
-
throw
|
|
1698
|
+
throw DomainError.internal("KIT_NUMBER_NEGATIVE", { value: numericString });
|
|
1562
1699
|
}
|
|
1563
1700
|
return `${numericValue.toFixed(precision)} ${symbol}`;
|
|
1564
1701
|
}
|
|
@@ -1589,6 +1726,19 @@ DomainToBlockchainUtils = __decorateClass([
|
|
|
1589
1726
|
Injectable()
|
|
1590
1727
|
], DomainToBlockchainUtils);
|
|
1591
1728
|
|
|
1729
|
+
const DIGEST_RE = /^[0-9a-f]{64}$/;
|
|
1730
|
+
function chainTextDigest(text) {
|
|
1731
|
+
if (!text)
|
|
1732
|
+
return "";
|
|
1733
|
+
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
1734
|
+
}
|
|
1735
|
+
function isChainTextDigest(value) {
|
|
1736
|
+
return typeof value === "string" && DIGEST_RE.test(value);
|
|
1737
|
+
}
|
|
1738
|
+
function resolveChainText(chainValue, current) {
|
|
1739
|
+
return isChainTextDigest(chainValue) ? current ?? "" : chainValue;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1592
1742
|
class AssetUtils {
|
|
1593
1743
|
/**
|
|
1594
1744
|
* Парсит строку ассета и возвращает числовое значение и символ
|
|
@@ -1675,17 +1825,17 @@ class AmountFormatterUtils {
|
|
|
1675
1825
|
*/
|
|
1676
1826
|
static formatAmount(amountStr) {
|
|
1677
1827
|
if (!amountStr || typeof amountStr !== "string") {
|
|
1678
|
-
throw
|
|
1828
|
+
throw DomainError.internal("KIT_AMOUNT_FORMAT_INVALID", { amount: amountStr });
|
|
1679
1829
|
}
|
|
1680
1830
|
const parts = amountStr.trim().split(/\s+/);
|
|
1681
1831
|
if (parts.length < 1 || !parts[0]) {
|
|
1682
|
-
throw
|
|
1832
|
+
throw DomainError.internal("KIT_AMOUNT_FORMAT_INVALID", { amount: amountStr });
|
|
1683
1833
|
}
|
|
1684
1834
|
const amountPart = parts[0].replace(",", ".");
|
|
1685
1835
|
const currency = parts.length >= 2 ? parts.slice(1).join(" ") : "";
|
|
1686
1836
|
const amount = parseFloat(amountPart);
|
|
1687
1837
|
if (isNaN(amount)) {
|
|
1688
|
-
throw
|
|
1838
|
+
throw DomainError.internal("KIT_AMOUNT_NUMBER_INVALID", { value: parts[0] });
|
|
1689
1839
|
}
|
|
1690
1840
|
const formattedAmount = amount.toLocaleString("ru-RU", {
|
|
1691
1841
|
minimumFractionDigits: 2,
|
|
@@ -1730,7 +1880,7 @@ function checkPaymentAmount(incomeAmount, expectedAmount, tolerancePercentage) {
|
|
|
1730
1880
|
if (incomeAmount < expectedAmount - tolerance) {
|
|
1731
1881
|
return {
|
|
1732
1882
|
status: "error",
|
|
1733
|
-
message:
|
|
1883
|
+
message: t("kit.payments.insufficientFunds", { income: incomeAmount, expected: expectedAmount })
|
|
1734
1884
|
};
|
|
1735
1885
|
}
|
|
1736
1886
|
return {
|
|
@@ -1761,7 +1911,7 @@ class QuantityUtils {
|
|
|
1761
1911
|
} else if (symbol === rootGovernSymbol) {
|
|
1762
1912
|
return rootGovernPrecision;
|
|
1763
1913
|
} else {
|
|
1764
|
-
throw
|
|
1914
|
+
throw DomainError.internal("KIT_SYMBOL_UNSUPPORTED", { symbol, rootSymbol, rootGovernSymbol });
|
|
1765
1915
|
}
|
|
1766
1916
|
}
|
|
1767
1917
|
/**
|
|
@@ -1771,7 +1921,7 @@ class QuantityUtils {
|
|
|
1771
1921
|
static validateSymbol(symbol) {
|
|
1772
1922
|
if (!this.isSupportedSymbol(symbol)) {
|
|
1773
1923
|
const { rootSymbol, rootGovernSymbol } = platformSettings().blockchain;
|
|
1774
|
-
throw
|
|
1924
|
+
throw DomainError.internal("KIT_SYMBOL_UNSUPPORTED", { symbol, rootSymbol, rootGovernSymbol });
|
|
1775
1925
|
}
|
|
1776
1926
|
}
|
|
1777
1927
|
/**
|
|
@@ -1783,7 +1933,7 @@ class QuantityUtils {
|
|
|
1783
1933
|
static formatQuantityForBlockchain(amount, symbol) {
|
|
1784
1934
|
this.validateSymbol(symbol);
|
|
1785
1935
|
if (isNaN(amount) || amount < 0) {
|
|
1786
|
-
throw
|
|
1936
|
+
throw DomainError.internal("KIT_NUMBER_INVALID", { value: amount });
|
|
1787
1937
|
}
|
|
1788
1938
|
const precision = this.getPrecisionForSymbol(symbol);
|
|
1789
1939
|
const formattedAmount = amount.toFixed(precision);
|
|
@@ -1798,7 +1948,7 @@ class QuantityUtils {
|
|
|
1798
1948
|
static combineQuantityAndSymbol(amount, symbol) {
|
|
1799
1949
|
this.validateSymbol(symbol);
|
|
1800
1950
|
if (isNaN(amount) || amount < 0) {
|
|
1801
|
-
throw
|
|
1951
|
+
throw DomainError.internal("KIT_NUMBER_INVALID", { value: amount });
|
|
1802
1952
|
}
|
|
1803
1953
|
return `${amount} ${symbol}`;
|
|
1804
1954
|
}
|
|
@@ -1810,12 +1960,12 @@ class QuantityUtils {
|
|
|
1810
1960
|
static parseQuantityString(quantity) {
|
|
1811
1961
|
const parts = quantity.split(" ");
|
|
1812
1962
|
if (parts.length !== 2) {
|
|
1813
|
-
throw
|
|
1963
|
+
throw DomainError.internal("KIT_QUANTITY_FORMAT_INVALID", { quantity });
|
|
1814
1964
|
}
|
|
1815
1965
|
const [amountStr, symbol] = parts;
|
|
1816
1966
|
const amount = parseFloat(amountStr);
|
|
1817
1967
|
if (isNaN(amount)) {
|
|
1818
|
-
throw
|
|
1968
|
+
throw DomainError.internal("KIT_QUANTITY_AMOUNT_INVALID", { amount: amountStr });
|
|
1819
1969
|
}
|
|
1820
1970
|
this.validateSymbol(symbol);
|
|
1821
1971
|
return { amount, symbol };
|
|
@@ -1878,14 +2028,29 @@ class DateUtils {
|
|
|
1878
2028
|
}
|
|
1879
2029
|
}
|
|
1880
2030
|
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
}
|
|
1886
|
-
await new Promise((resolve) => {
|
|
1887
|
-
setTimeout(resolve, ms);
|
|
2031
|
+
function waitForEvent(source, event, match, timeoutMs) {
|
|
2032
|
+
let settle;
|
|
2033
|
+
const promise = new Promise((resolve) => {
|
|
2034
|
+
settle = resolve;
|
|
1888
2035
|
});
|
|
2036
|
+
let done = false;
|
|
2037
|
+
let timer;
|
|
2038
|
+
const listener = (payload) => {
|
|
2039
|
+
if (match(payload))
|
|
2040
|
+
finish(payload);
|
|
2041
|
+
};
|
|
2042
|
+
function finish(value) {
|
|
2043
|
+
if (done)
|
|
2044
|
+
return;
|
|
2045
|
+
done = true;
|
|
2046
|
+
if (timer)
|
|
2047
|
+
clearTimeout(timer);
|
|
2048
|
+
source.off(event, listener);
|
|
2049
|
+
settle(value);
|
|
2050
|
+
}
|
|
2051
|
+
source.on(event, listener);
|
|
2052
|
+
timer = setTimeout(() => finish(null), timeoutMs);
|
|
2053
|
+
return { promise, cancel: () => finish(null) };
|
|
1889
2054
|
}
|
|
1890
2055
|
|
|
1891
2056
|
function getAppliedBlockNum(transactResult) {
|
|
@@ -1912,11 +2077,52 @@ function sanitizeUserText(value) {
|
|
|
1912
2077
|
return _Common.Text.sanitizeEditorMarkdown(value);
|
|
1913
2078
|
}
|
|
1914
2079
|
|
|
2080
|
+
function resolveSortColumn(repository, sortBy, fallback) {
|
|
2081
|
+
if (!sortBy)
|
|
2082
|
+
return fallback;
|
|
2083
|
+
const isKnownColumn = repository.metadata.columns.some(
|
|
2084
|
+
(column) => column.propertyName === sortBy || column.databaseName === sortBy
|
|
2085
|
+
);
|
|
2086
|
+
return isKnownColumn ? sortBy : fallback;
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
class HttpApiError extends HttpException {
|
|
2090
|
+
constructor(statusCode, message, isOperational = true, stack, subcode) {
|
|
2091
|
+
super(message, statusCode);
|
|
2092
|
+
this.isOperational = isOperational;
|
|
2093
|
+
this.subcode = subcode;
|
|
2094
|
+
if (stack) {
|
|
2095
|
+
this.stack = stack;
|
|
2096
|
+
} else {
|
|
2097
|
+
Error.captureStackTrace(this, this.constructor);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
const ASSERT_PREFIX = /assertion failure with message: (.+?)(?:\n|$)/;
|
|
2103
|
+
const CODED = /^([A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+):\s*(.*)$/s;
|
|
2104
|
+
function parseChainAssert(message) {
|
|
2105
|
+
const assert = message.match(ASSERT_PREFIX);
|
|
2106
|
+
const body = (assert ? assert[1] : message).trim();
|
|
2107
|
+
const coded = body.match(CODED);
|
|
2108
|
+
return coded ? { code: coded[1], text: coded[2].trim() } : { text: body };
|
|
2109
|
+
}
|
|
2110
|
+
function chainErrorCode(error) {
|
|
2111
|
+
if (error instanceof DomainError) {
|
|
2112
|
+
if (error.code !== "CHAIN_ASSERT" && error.code !== "CHAIN_ERROR")
|
|
2113
|
+
return error.code;
|
|
2114
|
+
return typeof error.params.message === "string" ? parseChainAssert(error.params.message).code : void 0;
|
|
2115
|
+
}
|
|
2116
|
+
const raw = error?.message ?? String(error);
|
|
2117
|
+
return parseChainAssert(raw).code;
|
|
2118
|
+
}
|
|
1915
2119
|
function rethrowChainError(error) {
|
|
1916
2120
|
const raw = error?.message ?? String(error);
|
|
1917
|
-
const match = raw.match(
|
|
1918
|
-
|
|
1919
|
-
|
|
2121
|
+
const match = raw.match(ASSERT_PREFIX);
|
|
2122
|
+
if (!match)
|
|
2123
|
+
throw DomainError.badRequest("CHAIN_ERROR", { message: raw });
|
|
2124
|
+
const { code, text } = parseChainAssert(raw);
|
|
2125
|
+
throw DomainError.badRequest(code ?? "CHAIN_ASSERT", { message: text });
|
|
1920
2126
|
}
|
|
1921
2127
|
|
|
1922
|
-
export { ActiveUserStatusGuard, AmountFormatterUtils, AssetUtils, AuthRoles, BaseExtensionModule, BucketRegistry, CandidateFilterInputDTO, CandidateOutputDTO, CandidateStatus, CurrencyValidationUtil, CurrentUser, DEFAULT_DOCUMENT_VERSION, DateUtils, DocumentAggregateDTO, DomainToBlockchainUtils, EMPTY_HASH, EXTENSION_APP_TERMINATE_EVENT, EXTENSION_REPOSITORY, EXTENSION_SECRET_SET, EXTENSION_SECRET_UNSET, ExpenseProposalStatementGenerateDocumentInputDTO, ExpenseProposalStatementSignedDocumentInputDTO, ExpenseProposalStatementSignedMetaDocumentInputDTO, ExtensionAvailability, ExtensionConfigSuppliedBy, ExtensionDomainEntity, GenerateDocumentInputDTO, GenerateDocumentOptionsInputDTO, GenerateMetaDocumentInputDTO, GeneratedDocumentDTO, GqlJwtAuthGuard, HttpApiError, HttpJwtAuthGuard, IPNProvider, InjectBucket, LOG_EXTENSION_REPOSITORY, LangType, LogExtensionDomainEntity, MetaDocumentInputDTO, ONBOARDING_EXPIRY_DAYS, ONBOARDING_EXPIRY_MS, OptionalCurrentUser, OptionalGqlJwtAuthGuard, PaginationInputDTO, PaginationResult, PaginationUtils, PaymentProvider, PollingProvider, QuantityUtils, ROLES_ANY_STATUS_KEY, ROLES_DENY_SELF_KEY, RolesGuard, SignatureInfoDTO, SignatureInfoInputDTO, SignedDigitalDocumentDTO, SignedDigitalDocumentInputDTO, TransactionDTO, UseBucket, bucketProvidersFor, bucketTokenFor, buildPaginationResult, checkPaymentAmount, checkPaymentSymbol, computeOnboardingExpiresAt, configureExtensionAuth, configurePlatformSettings, createPaginationResult, extensionEntities, generateHashFromString, generateRandomHash, generateUniqueHash, getAmountPlusFee, getAppliedBlockNum, hasServerSecret, isExtensionAvailable, mergeSecretConfig, paginationInputToOffset, platformSettings, providerSuppliedPaths, redactSecretConfig, registerExtensionEntities, resetExtensionEntities, rethrowChainError, sanitizeUserText, verifySignedDocumentAgainstStoredDraft,
|
|
2128
|
+
export { ActiveUserStatusGuard, AmountFormatterUtils, AssetUtils, AuthRoles, BaseExtensionModule, BucketRegistry, CandidateFilterInputDTO, CandidateOutputDTO, CandidateStatus, CurrencyValidationUtil, CurrentUser, DEFAULT_DOCUMENT_VERSION, DateUtils, DocumentAggregateDTO, DomainError, DomainToBlockchainUtils, EMPTY_HASH, EXTENSION_APP_TERMINATE_EVENT, EXTENSION_REPOSITORY, EXTENSION_SECRET_SET, EXTENSION_SECRET_UNSET, ExpenseProposalStatementGenerateDocumentInputDTO, ExpenseProposalStatementSignedDocumentInputDTO, ExpenseProposalStatementSignedMetaDocumentInputDTO, ExtensionAvailability, ExtensionConfigSuppliedBy, ExtensionDomainEntity, GenerateDocumentInputDTO, GenerateDocumentOptionsInputDTO, GenerateMetaDocumentInputDTO, GeneratedDocumentDTO, GqlJwtAuthGuard, HttpApiError, HttpJwtAuthGuard, IPNProvider, InjectBucket, LOG_EXTENSION_REPOSITORY, LangType, LogExtensionDomainEntity, MetaDocumentInputDTO, ONBOARDING_EXPIRY_DAYS, ONBOARDING_EXPIRY_MS, OptionalCurrentUser, OptionalGqlJwtAuthGuard, PaginationInputDTO, PaginationResult, PaginationUtils, PaymentProvider, PollingProvider, QuantityUtils, ROLES_ANY_STATUS_KEY, ROLES_DENY_SELF_KEY, RolesGuard, SORT_FIELD_PATTERN, SignatureInfoDTO, SignatureInfoInputDTO, SignedDigitalDocumentDTO, SignedDigitalDocumentInputDTO, TransactionDTO, UseBucket, bucketProvidersFor, bucketTokenFor, buildPaginationResult, chainErrorCode, chainTextDigest, checkPaymentAmount, checkPaymentSymbol, computeOnboardingExpiresAt, configureExtensionAuth, configurePlatformSettings, createPaginationResult, domainErrorMessage, extensionDatabaseMigrations, extensionEntities, generateHashFromString, generateRandomHash, generateUniqueHash, getAmountPlusFee, getAppliedBlockNum, hasServerSecret, isChainTextDigest, isExtensionAvailable, mergeSecretConfig, paginationInputToOffset, parseChainAssert, platformSettings, providerSuppliedPaths, redactSecretConfig, registerExtensionDatabaseMigrations, registerExtensionEntities, resetExtensionDatabaseMigrations, resetExtensionEntities, resolveChainText, resolveSortColumn, rethrowChainError, sanitizeUserText, validationMessage, verifySignedDocumentAgainstStoredDraft, waitForEvent };
|